OSDN Git Service

Fix issue #65359137: Apps with target API 26 can bypass background...
authorDianne Hackborn <hackbod@google.com>
Tue, 5 Sep 2017 23:44:36 +0000 (16:44 -0700)
committerDianne Hackborn <hackbod@google.com>
Wed, 6 Sep 2017 16:47:16 +0000 (09:47 -0700)
...limit introduced in Oreo by swiping away from the task list

There was an edge case where, when restarting a service, if the
process wasn't already running we would bring it up directly in
the idle state and never go through the mechanism of force stopping
services once an app goes idle.

The fix for now is pretty targeted, detecting when we have a new
uid that is immediately idle, and in that case doing the same
thing we do when an existing uid goes idle (stopping any services
in it).  This means that in this flow you will get a glitch of
the service starting and then immediately stopping when idle is
applied at that point, but we do end up ultimately in the correct
final state.

Test: manual
Bug: 65359137

Change-Id: I64c29975ad75e7d7390512bf59673d423df16cf2

services/core/java/com/android/server/am/ActivityManagerService.java

index ae0910c..dad3125 100644 (file)
@@ -22875,6 +22875,8 @@ public class ActivityManagerService extends IActivityManager.Stub
             requestPssAllProcsLocked(now, false, mProcessStats.isMemFactorLowered());
         }
 
+        ArrayList<UidRecord> becameIdle = null;
+
         // Update from any uid changes.
         if (mLocalPowerManager != null) {
             mLocalPowerManager.startUidChanges();
@@ -22907,6 +22909,10 @@ public class ActivityManagerService extends IActivityManager.Stub
                     }
                     if (uidRec.idle && !uidRec.setIdle) {
                         uidChange = UidRecord.CHANGE_IDLE;
+                        if (becameIdle == null) {
+                            becameIdle = new ArrayList<>();
+                        }
+                        becameIdle.add(uidRec);
                     }
                 } else {
                     if (uidRec.idle) {
@@ -22938,6 +22944,14 @@ public class ActivityManagerService extends IActivityManager.Stub
             mLocalPowerManager.finishUidChanges();
         }
 
+        if (becameIdle != null) {
+            // If we have any new uids that became idle this time, we need to make sure
+            // they aren't left with running services.
+            for (int i = becameIdle.size() - 1; i >= 0; i--) {
+                mServices.stopInBackgroundLocked(becameIdle.get(i).uid);
+            }
+        }
+
         if (mProcessStats.shouldWriteNowLocked(now)) {
             mHandler.post(new Runnable() {
                 @Override public void run() {