Move DO protected packages to ActiveAdmin

This is needed to allow POs to use this policy.

After this change PackageManagerInternal isn't updated when
transferring ownership, and thus retains the old DPC package
in its map. This will be addressed in the next CL on the
package manager side: owner package -> protected packages map
will be replaced with one keyed by userId, so such update won't
be necessary.

Bug: 218639412
Test: atest com.android.server.devicepolicy
Test: atest UserControlDisabledPackagesTest
Test: atest DeviceOwnerTest#testSetUserControlDisabledPackages_singleUser_reboot_verifyPackageNotStopped
Change-Id: I19c568461fdb4b341c9e3d4e7e101c859af176b6
This commit is contained in:
Pavel Grafov
2022-05-03 19:24:26 +01:00
parent 3c2330d3a9
commit ca761783a6
9 changed files with 262 additions and 175 deletions

View File

@@ -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<String> keepUninstalledPackages;
// List of packages for which the user cannot invoke "clear data" or "force stop".
List<String> 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);

View File

@@ -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<String> mLockTaskPackages = new ArrayList<>();
// List of packages protected by device owner
List<String> mUserControlDisabledPackages = new ArrayList<>();
/** @deprecated moved to {@link ActiveAdmin#protectedPackages}. */
@Deprecated
@Nullable
List<String> 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);

View File

@@ -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 <b>existing</b> 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();
}
}

View File

@@ -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<String, List<String>> 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<String> 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<String> 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<String> 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<String> getDeviceOwnerProtectedPackages(String packageName) {
synchronized (mData) {
return mData.mDeviceOwnerProtectedPackages.containsKey(packageName)
? mData.mDeviceOwnerProtectedPackages.get(packageName)
: Collections.emptyList();
}
}
void writeDeviceOwner() {
synchronized (mData) {
pushToDevicePolicyManager();

View File

@@ -91,8 +91,10 @@ class OwnersData {
// Device owner type for a managed device.
final ArrayMap<String, Integer> mDeviceOwnerTypes = new ArrayMap<>();
final ArrayMap<String, List<String>> mDeviceOwnerProtectedPackages = new ArrayMap<>();
/** @deprecated moved to {@link ActiveAdmin#protectedPackages}. */
@Deprecated
@Nullable
ArrayMap<String, List<String>> mDeviceOwnerProtectedPackages;
// Internal state for the profile owner packages.
final ArrayMap<Integer, OwnerInfo> mProfileOwners = new ArrayMap<>();
@@ -366,21 +368,6 @@ class OwnersData {
}
}
if (!mDeviceOwnerProtectedPackages.isEmpty()) {
for (ArrayMap.Entry<String, List<String>> entry :
mDeviceOwnerProtectedPackages.entrySet()) {
List<String> 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:

View File

@@ -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<DevicePolicyData> 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<DevicePolicyData> allUsersData) {
if (ownersData.mDeviceOwner == null) {
return;
}
List<String> 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<DevicePolicyData> 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);

View File

@@ -0,0 +1,6 @@
<?xml version='1.0' encoding='UTF-8' standalone='yes' ?>
<root>
<device-owner package="com.android.frameworks.servicestests" name="" component="com.android.frameworks.servicestests/com.android.server.devicepolicy.DummyDeviceAdmins$Admin1" userRestrictionsMigrated="true" isPoOrganizationOwnedDevice="true" />
<device-owner-context userId="0" />
<device-owner-protected-packages package="com.android.frameworks.servicestests" size="2" name0="com.some.app" name1="foo.bar.baz" />
</root>

View File

@@ -0,0 +1,13 @@
<?xml version='1.0' encoding='utf-8' standalone='yes' ?>
<policies setup-complete="true" provisioning-state="3">
<admin name="com.android.frameworks.servicestests/com.android.server.devicepolicy.DummyDeviceAdmins$Admin1">
<policies flags="991" />
<strong-auth-unlock-timeout value="0" />
<test-only-admin value="true" />
<cross-profile-calendar-packages />
<cross-profile-packages />
</admin>
<lock-task-features value="16" />
<protected-packages name="com.some.app" />
<protected-packages name="foo.bar.baz" />
</policies>

View File

@@ -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);