diff options
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; |