Fix inconsistent behavior of killPackageDependents.
ActivityManagerService.killPackageDependents behaved inconsistently when
used with USER_ALL vs a specific user id. In both cases, processes that
have added a dependency on the specified package via
addPackageDependency were killed as expected, but processes owned by the
specified package were only being killed when a specific user id was
used, and were left alone when USER_ALL was specified.
Fix this by looping over all the users as other similar process-killing
methods do, instead of relying on a single call to
killPackageProcessesLSP.
This also adds proper usage of UserController.handleIncomingUser, making
it possible to use the API with USER_CURRENT. Killing dependents for all
users now requires INTERACT_ACROSS_USERS_FULL to be consistent with
other similar APIs - previously no permission other than KILL_UID was
required.
Bug: 310653407
Test: atest CtsAppTestCases:PackageDependencyTest
Flag: EXEMPT bugfix
Change-Id: I7a95758bab4fa2c8b33d5c6748a614848c9d8d9a
diff --git a/services/core/java/com/android/server/am/ActivityManagerService.java b/services/core/java/com/android/server/am/ActivityManagerService.java
index 3c57476..a379218 100644
--- a/services/core/java/com/android/server/am/ActivityManagerService.java
+++ b/services/core/java/com/android/server/am/ActivityManagerService.java
@@ -418,7 +418,6 @@
import com.android.internal.util.FrameworkStatsLog;
import com.android.internal.util.MemInfoReader;
import com.android.internal.util.Preconditions;
-import com.android.server.crashrecovery.CrashRecoveryHelper;
import com.android.server.AlarmManagerInternal;
import com.android.server.BootReceiver;
import com.android.server.DeviceIdleInternal;
@@ -438,6 +437,7 @@
import com.android.server.appop.AppOpsService;
import com.android.server.compat.PlatformCompat;
import com.android.server.contentcapture.ContentCaptureManagerInternal;
+import com.android.server.crashrecovery.CrashRecoveryHelper;
import com.android.server.criticalevents.CriticalEventLog;
import com.android.server.firewall.IntentFirewall;
import com.android.server.graphics.fonts.FontManagerInternal;
@@ -18376,25 +18376,34 @@
"Cannot kill the dependents of a package without its name.");
}
+ userId = mUserController.handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(),
+ userId, true, ALLOW_FULL_ONLY, "killPackageDependents", null);
+ final int[] userIds = mUserController.expandUserId(userId);
+
final long callingId = Binder.clearCallingIdentity();
IPackageManager pm = AppGlobals.getPackageManager();
- int pkgUid = -1;
try {
- pkgUid = pm.getPackageUid(packageName, MATCH_DEBUG_TRIAGED_MISSING, userId);
- } catch (RemoteException e) {
- }
- if (userId != UserHandle.USER_ALL && pkgUid == -1) {
- throw new IllegalArgumentException(
- "Cannot kill dependents of non-existing package " + packageName);
- }
- try {
- synchronized(this) {
- synchronized (mProcLock) {
- mProcessList.killPackageProcessesLSP(packageName, UserHandle.getAppId(pkgUid),
- userId, ProcessList.FOREGROUND_APP_ADJ,
- ApplicationExitInfo.REASON_DEPENDENCY_DIED,
- ApplicationExitInfo.SUBREASON_UNKNOWN,
- "dep: " + packageName);
+ for (int targetUserId : userIds) {
+ int pkgUid = -1;
+ try {
+ pkgUid = pm.getPackageUid(packageName, MATCH_DEBUG_TRIAGED_MISSING,
+ targetUserId);
+ } catch (RemoteException e) {
+ }
+ if (userId != UserHandle.USER_ALL && pkgUid == -1) {
+ throw new IllegalArgumentException(
+ "Cannot kill dependents of non-existing package " + packageName);
+ }
+ synchronized (this) {
+ synchronized (mProcLock) {
+ mProcessList.killPackageProcessesLSP(packageName,
+ UserHandle.getAppId(pkgUid),
+ targetUserId,
+ ProcessList.FOREGROUND_APP_ADJ,
+ ApplicationExitInfo.REASON_DEPENDENCY_DIED,
+ ApplicationExitInfo.SUBREASON_UNKNOWN,
+ "dep: " + packageName);
+ }
}
}
} finally {