summaryrefslogtreecommitdiffstats
path: root/services
diff options
context:
space:
mode:
authorDianne Hackborn <hackbod@google.com>2009-05-07 15:53:46 -0700
committerDianne Hackborn <hackbod@google.com>2009-05-08 12:59:21 -0700
commit55280a91884b9256e8db6af6a09f28b3feeaa9d8 (patch)
treeac29de79b8ecec41f2fde6014a1834418a82d2fd /services
parent672f1e2b07d985526bfd5606e6a888005fdcb70c (diff)
downloadframeworks_base-55280a91884b9256e8db6af6a09f28b3feeaa9d8.zip
frameworks_base-55280a91884b9256e8db6af6a09f28b3feeaa9d8.tar.gz
frameworks_base-55280a91884b9256e8db6af6a09f28b3feeaa9d8.tar.bz2
Improve shutdown process to send broadcast for applications.
This introduces a new class in the base platform for performing a clean shutdown (which was copied from the classes in the policies). It includes new features to send a shutdown broadcast for applications to do cleanup, and ot have the activity manager pause the current activity before proceeding with the shutdown. These facilities are also use to write at the most recent stat files for sync, battery and user activity.
Diffstat (limited to 'services')
-rw-r--r--services/java/com/android/server/am/ActivityManagerService.java58
-rw-r--r--services/java/com/android/server/am/BatteryStatsService.java10
-rwxr-xr-xservices/java/com/android/server/am/UsageStatsService.java6
3 files changed, 66 insertions, 8 deletions
diff --git a/services/java/com/android/server/am/ActivityManagerService.java b/services/java/com/android/server/am/ActivityManagerService.java
index b04f5a8..2be4975 100644
--- a/services/java/com/android/server/am/ActivityManagerService.java
+++ b/services/java/com/android/server/am/ActivityManagerService.java
@@ -707,6 +707,11 @@ public final class ActivityManagerService extends ActivityManagerNative implemen
boolean mSleeping = false;
/**
+ * Set if we are shutting down the system, similar to sleeping.
+ */
+ boolean mShuttingDown = false;
+
+ /**
* Set when the system is going to sleep, until we have
* successfully paused the current activity and released our wake lock.
* At that point the system is allowed to actually sleep.
@@ -868,7 +873,7 @@ public final class ActivityManagerService extends ActivityManagerNative implemen
return;
}
AppErrorResult res = (AppErrorResult) data.get("result");
- if (!mSleeping) {
+ if (!mSleeping && !mShuttingDown) {
Dialog d = new AppErrorDialog(
mContext, res, proc,
(Integer)data.get("flags"),
@@ -1893,7 +1898,7 @@ public final class ActivityManagerService extends ActivityManagerNative implemen
// If we are not going to sleep, we want to ensure the device is
// awake until the next activity is started.
- if (!mSleeping) {
+ if (!mSleeping && !mShuttingDown) {
mLaunchingActivity.acquire();
if (!mHandler.hasMessages(LAUNCH_TIMEOUT_MSG)) {
// To be safe, don't allow the wake lock to be held for too long.
@@ -1972,12 +1977,15 @@ public final class ActivityManagerService extends ActivityManagerNative implemen
mPausingActivity = null;
}
- if (!mSleeping) {
+ if (!mSleeping && !mShuttingDown) {
resumeTopActivityLocked(prev);
} else {
if (mGoingToSleep.isHeld()) {
mGoingToSleep.release();
}
+ if (mShuttingDown) {
+ notifyAll();
+ }
}
if (prev != null) {
@@ -2243,7 +2251,8 @@ public final class ActivityManagerService extends ActivityManagerNative implemen
// If we are sleeping, and there is no resumed activity, and the top
// activity is paused, well that is the state we want.
- if (mSleeping && mLastPausedActivity == next && next.state == ActivityState.PAUSED) {
+ if ((mSleeping || mShuttingDown)
+ && mLastPausedActivity == next && next.state == ActivityState.PAUSED) {
// Make sure we have executed any pending transitions, since there
// should be nothing left to do at this point.
mWindowManager.executeAppTransition();
@@ -7098,8 +7107,45 @@ public final class ActivityManagerService extends ActivityManagerNative implemen
}
}
+ public boolean shutdown(int timeout) {
+ if (checkCallingPermission(android.Manifest.permission.SHUTDOWN)
+ != PackageManager.PERMISSION_GRANTED) {
+ throw new SecurityException("Requires permission "
+ + android.Manifest.permission.SHUTDOWN);
+ }
+
+ boolean timedout = false;
+
+ synchronized(this) {
+ mShuttingDown = true;
+ mWindowManager.setEventDispatching(false);
+
+ if (mResumedActivity != null) {
+ pauseIfSleepingLocked();
+ final long endTime = System.currentTimeMillis() + timeout;
+ while (mResumedActivity != null || mPausingActivity != null) {
+ long delay = endTime - System.currentTimeMillis();
+ if (delay <= 0) {
+ Log.w(TAG, "Activity manager shutdown timed out");
+ timedout = true;
+ break;
+ }
+ try {
+ this.wait();
+ } catch (InterruptedException e) {
+ }
+ }
+ }
+ }
+
+ mUsageStatsService.shutdown();
+ mBatteryStatsService.shutdown();
+
+ return timedout;
+ }
+
void pauseIfSleepingLocked() {
- if (mSleeping) {
+ if (mSleeping || mShuttingDown) {
if (!mGoingToSleep.isHeld()) {
mGoingToSleep.acquire();
if (mLaunchingActivity.isHeld()) {
@@ -8064,7 +8110,7 @@ public final class ActivityManagerService extends ActivityManagerNative implemen
+ " mBooting=" + mBooting
+ " mBooted=" + mBooted
+ " mFactoryTest=" + mFactoryTest);
- pw.println(" mSleeping=" + mSleeping);
+ pw.println(" mSleeping=" + mSleeping + " mShuttingDown=" + mShuttingDown);
pw.println(" mGoingToSleep=" + mGoingToSleep);
pw.println(" mLaunchingActivity=" + mLaunchingActivity);
pw.println(" mDebugApp=" + mDebugApp + "/orig=" + mOrigDebugApp
diff --git a/services/java/com/android/server/am/BatteryStatsService.java b/services/java/com/android/server/am/BatteryStatsService.java
index ddc3e68..a21893b 100644
--- a/services/java/com/android/server/am/BatteryStatsService.java
+++ b/services/java/com/android/server/am/BatteryStatsService.java
@@ -25,8 +25,7 @@ import android.os.IBinder;
import android.os.Parcel;
import android.os.Process;
import android.os.ServiceManager;
-import android.telephony.TelephonyManager;
-import android.util.PrintWriterPrinter;
+import android.util.Log;
import java.io.FileDescriptor;
import java.io.PrintWriter;
@@ -50,6 +49,13 @@ public final class BatteryStatsService extends IBatteryStats.Stub {
ServiceManager.addService("batteryinfo", asBinder());
}
+ public void shutdown() {
+ Log.w("BatteryStats", "Writing battery stats before shutdown...");
+ synchronized (mStats) {
+ mStats.writeLocked();
+ }
+ }
+
public static IBatteryStats getService() {
if (sService != null) {
return sService;
diff --git a/services/java/com/android/server/am/UsageStatsService.java b/services/java/com/android/server/am/UsageStatsService.java
index b6f9158..866334b 100755
--- a/services/java/com/android/server/am/UsageStatsService.java
+++ b/services/java/com/android/server/am/UsageStatsService.java
@@ -17,6 +17,7 @@
package com.android.server.am;
import com.android.internal.app.IUsageStats;
+
import android.content.ComponentName;
import android.content.Context;
import android.os.Binder;
@@ -418,6 +419,11 @@ public final class UsageStatsService extends IUsageStats.Stub {
ServiceManager.addService(SERVICE_NAME, asBinder());
}
+ public void shutdown() {
+ Log.w(TAG, "Writing usage stats before shutdown...");
+ writeStatsToFile(true);
+ }
+
public static IUsageStats getService() {
if (sService != null) {
return sService;