Merge "Enforce DevicePolicyManager.setUserControlDisabledPackages in AppStandbyController" into rvc-dev am: b4083e039e
Original change: https://googleplex-android-review.googlesource.com/c/platform/frameworks/base/+/22301867
Change-Id: Ibf1c9fb61e6b987d2b5676ab8eb193d96e70515d
Signed-off-by: Automerger Merge Worker <android-build-automerger-merge-worker@system.gserviceaccount.com>
diff --git a/apex/jobscheduler/framework/java/com/android/server/usage/AppStandbyInternal.java b/apex/jobscheduler/framework/java/com/android/server/usage/AppStandbyInternal.java
index e15f0f3..0e98bf0 100644
--- a/apex/jobscheduler/framework/java/com/android/server/usage/AppStandbyInternal.java
+++ b/apex/jobscheduler/framework/java/com/android/server/usage/AppStandbyInternal.java
@@ -146,6 +146,8 @@
void setActiveAdminApps(Set<String> adminPkgs, int userId);
+ void setAdminProtectedPackages(Set<String> packageNames, int userId);
+
void onAdminDataAvailable();
void clearCarrierPrivilegedApps();
diff --git a/apex/jobscheduler/service/java/com/android/server/usage/AppStandbyController.java b/apex/jobscheduler/service/java/com/android/server/usage/AppStandbyController.java
index 36ccaf9..403e8b5 100644
--- a/apex/jobscheduler/service/java/com/android/server/usage/AppStandbyController.java
+++ b/apex/jobscheduler/service/java/com/android/server/usage/AppStandbyController.java
@@ -233,6 +233,10 @@
@GuardedBy("mActiveAdminApps")
private final SparseArray<Set<String>> mActiveAdminApps = new SparseArray<>();
+ /** List of admin protected packages. Can contain {@link android.os.UserHandle#USER_ALL}. */
+ @GuardedBy("mAdminProtectedPackages")
+ private final SparseArray<Set<String>> mAdminProtectedPackages = new SparseArray<>();
+
/**
* Set of system apps that are headless (don't have any declared activities, enabled or
* disabled). Presence in this map indicates that the app is a headless system app.
@@ -1019,6 +1023,9 @@
synchronized (mActiveAdminApps) {
mActiveAdminApps.remove(userId);
}
+ synchronized (mAdminProtectedPackages) {
+ mAdminProtectedPackages.remove(userId);
+ }
}
}
@@ -1108,6 +1115,10 @@
return STANDBY_BUCKET_EXEMPTED;
}
+ if (isAdminProtectedPackages(packageName, userId)) {
+ return STANDBY_BUCKET_EXEMPTED;
+ }
+
if (isActiveNetworkScorer(packageName)) {
return STANDBY_BUCKET_EXEMPTED;
}
@@ -1510,6 +1521,17 @@
}
}
+ private boolean isAdminProtectedPackages(String packageName, int userId) {
+ synchronized (mAdminProtectedPackages) {
+ if (mAdminProtectedPackages.contains(UserHandle.USER_ALL)
+ && mAdminProtectedPackages.get(UserHandle.USER_ALL).contains(packageName)) {
+ return true;
+ }
+ return mAdminProtectedPackages.contains(userId)
+ && mAdminProtectedPackages.get(userId).contains(packageName);
+ }
+ }
+
@Override
public void addActiveDeviceAdmin(String adminPkg, int userId) {
synchronized (mActiveAdminApps) {
@@ -1534,6 +1556,17 @@
}
@Override
+ public void setAdminProtectedPackages(Set<String> packageNames, int userId) {
+ synchronized (mAdminProtectedPackages) {
+ if (packageNames == null || packageNames.isEmpty()) {
+ mAdminProtectedPackages.remove(userId);
+ } else {
+ mAdminProtectedPackages.put(userId, packageNames);
+ }
+ }
+ }
+
+ @Override
public void onAdminDataAvailable() {
mAdminDataAvailableLatch.countDown();
}
@@ -1555,6 +1588,13 @@
}
}
+ @VisibleForTesting
+ Set<String> getAdminProtectedPackagesForTest(int userId) {
+ synchronized (mAdminProtectedPackages) {
+ return mAdminProtectedPackages.get(userId);
+ }
+ }
+
/**
* Returns {@code true} if the supplied package is the device provisioning app. Otherwise,
* returns {@code false}.
diff --git a/core/java/android/app/admin/DevicePolicyManager.java b/core/java/android/app/admin/DevicePolicyManager.java
index 92578dc9f..ee82555 100644
--- a/core/java/android/app/admin/DevicePolicyManager.java
+++ b/core/java/android/app/admin/DevicePolicyManager.java
@@ -11996,7 +11996,8 @@
/**
* Called by Device owner to disable user control over apps. User will not be able to clear
- * app data or force-stop packages.
+ * app data or force-stop packages. Packages with user control disabled are exempted from
+ * App Standby Buckets.
*
* @param admin which {@link DeviceAdminReceiver} this request is associated with
* @param packages The package names for the apps.
diff --git a/services/core/java/android/app/usage/UsageStatsManagerInternal.java b/services/core/java/android/app/usage/UsageStatsManagerInternal.java
index fa84427..920fe1b 100644
--- a/services/core/java/android/app/usage/UsageStatsManagerInternal.java
+++ b/services/core/java/android/app/usage/UsageStatsManagerInternal.java
@@ -199,6 +199,16 @@
public abstract void setActiveAdminApps(Set<String> adminApps, int userId);
/**
+ * Called by DevicePolicyManagerService to inform about the protected packages for a user.
+ * User control will be disabled for protected packages.
+ *
+ * @param packageNames the set of protected packages for {@code userId}.
+ * @param userId the userId to which the protected packages belong.
+ */
+ public abstract void setAdminProtectedPackages(@Nullable Set<String> packageNames,
+ @UserIdInt int userId);
+
+ /**
* Called by DevicePolicyManagerService during boot to inform that admin data is loaded and
* pushed to UsageStatsService.
*/
diff --git a/services/devicepolicy/java/com/android/server/devicepolicy/DevicePolicyManagerService.java b/services/devicepolicy/java/com/android/server/devicepolicy/DevicePolicyManagerService.java
index e405771..3ca8ffb 100644
--- a/services/devicepolicy/java/com/android/server/devicepolicy/DevicePolicyManagerService.java
+++ b/services/devicepolicy/java/com/android/server/devicepolicy/DevicePolicyManagerService.java
@@ -4021,7 +4021,9 @@
updateMaximumTimeToLockLocked(userHandle);
updateLockTaskPackagesLocked(policy.mLockTaskPackages, userHandle);
updateLockTaskFeaturesLocked(policy.mLockTaskFeatures, userHandle);
- updateUserControlDisabledPackagesLocked(policy.mUserControlDisabledPackages);
+ if (userHandle == UserHandle.USER_SYSTEM) {
+ updateUserControlDisabledPackagesLocked(policy.mUserControlDisabledPackages);
+ }
if (policy.mStatusBarDisabled) {
setStatusBarDisabledInternal(policy.mStatusBarDisabled, userHandle);
}
@@ -4049,6 +4051,8 @@
private void updateUserControlDisabledPackagesLocked(List<String> packages) {
mInjector.getPackageManagerInternal().setDeviceOwnerProtectedPackages(packages);
+ mUsageStatsManagerInternal.setAdminProtectedPackages(
+ new ArraySet(packages), UserHandle.USER_ALL);
}
private void updateLockTaskFeaturesLocked(int flags, int userId) {
diff --git a/services/tests/servicestests/src/com/android/server/usage/AppStandbyControllerTests.java b/services/tests/servicestests/src/com/android/server/usage/AppStandbyControllerTests.java
index 1ced467..8da4fed 100644
--- a/services/tests/servicestests/src/com/android/server/usage/AppStandbyControllerTests.java
+++ b/services/tests/servicestests/src/com/android/server/usage/AppStandbyControllerTests.java
@@ -125,6 +125,9 @@
private static final String ADMIN_PKG2 = "com.android.admin2";
private static final String ADMIN_PKG3 = "com.android.admin3";
+ private static final String ADMIN_PROTECTED_PKG = "com.android.admin.protected";
+ private static final String ADMIN_PROTECTED_PKG2 = "com.android.admin.protected2";
+
private static final long MINUTE_MS = 60 * 1000;
private static final long HOUR_MS = 60 * MINUTE_MS;
private static final long DAY_MS = 24 * HOUR_MS;
@@ -1370,6 +1373,19 @@
}
@Test
+ public void testSetAdminProtectedPackages() {
+ assertAdminProtectedPackagesForTest(USER_ID, (String[]) null);
+ assertAdminProtectedPackagesForTest(USER_ID2, (String[]) null);
+
+ setAdminProtectedPackages(USER_ID, ADMIN_PROTECTED_PKG, ADMIN_PROTECTED_PKG2);
+ assertAdminProtectedPackagesForTest(USER_ID, ADMIN_PROTECTED_PKG, ADMIN_PROTECTED_PKG2);
+ assertAdminProtectedPackagesForTest(USER_ID2, (String[]) null);
+
+ setAdminProtectedPackages(USER_ID, (String[]) null);
+ assertAdminProtectedPackagesForTest(USER_ID, (String[]) null);
+ }
+
+ @Test
public void testUserInteraction_CrossProfile() throws Exception {
mInjector.mRunningUsers = new int[] {USER_ID, USER_ID2, USER_ID3};
mInjector.mCrossProfileTargets = Arrays.asList(USER_HANDLE_USER2);
@@ -1593,6 +1609,28 @@
mController.setActiveAdminApps(new ArraySet<>(Arrays.asList(admins)), userId);
}
+ private void setAdminProtectedPackages(int userId, String... packageNames) {
+ Set<String> adminProtectedPackages = packageNames != null ? new ArraySet<>(
+ Arrays.asList(packageNames)) : null;
+ mController.setAdminProtectedPackages(adminProtectedPackages, userId);
+ }
+
+ private void assertAdminProtectedPackagesForTest(int userId, String... packageNames) {
+ final Set<String> actualAdminProtectedPackages =
+ mController.getAdminProtectedPackagesForTest(userId);
+ if (packageNames == null) {
+ if (actualAdminProtectedPackages != null && !actualAdminProtectedPackages.isEmpty()) {
+ fail("Admin protected packages should be null; " + getAdminAppsStr(userId,
+ actualAdminProtectedPackages));
+ }
+ return;
+ }
+ assertEquals(packageNames.length, actualAdminProtectedPackages.size());
+ for (String adminProtectedPackage : packageNames) {
+ assertTrue(actualAdminProtectedPackages.contains(adminProtectedPackage));
+ }
+ }
+
private void setAndAssertBucket(String pkg, int user, int bucket, int reason) throws Exception {
rearmLatch(pkg);
mController.setAppStandbyBucket(pkg, user, bucket, reason);
diff --git a/services/usage/java/com/android/server/usage/UsageStatsService.java b/services/usage/java/com/android/server/usage/UsageStatsService.java
index a54f263..c0b3fee 100644
--- a/services/usage/java/com/android/server/usage/UsageStatsService.java
+++ b/services/usage/java/com/android/server/usage/UsageStatsService.java
@@ -2303,6 +2303,11 @@
}
@Override
+ public void setAdminProtectedPackages(Set<String> packageNames, int userId) {
+ mAppStandby.setAdminProtectedPackages(packageNames, userId);
+ }
+
+ @Override
public void onAdminDataAvailable() {
mAppStandby.onAdminDataAvailable();
}