diff --git a/services/core/java/com/android/server/am/ActivityManagerService.java b/services/core/java/com/android/server/am/ActivityManagerService.java index 4ec84a0b1b837..3f41964115ea0 100644 --- a/services/core/java/com/android/server/am/ActivityManagerService.java +++ b/services/core/java/com/android/server/am/ActivityManagerService.java @@ -4190,7 +4190,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, @@ -7227,6 +7227,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"); @@ -7248,6 +7249,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 f35afa5b7ca0f..fb38aec09a44e 100644 --- a/services/core/java/com/android/server/am/ProcessList.java +++ b/services/core/java/com/android/server/am/ProcessList.java @@ -2751,8 +2751,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") @@ -2785,9 +2785,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 @@ -2804,7 +2805,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; } @@ -2819,6 +2831,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) { @@ -2840,9 +2854,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! @@ -2852,14 +2873,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 4c638d669019f..bb3eb81df6ed7 100644 --- a/services/tests/servicestests/AndroidTest.xml +++ b/services/tests/servicestests/AndroidTest.xml @@ -16,6 +16,13 @@