From 3c80539c5dcb1c10db43a47cdf93ca05ccb28d29 Mon Sep 17 00:00:00 2001 From: Alex Johnston Date: Wed, 15 Feb 2023 19:55:45 +0000 Subject: [PATCH] Add exemption check for OP_SYSTEM_EXEMPT_FROM_SUSPENSION If an app has the OP_SYSTEM_EXEMPT_FROM_SUSPENSION appop, it cannot be suspended. Add the exemption to SuspendPackageHelper. Bug: 246330879 Test: atest SuspendPackageHelperTest Manual testing with adb and Settings Change-Id: I72b73324f64f330a9d1ee925dee64d42e0455548 (cherry picked from commit 9a276332ae92783130621b2f8f1c101fbefe8826) Merged-In: I72b73324f64f330a9d1ee925dee64d42e0455548 --- .../android/server/pm/SuspendPackageHelper.java | 17 +++++++++++++++++ 1 file changed, 17 insertions(+) diff --git a/services/core/java/com/android/server/pm/SuspendPackageHelper.java b/services/core/java/com/android/server/pm/SuspendPackageHelper.java index 07d36b311aacf..18eebe45a7599 100644 --- a/services/core/java/com/android/server/pm/SuspendPackageHelper.java +++ b/services/core/java/com/android/server/pm/SuspendPackageHelper.java @@ -27,6 +27,7 @@ import android.annotation.NonNull; import android.annotation.Nullable; import android.annotation.UserIdInt; import android.app.ActivityManager; +import android.app.AppOpsManager; import android.app.IActivityManager; import android.app.admin.DevicePolicyManagerInternal; import android.content.Intent; @@ -39,6 +40,7 @@ import android.os.PersistableBundle; import android.os.Process; import android.os.UserHandle; import android.os.UserManager; +import android.provider.DeviceConfig; import android.util.ArrayMap; import android.util.ArraySet; import android.util.IntArray; @@ -63,6 +65,9 @@ import java.util.Set; import java.util.function.Predicate; public final class SuspendPackageHelper { + + private static final String SYSTEM_EXEMPT_FROM_SUSPENSION = "system_exempt_from_suspension"; + // TODO(b/198166813): remove PMS dependency private final PackageManagerService mPm; private final PackageManagerServiceInjector mInjector; @@ -502,6 +507,10 @@ public final class SuspendPackageHelper { final String requiredPermissionControllerPackage = getKnownPackageName(snapshot, KnownPackages.PACKAGE_PERMISSION_CONTROLLER, userId); + final AppOpsManager appOpsManager = mInjector.getSystemService(AppOpsManager.class); + final boolean isSystemExemptFlagEnabled = DeviceConfig.getBoolean( + DeviceConfig.NAMESPACE_PACKAGE_MANAGER_SERVICE, + SYSTEM_EXEMPT_FROM_SUSPENSION, /* defaultValue= */ true); for (int i = 0; i < packageNames.length; i++) { canSuspend[i] = false; final String packageName = packageNames[i]; @@ -558,6 +567,7 @@ public final class SuspendPackageHelper { PackageStateInternal packageState = snapshot.getPackageStateInternal(packageName); AndroidPackage pkg = packageState == null ? null : packageState.getPkg(); if (pkg != null) { + final int uid = UserHandle.getUid(userId, packageState.getAppId()); // Cannot suspend SDK libs as they are controlled by SDK manager. if (pkg.isSdkLibrary()) { Slog.w(TAG, "Cannot suspend package: " + packageName @@ -574,6 +584,13 @@ public final class SuspendPackageHelper { + pkg.getStaticSharedLibraryName()); continue; } + if (isSystemExemptFlagEnabled && appOpsManager.checkOpNoThrow( + AppOpsManager.OP_SYSTEM_EXEMPT_FROM_SUSPENSION, uid, packageName) + == AppOpsManager.MODE_ALLOWED) { + Slog.w(TAG, "Cannot suspend package \"" + packageName + + "\": has OP_SYSTEM_EXEMPT_FROM_SUSPENSION set"); + continue; + } } if (PLATFORM_PACKAGE_NAME.equals(packageName)) { Slog.w(TAG, "Cannot suspend the platform package: " + packageName);