diff --git a/services/devicepolicy/java/com/android/server/devicepolicy/ActiveAdmin.java b/services/devicepolicy/java/com/android/server/devicepolicy/ActiveAdmin.java index 3912991a41edd..0c69067ab1311 100644 --- a/services/devicepolicy/java/com/android/server/devicepolicy/ActiveAdmin.java +++ b/services/devicepolicy/java/com/android/server/devicepolicy/ActiveAdmin.java @@ -157,13 +157,14 @@ class ActiveAdmin { private static final String TAG_SSID_ALLOWLIST = "ssid-allowlist"; private static final String TAG_SSID_DENYLIST = "ssid-denylist"; private static final String TAG_SSID = "ssid"; - private static final String ATTR_VALUE = "value"; - private static final String ATTR_LAST_NETWORK_LOGGING_NOTIFICATION = "last-notification"; - private static final String ATTR_NUM_NETWORK_LOGGING_NOTIFICATIONS = "num-notifications"; private static final String TAG_PREFERENTIAL_NETWORK_SERVICE_CONFIGS = "preferential_network_service_configs"; private static final String TAG_PREFERENTIAL_NETWORK_SERVICE_CONFIG = "preferential_network_service_config"; + private static final String TAG_PROTECTED_PACKAGES = "protected_packages"; + private static final String ATTR_VALUE = "value"; + private static final String ATTR_LAST_NETWORK_LOGGING_NOTIFICATION = "last-notification"; + private static final String ATTR_NUM_NETWORK_LOGGING_NOTIFICATIONS = "num-notifications"; DeviceAdminInfo info; @@ -253,6 +254,9 @@ class ActiveAdmin { // List of package names to keep cached. List keepUninstalledPackages; + // List of packages for which the user cannot invoke "clear data" or "force stop". + List protectedPackages; + // Wi-Fi SSID restriction policy. WifiSsidPolicy mWifiSsidPolicy; @@ -505,6 +509,7 @@ class ActiveAdmin { permittedNotificationListeners); writePackageListToXml(out, TAG_KEEP_UNINSTALLED_PACKAGES, keepUninstalledPackages); writePackageListToXml(out, TAG_METERED_DATA_DISABLED_PACKAGES, meteredDisabledPackages); + writePackageListToXml(out, TAG_PROTECTED_PACKAGES, protectedPackages); if (hasUserRestrictions()) { UserRestrictionsUtils.writeRestrictions( out, userRestrictions, TAG_USER_RESTRICTIONS); @@ -771,6 +776,8 @@ class ActiveAdmin { keepUninstalledPackages = readPackageList(parser, tag); } else if (TAG_METERED_DATA_DISABLED_PACKAGES.equals(tag)) { meteredDisabledPackages = readPackageList(parser, tag); + } else if (TAG_PROTECTED_PACKAGES.equals(tag)) { + protectedPackages = readPackageList(parser, tag); } else if (TAG_USER_RESTRICTIONS.equals(tag)) { userRestrictions = UserRestrictionsUtils.readRestrictions(parser); } else if (TAG_DEFAULT_ENABLED_USER_RESTRICTIONS.equals(tag)) { @@ -1210,6 +1217,16 @@ class ActiveAdmin { pw.println(keepUninstalledPackages); } + if (meteredDisabledPackages != null) { + pw.print("meteredDisabledPackages="); + pw.println(meteredDisabledPackages); + } + + if (protectedPackages != null) { + pw.print("protectedPackages="); + pw.println(protectedPackages); + } + pw.print("organizationColor="); pw.println(organizationColor); diff --git a/services/devicepolicy/java/com/android/server/devicepolicy/DevicePolicyData.java b/services/devicepolicy/java/com/android/server/devicepolicy/DevicePolicyData.java index 48a436f158038..fd97db23f01aa 100644 --- a/services/devicepolicy/java/com/android/server/devicepolicy/DevicePolicyData.java +++ b/services/devicepolicy/java/com/android/server/devicepolicy/DevicePolicyData.java @@ -17,6 +17,7 @@ package com.android.server.devicepolicy; import android.annotation.NonNull; +import android.annotation.Nullable; import android.annotation.UserIdInt; import android.app.admin.DeviceAdminInfo; import android.app.admin.DevicePolicyManager; @@ -129,8 +130,10 @@ class DevicePolicyData { // This is the list of component allowed to start lock task mode. List mLockTaskPackages = new ArrayList<>(); - // List of packages protected by device owner - List mUserControlDisabledPackages = new ArrayList<>(); + /** @deprecated moved to {@link ActiveAdmin#protectedPackages}. */ + @Deprecated + @Nullable + List mUserControlDisabledPackages; // Bitfield of feature flags to be enabled during LockTask mode. // We default on the power button menu, in order to be consistent with pre-P behaviour. @@ -364,13 +367,6 @@ class DevicePolicyData { out.endTag(null, TAG_OWNER_INSTALLED_CA_CERT); } - for (int i = 0, size = policyData.mUserControlDisabledPackages.size(); i < size; i++) { - String packageName = policyData.mUserControlDisabledPackages.get(i); - out.startTag(null, TAG_PROTECTED_PACKAGES); - out.attribute(null, ATTR_NAME, packageName); - out.endTag(null, TAG_PROTECTED_PACKAGES); - } - if (policyData.mAppsSuspended) { out.startTag(null, TAG_APPS_SUSPENDED); out.attributeBoolean(null, ATTR_VALUE, policyData.mAppsSuspended); @@ -473,7 +469,7 @@ class DevicePolicyData { policy.mAdminMap.clear(); policy.mAffiliationIds.clear(); policy.mOwnerInstalledCaCerts.clear(); - policy.mUserControlDisabledPackages.clear(); + policy.mUserControlDisabledPackages = null; while ((type = parser.next()) != XmlPullParser.END_DOCUMENT && (type != XmlPullParser.END_TAG || parser.getDepth() > outerDepth)) { if (type == XmlPullParser.END_TAG || type == XmlPullParser.TEXT) { @@ -561,15 +557,19 @@ class DevicePolicyData { policy.mCurrentInputMethodSet = true; } else if (TAG_OWNER_INSTALLED_CA_CERT.equals(tag)) { policy.mOwnerInstalledCaCerts.add(parser.getAttributeValue(null, ATTR_ALIAS)); - } else if (TAG_PROTECTED_PACKAGES.equals(tag)) { - policy.mUserControlDisabledPackages.add( - parser.getAttributeValue(null, ATTR_NAME)); } else if (TAG_APPS_SUSPENDED.equals(tag)) { policy.mAppsSuspended = parser.getAttributeBoolean(null, ATTR_VALUE, false); } else if (TAG_BYPASS_ROLE_QUALIFICATIONS.equals(tag)) { policy.mBypassDevicePolicyManagementRoleQualifications = true; policy.mCurrentRoleHolder = parser.getAttributeValue(null, ATTR_VALUE); + // Deprecated tags below + } else if (TAG_PROTECTED_PACKAGES.equals(tag)) { + if (policy.mUserControlDisabledPackages == null) { + policy.mUserControlDisabledPackages = new ArrayList<>(); + } + policy.mUserControlDisabledPackages.add( + parser.getAttributeValue(null, ATTR_NAME)); } else { Slogf.w(TAG, "Unknown tag: %s", tag); XmlUtils.skipCurrentTag(parser); @@ -674,8 +674,6 @@ class DevicePolicyData { pw.increaseIndent(); pw.print("mPasswordOwner="); pw.println(mPasswordOwner); pw.print("mPasswordTokenHandle="); pw.println(Long.toHexString(mPasswordTokenHandle)); - pw.print("mUserControlDisabledPackages="); - pw.println(mUserControlDisabledPackages); pw.print("mAppsSuspended="); pw.println(mAppsSuspended); pw.print("mUserSetupComplete="); pw.println(mUserSetupComplete); pw.print("mAffiliationIds="); pw.println(mAffiliationIds); diff --git a/services/devicepolicy/java/com/android/server/devicepolicy/DevicePolicyManagerService.java b/services/devicepolicy/java/com/android/server/devicepolicy/DevicePolicyManagerService.java index 8a7134e24cf86..372cb5d244e85 100644 --- a/services/devicepolicy/java/com/android/server/devicepolicy/DevicePolicyManagerService.java +++ b/services/devicepolicy/java/com/android/server/devicepolicy/DevicePolicyManagerService.java @@ -536,7 +536,7 @@ public class DevicePolicyManagerService extends BaseIDevicePolicyManager { // to decide whether an existing policy in the {@link #DEVICE_POLICIES_XML} needs to // be upgraded. See {@link PolicyVersionUpgrader} on instructions how to add an upgrade // step. - static final int DPMS_VERSION = 2; + static final int DPMS_VERSION = 3; static { SECURE_SETTINGS_ALLOWLIST = new ArraySet<>(); @@ -1908,38 +1908,11 @@ public class DevicePolicyManagerService extends BaseIDevicePolicyManager { if (userHandle == UserHandle.USER_SYSTEM) { mStateCache.setDeviceProvisioned(policy.mUserSetupComplete); } - - migrateDeviceOwnerProtectedPackagesToOwners(userHandle, policy); } return policy; } } - /** - * Only used by {@link #getUserData(int)} to migrate existing device owner protected - * packages that were stored in {@link DevicePolicyData#mUserControlDisabledPackages} to - * {@link Owners} because the device owner protected packages are now stored on a per device - * owner basis instead of on a per user basis. - * - * Any calls to {@link #setUserControlDisabledPackages(ComponentName, List)} would now store - * the device owner protected packages in {@link Owners} instead of {@link DevicePolicyData}. - * @param userHandle The device owner user - * @param policy The policy data of the device owner user - */ - private void migrateDeviceOwnerProtectedPackagesToOwners( - int userHandle, DevicePolicyData policy) { - ComponentName deviceOwnerComponent = getOwnerComponent(userHandle); - if (isDeviceOwner(deviceOwnerComponent, userHandle) - && !policy.mUserControlDisabledPackages.isEmpty()) { - mOwners.setDeviceOwnerProtectedPackages( - deviceOwnerComponent.getPackageName(), - policy.mUserControlDisabledPackages); - - policy.mUserControlDisabledPackages = new ArrayList<>(); - saveSettingsLocked(userHandle); - } - } - /** * Creates and loads the policy data from xml for data that is shared between * various profiles of a user. In contrast to {@link #getUserData(int)} @@ -3182,6 +3155,7 @@ public class DevicePolicyManagerService extends BaseIDevicePolicyManager { void handleStartUser(int userId) { synchronized (getLockObject()) { pushScreenCapturePolicy(userId); + pushUserControlDisabledPackagesLocked(userId); } pushUserRestrictions(userId); // When system user is started (device boot), load cache for all users. @@ -3204,6 +3178,20 @@ public class DevicePolicyManagerService extends BaseIDevicePolicyManager { startOwnerService(userId, "start-user"); } + // TODO(b/218639412): Once PM stores these on a per-user basis, push even empty lists to handle + // DO/PO removal correctly. + void pushUserControlDisabledPackagesLocked(int userId) { + if (userId != mOwners.getDeviceOwnerUserId()) { + return; + } + ActiveAdmin deviceOwner = getDeviceOwnerAdminLocked(); + if (deviceOwner == null || deviceOwner.protectedPackages == null) { + return; + } + mInjector.getPackageManagerInternal().setDeviceOwnerProtectedPackages( + deviceOwner.info.getPackageName(), deviceOwner.protectedPackages); + } + @Override void handleUnlockUser(int userId) { startOwnerService(userId, "unlock-user"); @@ -8795,6 +8783,7 @@ public class DevicePolicyManagerService extends BaseIDevicePolicyManager { setNetworkLoggingActiveInternal(false); deleteTransferOwnershipBundleLocked(userId); toggleBackupServiceActive(UserHandle.USER_SYSTEM, true); + pushUserControlDisabledPackagesLocked(userId); } private void clearApplicationRestrictions(int userId) { @@ -8979,7 +8968,6 @@ public class DevicePolicyManagerService extends BaseIDevicePolicyManager { policy.mLockTaskPackages.clear(); updateLockTaskPackagesLocked(policy.mLockTaskPackages, userId); policy.mLockTaskFeatures = DevicePolicyManager.LOCK_TASK_FEATURE_NONE; - policy.mUserControlDisabledPackages.clear(); saveSettingsLocked(userId); try { @@ -16976,13 +16964,22 @@ public class DevicePolicyManagerService extends BaseIDevicePolicyManager { DevicePolicyManager.OPERATION_SET_USER_CONTROL_DISABLED_PACKAGES); synchronized (getLockObject()) { - mOwners.setDeviceOwnerProtectedPackages(who.getPackageName(), packages); - DevicePolicyEventLogger - .createEvent(DevicePolicyEnums.SET_USER_CONTROL_DISABLED_PACKAGES) - .setAdmin(who) - .setStrings(packages.toArray(new String[packages.size()])) - .write(); + ActiveAdmin deviceOwner = getDeviceOwnerAdminLocked(); + if (!Objects.equals(deviceOwner.protectedPackages, packages)) { + deviceOwner.protectedPackages = packages.isEmpty() ? null : packages; + saveSettingsLocked(caller.getUserId()); + } } + + mInjector.binderWithCleanCallingIdentity( + () -> mInjector.getPackageManagerInternal().setDeviceOwnerProtectedPackages( + who.getPackageName(), packages)); + + DevicePolicyEventLogger + .createEvent(DevicePolicyEnums.SET_USER_CONTROL_DISABLED_PACKAGES) + .setAdmin(who) + .setStrings(packages.toArray(new String[packages.size()])) + .write(); } @Override @@ -16994,7 +16991,9 @@ public class DevicePolicyManagerService extends BaseIDevicePolicyManager { isDefaultDeviceOwner(caller) || isFinancedDeviceOwner(caller)); synchronized (getLockObject()) { - return mOwners.getDeviceOwnerProtectedPackages(who.getPackageName()); + ActiveAdmin deviceOwner = getDeviceOwnerAdminLocked(); + return deviceOwner.protectedPackages != null + ? deviceOwner.protectedPackages : Collections.emptyList(); } } diff --git a/services/devicepolicy/java/com/android/server/devicepolicy/Owners.java b/services/devicepolicy/java/com/android/server/devicepolicy/Owners.java index d1c6b3411b202..08bd3e4c7c47e 100644 --- a/services/devicepolicy/java/com/android/server/devicepolicy/Owners.java +++ b/services/devicepolicy/java/com/android/server/devicepolicy/Owners.java @@ -31,7 +31,6 @@ import android.os.Binder; import android.os.Process; import android.os.UserHandle; import android.os.UserManager; -import android.util.ArrayMap; import android.util.ArraySet; import android.util.IndentingPrintWriter; import android.util.Pair; @@ -49,7 +48,6 @@ import com.android.server.wm.ActivityTaskManagerInternal; import java.io.File; import java.time.LocalDate; import java.util.ArrayList; -import java.util.Collections; import java.util.List; import java.util.Objects; import java.util.Set; @@ -108,12 +106,6 @@ class Owners { notifyChangeLocked(); pushToActivityTaskManagerLocked(); - - for (ArrayMap.Entry> entry : - mData.mDeviceOwnerProtectedPackages.entrySet()) { - mPackageManagerInternal.setDeviceOwnerProtectedPackages( - entry.getKey(), entry.getValue()); - } } } @@ -247,12 +239,6 @@ class Owners { void clearDeviceOwner() { synchronized (mData) { mData.mDeviceOwnerTypes.remove(mData.mDeviceOwner.packageName); - List protectedPackages = - mData.mDeviceOwnerProtectedPackages.remove(mData.mDeviceOwner.packageName); - if (protectedPackages != null) { - mPackageManagerInternal.setDeviceOwnerProtectedPackages( - mData.mDeviceOwner.packageName, new ArrayList<>()); - } mData.mDeviceOwner = null; mData.mDeviceOwnerUserId = UserHandle.USER_NULL; @@ -296,12 +282,6 @@ class Owners { synchronized (mData) { Integer previousDeviceOwnerType = mData.mDeviceOwnerTypes.remove( mData.mDeviceOwner.packageName); - List previousProtectedPackages = - mData.mDeviceOwnerProtectedPackages.remove(mData.mDeviceOwner.packageName); - if (previousProtectedPackages != null) { - mPackageManagerInternal.setDeviceOwnerProtectedPackages( - mData.mDeviceOwner.packageName, new ArrayList<>()); - } // We don't set a name because it's not used anyway. // See DevicePolicyManagerService#getDeviceOwnerName mData.mDeviceOwner = new OwnerInfo(null, target, @@ -313,10 +293,6 @@ class Owners { mData.mDeviceOwnerTypes.put( mData.mDeviceOwner.packageName, previousDeviceOwnerType); } - if (previousProtectedPackages != null) { - mData.mDeviceOwnerProtectedPackages.put( - mData.mDeviceOwner.packageName, previousProtectedPackages); - } notifyChangeLocked(); pushToActivityTaskManagerLocked(); } @@ -504,34 +480,6 @@ class Owners { } } - void setDeviceOwnerProtectedPackages(String packageName, List protectedPackages) { - synchronized (mData) { - if (!hasDeviceOwner()) { - Slog.e(TAG, - "Attempting to set device owner protected packages when there is no " - + "device owner"); - return; - } else if (!mData.mDeviceOwner.packageName.equals(packageName)) { - Slog.e(TAG, "Attempting to set device owner protected packages when the provided " - + "package name " + packageName - + " does not match the device owner package name"); - return; - } - - mData.mDeviceOwnerProtectedPackages.put(packageName, protectedPackages); - mPackageManagerInternal.setDeviceOwnerProtectedPackages(packageName, protectedPackages); - writeDeviceOwner(); - } - } - - List getDeviceOwnerProtectedPackages(String packageName) { - synchronized (mData) { - return mData.mDeviceOwnerProtectedPackages.containsKey(packageName) - ? mData.mDeviceOwnerProtectedPackages.get(packageName) - : Collections.emptyList(); - } - } - void writeDeviceOwner() { synchronized (mData) { pushToDevicePolicyManager(); diff --git a/services/devicepolicy/java/com/android/server/devicepolicy/OwnersData.java b/services/devicepolicy/java/com/android/server/devicepolicy/OwnersData.java index 4fe4f0d83f1ae..694842034d1fc 100644 --- a/services/devicepolicy/java/com/android/server/devicepolicy/OwnersData.java +++ b/services/devicepolicy/java/com/android/server/devicepolicy/OwnersData.java @@ -91,8 +91,10 @@ class OwnersData { // Device owner type for a managed device. final ArrayMap mDeviceOwnerTypes = new ArrayMap<>(); - final ArrayMap> mDeviceOwnerProtectedPackages = new ArrayMap<>(); - + /** @deprecated moved to {@link ActiveAdmin#protectedPackages}. */ + @Deprecated + @Nullable + ArrayMap> mDeviceOwnerProtectedPackages; // Internal state for the profile owner packages. final ArrayMap mProfileOwners = new ArrayMap<>(); @@ -366,21 +368,6 @@ class OwnersData { } } - if (!mDeviceOwnerProtectedPackages.isEmpty()) { - for (ArrayMap.Entry> entry : - mDeviceOwnerProtectedPackages.entrySet()) { - List protectedPackages = entry.getValue(); - - out.startTag(null, TAG_DEVICE_OWNER_PROTECTED_PACKAGES); - out.attribute(null, ATTR_PACKAGE, entry.getKey()); - out.attributeInt(null, ATTR_SIZE, protectedPackages.size()); - for (int i = 0, size = protectedPackages.size(); i < size; i++) { - out.attribute(null, ATTR_NAME + i, protectedPackages.get(i)); - } - out.endTag(null, TAG_DEVICE_OWNER_PROTECTED_PACKAGES); - } - } - if (mSystemUpdatePolicy != null) { out.startTag(null, TAG_SYSTEM_UPDATE_POLICY); mSystemUpdatePolicy.saveToXml(out); @@ -444,6 +431,7 @@ class OwnersData { null, ATTR_DEVICE_OWNER_TYPE_VALUE, DEVICE_OWNER_TYPE_DEFAULT); mDeviceOwnerTypes.put(packageName, deviceOwnerType); break; + // Deprecated fields below. case TAG_DEVICE_OWNER_PROTECTED_PACKAGES: packageName = parser.getAttributeValue(null, ATTR_PACKAGE); int protectedPackagesSize = parser.getAttributeInt(null, ATTR_SIZE, 0); @@ -451,6 +439,9 @@ class OwnersData { for (int i = 0; i < protectedPackagesSize; i++) { protectedPackages.add(parser.getAttributeValue(null, ATTR_NAME + i)); } + if (mDeviceOwnerProtectedPackages == null) { + mDeviceOwnerProtectedPackages = new ArrayMap<>(); + } mDeviceOwnerProtectedPackages.put(packageName, protectedPackages); break; default: diff --git a/services/devicepolicy/java/com/android/server/devicepolicy/PolicyVersionUpgrader.java b/services/devicepolicy/java/com/android/server/devicepolicy/PolicyVersionUpgrader.java index 7556d690f6fd0..253851cdbf68e 100644 --- a/services/devicepolicy/java/com/android/server/devicepolicy/PolicyVersionUpgrader.java +++ b/services/devicepolicy/java/com/android/server/devicepolicy/PolicyVersionUpgrader.java @@ -16,6 +16,7 @@ package com.android.server.devicepolicy; +import android.annotation.Nullable; import android.content.ComponentName; import android.os.UserHandle; import android.util.Slog; @@ -28,6 +29,8 @@ import java.io.File; import java.io.IOException; import java.nio.charset.Charset; import java.nio.file.Files; +import java.util.ArrayList; +import java.util.List; /** * Class for dealing with Device Policy Manager Service version upgrades. @@ -91,30 +94,82 @@ public class PolicyVersionUpgrader { if (currentVersion == 1) { Slog.i(LOG_TAG, String.format("Upgrading from version %d", currentVersion)); - // This upgrade step is for Device Owner scenario only: For devices upgrading to S, - // if there is a device owner, it retains the ability to control sensors-related - // permission grants. - for (int userId : allUsers) { - DevicePolicyData userData = allUsersData.get(userId); - if (userData == null) { - continue; - } - for (ActiveAdmin admin : userData.mAdminList) { - if (ownersData.mDeviceOwnerUserId == userId - && ownersData.mDeviceOwner != null - && ownersData.mDeviceOwner.admin.equals(admin.info.getComponent())) { - Slog.i(LOG_TAG, String.format( - "Marking Device Owner in user %d for permission grant ", userId)); - admin.mAdminCanGrantSensorsPermissions = true; - } - } - } + upgradeSensorPermissionsAccess(allUsers, ownersData, allUsersData); currentVersion = 2; } + if (currentVersion == 2) { + Slog.i(LOG_TAG, String.format("Upgrading from version %d", currentVersion)); + upgradeProtectedPackages(ownersData, allUsersData); + currentVersion = 3; + } + writePoliciesAndVersion(allUsers, allUsersData, ownersData, currentVersion); } + /** + * This upgrade step is for Device Owner scenario only: For devices upgrading to S, if there is + * a device owner, it retains the ability to control sensors-related permission grants. + */ + private void upgradeSensorPermissionsAccess( + int[] allUsers, OwnersData ownersData, SparseArray allUsersData) { + for (int userId : allUsers) { + DevicePolicyData userData = allUsersData.get(userId); + if (userData == null) { + continue; + } + for (ActiveAdmin admin : userData.mAdminList) { + if (ownersData.mDeviceOwnerUserId == userId + && ownersData.mDeviceOwner != null + && ownersData.mDeviceOwner.admin.equals(admin.info.getComponent())) { + Slog.i(LOG_TAG, String.format( + "Marking Device Owner in user %d for permission grant ", userId)); + admin.mAdminCanGrantSensorsPermissions = true; + } + } + } + } + + /** + * This upgrade step moves device owner protected packages to ActiveAdmin. + * Initially these packages were stored in DevicePolicyData, then moved to Owners without + * employing PolicyVersionUpgrader. Here we check both places. + */ + private void upgradeProtectedPackages( + OwnersData ownersData, SparseArray allUsersData) { + if (ownersData.mDeviceOwner == null) { + return; + } + List protectedPackages = null; + DevicePolicyData doUserData = allUsersData.get(ownersData.mDeviceOwnerUserId); + if (doUserData == null) { + Slog.e(LOG_TAG, "No policy data for do user"); + return; + } + if (ownersData.mDeviceOwnerProtectedPackages != null) { + protectedPackages = ownersData.mDeviceOwnerProtectedPackages + .get(ownersData.mDeviceOwner.packageName); + if (protectedPackages != null) { + Slog.i(LOG_TAG, "Found protected packages in Owners"); + } + ownersData.mDeviceOwnerProtectedPackages = null; + } else if (doUserData.mUserControlDisabledPackages != null) { + Slog.i(LOG_TAG, "Found protected packages in DevicePolicyData"); + protectedPackages = doUserData.mUserControlDisabledPackages; + doUserData.mUserControlDisabledPackages = null; + } + + ActiveAdmin doAdmin = doUserData.mAdminMap.get(ownersData.mDeviceOwner.admin); + if (doAdmin == null) { + Slog.e(LOG_TAG, "DO admin not found in DO user"); + return; + } + + if (protectedPackages != null) { + doAdmin.protectedPackages = new ArrayList<>(protectedPackages); + } + } + private OwnersData loadOwners(int[] allUsers) { OwnersData ownersData = new OwnersData(mPathProvider); ownersData.load(allUsers); @@ -146,17 +201,23 @@ public class PolicyVersionUpgrader { OwnersData ownersData) { final SparseArray allUsersData = new SparseArray<>(); for (int user: allUsers) { - ComponentName owner = null; - if (ownersData.mDeviceOwnerUserId == user && ownersData.mDeviceOwner != null) { - owner = ownersData.mDeviceOwner.admin; - } else if (ownersData.mProfileOwners.containsKey(user)) { - owner = ownersData.mProfileOwners.get(user).admin; - } + ComponentName owner = getOwnerForUser(ownersData, user); allUsersData.append(user, loadDataForUser(user, loadVersion, owner)); } return allUsersData; } + @Nullable + private ComponentName getOwnerForUser(OwnersData ownersData, int user) { + ComponentName owner = null; + if (ownersData.mDeviceOwnerUserId == user && ownersData.mDeviceOwner != null) { + owner = ownersData.mDeviceOwner.admin; + } else if (ownersData.mProfileOwners.containsKey(user)) { + owner = ownersData.mProfileOwners.get(user).admin; + } + return owner; + } + private DevicePolicyData loadDataForUser( int userId, int loadVersion, ComponentName ownerComponent) { DevicePolicyData policy = new DevicePolicyData(userId); diff --git a/services/tests/servicestests/assets/PolicyVersionUpgraderTest/protected_packages_device_owner_2.xml b/services/tests/servicestests/assets/PolicyVersionUpgraderTest/protected_packages_device_owner_2.xml new file mode 100644 index 0000000000000..0725d25cdcab3 --- /dev/null +++ b/services/tests/servicestests/assets/PolicyVersionUpgraderTest/protected_packages_device_owner_2.xml @@ -0,0 +1,6 @@ + + + + + + diff --git a/services/tests/servicestests/assets/PolicyVersionUpgraderTest/protected_packages_device_policies.xml b/services/tests/servicestests/assets/PolicyVersionUpgraderTest/protected_packages_device_policies.xml new file mode 100644 index 0000000000000..2d06ee6dca0e8 --- /dev/null +++ b/services/tests/servicestests/assets/PolicyVersionUpgraderTest/protected_packages_device_policies.xml @@ -0,0 +1,13 @@ + + + + + + + + + + + + + diff --git a/services/tests/servicestests/src/com/android/server/devicepolicy/PolicyVersionUpgraderTest.java b/services/tests/servicestests/src/com/android/server/devicepolicy/PolicyVersionUpgraderTest.java index 9efc10cb55ec9..412722d68f436 100644 --- a/services/tests/servicestests/src/com/android/server/devicepolicy/PolicyVersionUpgraderTest.java +++ b/services/tests/servicestests/src/com/android/server/devicepolicy/PolicyVersionUpgraderTest.java @@ -63,8 +63,9 @@ import java.util.function.Function; public class PolicyVersionUpgraderTest extends DpmTestBase { // NOTE: Only change this value if the corresponding CL also adds a test to test the upgrade // to the new version. - private static final int LATEST_TESTED_VERSION = 2; + private static final int LATEST_TESTED_VERSION = 3; public static final String PERMISSIONS_TAG = "admin-can-grant-sensors-permissions"; + public static final String DEVICE_OWNER_XML = "device_owner_2.xml"; private ComponentName mFakeAdmin; private class FakePolicyUpgraderDataProvider implements PolicyUpgraderDataProvider { @@ -119,18 +120,18 @@ public class PolicyVersionUpgraderTest extends DpmTestBase { mUpgrader = new PolicyVersionUpgrader(mProvider, getServices().pathProvider); mFakeAdmin = new ComponentName( "com.android.frameworks.servicestests", - "com.android.server.devicepolicy.DummyDeviceAdmins$Admin1"); + "com.android.server.devicepolicy.DummyDeviceAdmins$Admin1"); ActivityInfo activityInfo = createActivityInfo(mFakeAdmin); DeviceAdminInfo dai = createDeviceAdminInfo(activityInfo); mProvider.mComponentToDeviceAdminInfo.put(mFakeAdmin, dai); - mProvider.mUsers = new int[] {0}; + mProvider.mUsers = new int[]{0}; } @Test public void testSameVersionDoesNothing() throws IOException { writeVersionToXml(DevicePolicyManagerService.DPMS_VERSION); final int userId = mProvider.mUsers[0]; - preparePoliciesFile(userId); + preparePoliciesFile(userId, "device_policies.xml"); String oldContents = readPoliciesFile(userId); mUpgrader.upgradePolicy(DevicePolicyManagerService.DPMS_VERSION); @@ -142,19 +143,19 @@ public class PolicyVersionUpgraderTest extends DpmTestBase { @Test public void testUpgrade0To1RemovesPasswordMetrics() throws IOException, XmlPullParserException { final String activePasswordTag = "active-password"; - mProvider.mUsers = new int[] {0, 10}; + mProvider.mUsers = new int[]{0, 10}; getServices().addUser(10, /* flags= */ 0, USER_TYPE_PROFILE_MANAGED); writeVersionToXml(0); for (int userId : mProvider.mUsers) { - preparePoliciesFile(userId); + preparePoliciesFile(userId, "device_policies.xml"); } // Validate test set-up. assertThat(isTagPresent(readPoliciesFileToStream(0), activePasswordTag)).isTrue(); mUpgrader.upgradePolicy(1); - assertThat(readVersionFromXml()).isGreaterThan(1); - for (int user: mProvider.mUsers) { + assertThat(readVersionFromXml()).isAtLeast(1); + for (int user : mProvider.mUsers) { assertThat(isTagPresent(readPoliciesFileToStream(user), activePasswordTag)).isFalse(); } } @@ -163,17 +164,17 @@ public class PolicyVersionUpgraderTest extends DpmTestBase { public void testUpgrade1To2MarksDoForPermissionControl() throws IOException, XmlPullParserException { final int ownerUser = 10; - mProvider.mUsers = new int[] {0, ownerUser}; + mProvider.mUsers = new int[]{0, ownerUser}; getServices().addUser(ownerUser, FLAG_PRIMARY, USER_TYPE_FULL_SYSTEM); writeVersionToXml(1); for (int userId : mProvider.mUsers) { - preparePoliciesFile(userId); + preparePoliciesFile(userId, "device_policies.xml"); } - prepareDeviceOwnerFile(ownerUser); + prepareDeviceOwnerFile(ownerUser, "device_owner_2.xml"); mUpgrader.upgradePolicy(2); - assertThat(readVersionFromXml()).isEqualTo(2); + assertThat(readVersionFromXml()).isAtLeast(2); assertThat(getBooleanValueTag(readPoliciesFileToStream(mProvider.mUsers[0]), PERMISSIONS_TAG)).isFalse(); assertThat(getBooleanValueTag(readPoliciesFileToStream(ownerUser), @@ -186,8 +187,8 @@ public class PolicyVersionUpgraderTest extends DpmTestBase { getServices().addUser(ownerUser, FLAG_PRIMARY, USER_TYPE_FULL_SYSTEM); setUpPackageManagerForAdmin(admin1, UserHandle.getUid(ownerUser, 123 /* admin app ID */)); writeVersionToXml(0); - preparePoliciesFile(ownerUser); - prepareDeviceOwnerFile(ownerUser); + preparePoliciesFile(ownerUser, "device_policies.xml"); + prepareDeviceOwnerFile(ownerUser, "device_owner_2.xml"); DevicePolicyManagerServiceTestable dpms; final long ident = getContext().binder.clearCallingIdentity(); @@ -202,11 +203,65 @@ public class PolicyVersionUpgraderTest extends DpmTestBase { getContext().binder.restoreCallingIdentity(ident); } + assertThat(readVersionFromXml()).isEqualTo(DevicePolicyManagerService.DPMS_VERSION); + // DO should be marked as able to grant sensors permission during upgrade and should be // reported as such via the API. assertThat(dpms.canAdminGrantSensorsPermissionsForUser(ownerUser)).isTrue(); } + /** + * Up to Android R DO protected packages were stored in DevicePolicyData, verify that they are + * moved to ActiveAdmin. + */ + @Test + public void testUserControlDisabledPackagesFromR() throws Exception { + final String oldTag = "protected-packages"; + final String newTag = "protected_packages"; + final int ownerUser = 0; + mProvider.mUsers = new int[]{0}; + getServices().addUser(ownerUser, FLAG_PRIMARY, USER_TYPE_FULL_SYSTEM); + writeVersionToXml(2); + preparePoliciesFile(ownerUser, "protected_packages_device_policies.xml"); + prepareDeviceOwnerFile(ownerUser, "device_owner_2.xml"); + + // Validate the setup. + assertThat(isTagPresent(readPoliciesFileToStream(ownerUser), oldTag)).isTrue(); + assertThat(isTagPresent(readPoliciesFileToStream(ownerUser), newTag)).isFalse(); + + mUpgrader.upgradePolicy(3); + + assertThat(readVersionFromXml()).isAtLeast(3); + assertThat(isTagPresent(readPoliciesFileToStream(ownerUser), oldTag)).isFalse(); + assertThat(isTagPresent(readPoliciesFileToStream(ownerUser), newTag)).isTrue(); + } + + /** + * In Android S DO protected packages were stored in Owners, verify that they are moved to + * ActiveAdmin. + */ + @Test + public void testUserControlDisabledPackagesFromS() throws Exception { + final String oldTag = "device-owner-protected-packages"; + final String newTag = "protected_packages"; + final int ownerUser = 0; + mProvider.mUsers = new int[]{0}; + getServices().addUser(ownerUser, FLAG_PRIMARY, USER_TYPE_FULL_SYSTEM); + writeVersionToXml(2); + preparePoliciesFile(ownerUser, "device_policies.xml"); + prepareDeviceOwnerFile(ownerUser, "protected_packages_device_owner_2.xml"); + + // Validate the setup. + assertThat(isTagPresent(readDoToStream(), oldTag)).isTrue(); + assertThat(isTagPresent(readPoliciesFileToStream(ownerUser), newTag)).isFalse(); + + mUpgrader.upgradePolicy(3); + + assertThat(readVersionFromXml()).isAtLeast(3); + assertThat(isTagPresent(readDoToStream(), oldTag)).isFalse(); + assertThat(isTagPresent(readPoliciesFileToStream(ownerUser), newTag)).isTrue(); + } + @Test public void isLatestVersionTested() { assertThat(DevicePolicyManagerService.DPMS_VERSION).isEqualTo(LATEST_TESTED_VERSION); @@ -226,32 +281,27 @@ public class PolicyVersionUpgraderTest extends DpmTestBase { return Integer.parseInt(versionString); } - private void preparePoliciesFile(int userId) throws IOException { + private void preparePoliciesFile(int userId, String assetFile) throws IOException { JournaledFile policiesFile = mProvider.makeDevicePoliciesJournaledFile(userId); DpmTestUtils.writeToFile( policiesFile.chooseForWrite(), - DpmTestUtils.readAsset(mRealTestContext, - "PolicyVersionUpgraderTest/device_policies.xml")); + DpmTestUtils.readAsset(mRealTestContext, "PolicyVersionUpgraderTest/" + assetFile)); policiesFile.commit(); } - private void prepareDeviceOwnerFile(int userId) throws IOException { - File parentDir = getServices().pathProvider.getDataSystemDirectory(); - File doFilePath = (new File(parentDir, "device_owner_2.xml")).getAbsoluteFile(); - android.util.Log.i("YYYYYY", "DO paath: " + doFilePath); + private void prepareDeviceOwnerFile(int userId, String assetFile) throws IOException { + File doFilePath = getDoFilePath(); String doFileContent = DpmTestUtils.readAsset(mRealTestContext, - "PolicyVersionUpgraderTest/device_owner_2.xml") + "PolicyVersionUpgraderTest/" + assetFile) // Substitute the right DO userId, XML in resources has 0 .replace("userId=\"0\"", "userId=\"" + userId + "\""); DpmTestUtils.writeToFile(doFilePath, doFileContent); } - private void prepareProfileOwnerFile(int userId) throws IOException { - File parentDir = getServices().pathProvider.getUserSystemDirectory(userId); - DpmTestUtils.writeToFile( - (new File(parentDir, "profile_owner.xml")).getAbsoluteFile(), - DpmTestUtils.readAsset(mRealTestContext, - "PolicyVersionUpgraderTest/profile_owner.xml")); + private File getDoFilePath() { + File parentDir = getServices().pathProvider.getDataSystemDirectory(); + File doFilePath = (new File(parentDir, DEVICE_OWNER_XML)).getAbsoluteFile(); + return doFilePath; } private String readPoliciesFile(int userId) throws IOException { @@ -259,6 +309,10 @@ public class PolicyVersionUpgraderTest extends DpmTestBase { return new String(Files.asByteSource(policiesFile).read(), Charset.defaultCharset()); } + private InputStream readDoToStream() throws IOException { + return new FileInputStream(getDoFilePath()); + } + private InputStream readPoliciesFileToStream(int userId) throws IOException { File policiesFile = mProvider.makeDevicePoliciesJournaledFile(userId).chooseForRead(); return new FileInputStream(policiesFile);