From ec8cff62610d0964b015e7e0918ba060a29bb617 Mon Sep 17 00:00:00 2001 From: Jing Ji Date: Fri, 3 Dec 2021 02:30:31 -0800 Subject: [PATCH] Allow service auto-restarts when its dependency is force-stopped While force-stopping a package, if it's being loaded as dependency of another package, previously the processes of the latter package will be stopped too, now retain the auto-restartable services in the latter package and restart them later. Bug: 190749907 Bug: 200137455 Test: atest FrameworksServicesTests#ServiceRestarterTest Change-Id: Ieef1fcee01f3009251f5a8e147063665cedaae90 Merged-In: Ieef1fcee01f3009251f5a8e147063665cedaae90 --- .../server/am/ActivityManagerService.java | 4 +- .../com/android/server/am/ProcessList.java | 42 ++++++--- services/tests/servicestests/AndroidTest.xml | 7 ++ .../server/am/ServiceRestarterTest.java | 88 +++++++++++++++++++ .../SimpleServiceTestApp/AndroidManifest.xml | 1 + .../simpleservicetestapp/SimpleService.java | 20 +++++ 6 files changed, 151 insertions(+), 11 deletions(-) diff --git a/services/core/java/com/android/server/am/ActivityManagerService.java b/services/core/java/com/android/server/am/ActivityManagerService.java index dde1ed9cdca96..3ace2bb0be117 100644 --- a/services/core/java/com/android/server/am/ActivityManagerService.java +++ b/services/core/java/com/android/server/am/ActivityManagerService.java @@ -4173,7 +4173,7 @@ public class ActivityManagerService extends IActivityManager.Stub didSomething |= mProcessList.killPackageProcessesLSP(packageName, appId, userId, ProcessList.INVALID_ADJ, callerWillRestart, false /* allowRestart */, doit, - evenPersistent, true /* setRemoved */, + evenPersistent, true /* setRemoved */, uninstalling, packageName == null ? ApplicationExitInfo.REASON_USER_STOPPED : ApplicationExitInfo.REASON_USER_REQUESTED, ApplicationExitInfo.SUBREASON_UNKNOWN, @@ -7209,6 +7209,7 @@ public class ActivityManagerService extends IActivityManager.Stub ProcessList.PERSISTENT_PROC_ADJ, false /* callerWillRestart */, true /* callerWillRestart */, true /* doit */, true /* evenPersistent */, false /* setRemoved */, + false /* uninstalling */, ApplicationExitInfo.REASON_OTHER, ApplicationExitInfo.SUBREASON_KILL_UID, reason != null ? reason : "kill uid"); @@ -7230,6 +7231,7 @@ public class ActivityManagerService extends IActivityManager.Stub ProcessList.PERSISTENT_PROC_ADJ, false /* callerWillRestart */, true /* callerWillRestart */, true /* doit */, true /* evenPersistent */, false /* setRemoved */, + false /* uninstalling */, ApplicationExitInfo.REASON_PERMISSION_CHANGE, ApplicationExitInfo.SUBREASON_UNKNOWN, reason != null ? reason : "kill uid"); diff --git a/services/core/java/com/android/server/am/ProcessList.java b/services/core/java/com/android/server/am/ProcessList.java index b77270f5963bb..92c82232d4740 100644 --- a/services/core/java/com/android/server/am/ProcessList.java +++ b/services/core/java/com/android/server/am/ProcessList.java @@ -2750,8 +2750,8 @@ public final class ProcessList { int reasonCode, int subReason, String reason) { return killPackageProcessesLSP(packageName, appId, userId, minOomAdj, false /* callerWillRestart */, true /* allowRestart */, true /* doit */, - false /* evenPersistent */, false /* setRemoved */, reasonCode, - subReason, reason); + false /* evenPersistent */, false /* setRemoved */, false /* uninstalling */, + reasonCode, subReason, reason); } @GuardedBy("mService") @@ -2784,9 +2784,10 @@ public final class ProcessList { @GuardedBy({"mService", "mProcLock"}) boolean killPackageProcessesLSP(String packageName, int appId, int userId, int minOomAdj, boolean callerWillRestart, boolean allowRestart, - boolean doit, boolean evenPersistent, boolean setRemoved, int reasonCode, - int subReason, String reason) { - ArrayList procs = new ArrayList<>(); + boolean doit, boolean evenPersistent, boolean setRemoved, boolean uninstalling, + int reasonCode, int subReason, String reason) { + final PackageManagerInternal pm = mService.getPackageManagerInternal(); + final ArrayList> procs = new ArrayList<>(); // Remove all processes this package may have touched: all with the // same UID (except for the system or root user), and all whose name @@ -2803,7 +2804,18 @@ public final class ProcessList { } if (app.isRemoved()) { if (doit) { - procs.add(app); + boolean shouldAllowRestart = false; + if (!uninstalling && packageName != null) { + // This package has a dependency on the given package being stopped, + // while it's not being frozen nor uninstalled, allow to restart it. + shouldAllowRestart = !app.getPkgList().containsKey(packageName) + && app.getPkgDeps() != null + && app.getPkgDeps().contains(packageName) + && app.info != null + && !pm.isPackageFrozen(app.info.packageName, app.uid, + app.userId); + } + procs.add(new Pair<>(app, shouldAllowRestart)); } continue; } @@ -2818,6 +2830,8 @@ public final class ProcessList { continue; } + boolean shouldAllowRestart = false; + // If no package is specified, we call all processes under the // give user id. if (packageName == null) { @@ -2839,9 +2853,16 @@ public final class ProcessList { if (userId != UserHandle.USER_ALL && app.userId != userId) { continue; } - if (!app.getPkgList().containsKey(packageName) && !isDep) { + final boolean isInPkgList = app.getPkgList().containsKey(packageName); + if (!isInPkgList && !isDep) { continue; } + if (!isInPkgList && isDep && !uninstalling && app.info != null + && !pm.isPackageFrozen(app.info.packageName, app.uid, app.userId)) { + // This package has a dependency on the given package being stopped, + // while it's not being frozen nor uninstalled, allow to restart it. + shouldAllowRestart = true; + } } // Process has passed all conditions, kill it! @@ -2851,14 +2872,15 @@ public final class ProcessList { if (setRemoved) { app.setRemoved(true); } - procs.add(app); + procs.add(new Pair<>(app, shouldAllowRestart)); } } int N = procs.size(); for (int i=0; i proc = procs.get(i); + removeProcessLocked(proc.first, callerWillRestart, allowRestart || proc.second, + reasonCode, subReason, reason); } killAppZygotesLocked(packageName, appId, userId, false /* force */); mService.updateOomAdjLocked(OomAdjuster.OOM_ADJ_REASON_PROCESS_END); diff --git a/services/tests/servicestests/AndroidTest.xml b/services/tests/servicestests/AndroidTest.xml index 5a0f1ee963a2e..a95dad02000a2 100644 --- a/services/tests/servicestests/AndroidTest.xml +++ b/services/tests/servicestests/AndroidTest.xml @@ -16,6 +16,13 @@