From 80a7ac10634dabb39644004f3edfc648a2c036f7 Mon Sep 17 00:00:00 2001 From: Dianne Hackborn Date: Thu, 22 Sep 2011 18:32:52 -0700 Subject: [PATCH] Fix issue #5321282: Force Stop Button in Battery Screen Not disabled correctly If the app had activities still finishing, when we checked whether it was now stopped we would get told no. Also some other improvements: - Schedule an idle as part of the force stop, to get any finishing activities out of the stack soon rather than waiting for some activity to idle. - Don't filter out stopped system apps. This is dangerous because system apps may have no way for the user to explicitly launch them, so they could get put into a stopped state for which there is no way to get them out. Also if the user really wants a system app to not run, the new disabling mechanism is more appropriate. Change-Id: I34003f21dac29e2ca0f66a23b88c710de41bab99 --- .../server/am/ActivityManagerService.java | 6 ++++++ .../com/android/server/am/ActivityStack.java | 18 +++++++++--------- .../server/pm/PackageManagerService.java | 10 ++++++++-- 3 files changed, 23 insertions(+), 11 deletions(-) diff --git a/services/java/com/android/server/am/ActivityManagerService.java b/services/java/com/android/server/am/ActivityManagerService.java index ed960d6d219f8..59ed80f0c5dcd 100644 --- a/services/java/com/android/server/am/ActivityManagerService.java +++ b/services/java/com/android/server/am/ActivityManagerService.java @@ -3334,6 +3334,11 @@ public final class ActivityManagerService extends ActivityManagerNative if ((samePackage || r.task == lastTask) && (r.app == null || evenPersistent || !r.app.persistent)) { if (!doit) { + if (r.finishing) { + // If this activity is just finishing, then it is not + // interesting as far as something to stop. + continue; + } return true; } didSomething = true; @@ -3399,6 +3404,7 @@ public final class ActivityManagerService extends ActivityManagerNative } } mMainStack.resumeTopActivityLocked(null); + mMainStack.scheduleIdleLocked(); } return didSomething; diff --git a/services/java/com/android/server/am/ActivityStack.java b/services/java/com/android/server/am/ActivityStack.java index a0aedf9844739..35dee3cb96a11 100644 --- a/services/java/com/android/server/am/ActivityStack.java +++ b/services/java/com/android/server/am/ActivityStack.java @@ -765,9 +765,7 @@ final class ActivityStack { // Still need to tell some activities to stop; can't sleep yet. if (DEBUG_PAUSE) Slog.v(TAG, "Sleep still need to stop " + mStoppingActivities.size() + " activities"); - Message msg = Message.obtain(); - msg.what = IDLE_NOW_MSG; - mHandler.sendMessage(msg); + scheduleIdleLocked(); return; } @@ -978,9 +976,7 @@ final class ActivityStack { // then give up on things going idle and start clearing // them out. if (DEBUG_PAUSE) Slog.v(TAG, "To many pending stops, forcing idle"); - Message msg = Message.obtain(); - msg.what = IDLE_NOW_MSG; - mHandler.sendMessage(msg); + scheduleIdleLocked(); } else { checkReadyForSleepLocked(); } @@ -3103,6 +3099,12 @@ final class ActivityStack { return stops; } + final void scheduleIdleLocked() { + Message msg = Message.obtain(); + msg.what = IDLE_NOW_MSG; + mHandler.sendMessage(msg); + } + final ActivityRecord activityIdleInternal(IBinder token, boolean fromTimeout, Configuration config) { if (localLOGV) Slog.v(TAG, "Activity idle: " + token); @@ -3413,9 +3415,7 @@ final class ActivityStack { // If we already have a few activities waiting to stop, // then give up on things going idle and start clearing // them out. - Message msg = Message.obtain(); - msg.what = IDLE_NOW_MSG; - mHandler.sendMessage(msg); + scheduleIdleLocked(); } else { checkReadyForSleepLocked(); } diff --git a/services/java/com/android/server/pm/PackageManagerService.java b/services/java/com/android/server/pm/PackageManagerService.java index 105e603769fed..471bc132460a7 100644 --- a/services/java/com/android/server/pm/PackageManagerService.java +++ b/services/java/com/android/server/pm/PackageManagerService.java @@ -4350,7 +4350,10 @@ public class PackageManagerService extends IPackageManager.Stub { if (p != null) { PackageSetting ps = (PackageSetting)p.mExtras; if (ps != null) { - return ps.stopped; + // System apps are never considered stopped for purposes of + // filtering, because there may be no way for the user to + // actually re-launch them. + return ps.stopped && (ps.pkgFlags&ApplicationInfo.FLAG_SYSTEM) == 0; } } return false; @@ -4522,7 +4525,10 @@ public class PackageManagerService extends IPackageManager.Stub { if (p != null) { PackageSetting ps = (PackageSetting)p.mExtras; if (ps != null) { - return ps.stopped; + // System apps are never considered stopped for purposes of + // filtering, because there may be no way for the user to + // actually re-launch them. + return ps.stopped && (ps.pkgFlags&ApplicationInfo.FLAG_SYSTEM) == 0; } } return false;