diff --git a/services/core/java/com/android/server/pm/PackageManagerService.java b/services/core/java/com/android/server/pm/PackageManagerService.java index 419e4ad19e71f..f2c93d5c65146 100644 --- a/services/core/java/com/android/server/pm/PackageManagerService.java +++ b/services/core/java/com/android/server/pm/PackageManagerService.java @@ -1128,6 +1128,7 @@ public class PackageManagerService extends IPackageManager.Stub { final @NonNull String mRequiredInstallerPackage; final @NonNull String mRequiredUninstallerPackage; final @Nullable String mSetupWizardPackage; + final @Nullable String mStorageManagerPackage; final @NonNull String mServicesSystemSharedLibraryPackageName; final @NonNull String mSharedSystemSharedLibraryPackageName; @@ -2469,6 +2470,9 @@ public class PackageManagerService extends IPackageManager.Stub { } mExpectingBetter.clear(); + // Resolve the storage manager. + mStorageManagerPackage = getStorageManagerPackageName(); + // Resolve protected action filters. Only the setup wizard is allowed to // have a high priority filter for these actions. mSetupWizardPackage = getSetupWizardPackageName(); @@ -15513,6 +15517,12 @@ public class PackageManagerService extends IPackageManager.Stub { callingUid == getPackageUid(mRequiredUninstallerPackage, 0, callingUserId)) { return true; } + + // Allow storage manager to silently uninstall. + if (mStorageManagerPackage != null && + callingUid == getPackageUid(mStorageManagerPackage, 0, callingUserId)) { + return true; + } return false; } @@ -17728,6 +17738,22 @@ Slog.v(TAG, ":: stepped forward, applying functor at tag " + parser.getName()); } } + private @Nullable String getStorageManagerPackageName() { + final Intent intent = new Intent(StorageManager.ACTION_MANAGE_STORAGE); + + final List matches = queryIntentActivitiesInternal(intent, null, + MATCH_SYSTEM_ONLY | MATCH_DIRECT_BOOT_AWARE | MATCH_DIRECT_BOOT_UNAWARE + | MATCH_DISABLED_COMPONENTS, + UserHandle.myUserId()); + if (matches.size() == 1) { + return matches.get(0).getComponentInfo().packageName; + } else { + Slog.e(TAG, "There should probably be exactly one storage manager; found " + + matches.size() + ": matches=" + matches); + return null; + } + } + @Override public void setApplicationEnabledSetting(String appPackageName, int newState, int flags, int userId, String callingPackage) {