diff options
author | Dianne Hackborn <hackbod@google.com> | 2009-05-07 15:53:46 -0700 |
---|---|---|
committer | Dianne Hackborn <hackbod@google.com> | 2009-05-08 12:59:21 -0700 |
commit | 55280a91884b9256e8db6af6a09f28b3feeaa9d8 (patch) | |
tree | ac29de79b8ecec41f2fde6014a1834418a82d2fd /services | |
parent | 672f1e2b07d985526bfd5606e6a888005fdcb70c (diff) | |
download | frameworks_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')
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; |