Loading services/devicepolicy/java/com/android/server/devicepolicy/ActiveAdmin.java +11 −0 Original line number Diff line number Diff line Loading @@ -162,6 +162,7 @@ class ActiveAdmin { 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 TAG_SUSPENDED_PACKAGES = "suspended-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"; Loading Loading @@ -257,6 +258,8 @@ class ActiveAdmin { // List of packages for which the user cannot invoke "clear data" or "force stop". List<String> protectedPackages; List<String> suspendedPackages; // Wi-Fi SSID restriction policy. WifiSsidPolicy mWifiSsidPolicy; Loading Loading @@ -508,6 +511,7 @@ class ActiveAdmin { writePackageListToXml(out, TAG_KEEP_UNINSTALLED_PACKAGES, keepUninstalledPackages); writePackageListToXml(out, TAG_METERED_DATA_DISABLED_PACKAGES, meteredDisabledPackages); writePackageListToXml(out, TAG_PROTECTED_PACKAGES, protectedPackages); writePackageListToXml(out, TAG_SUSPENDED_PACKAGES, suspendedPackages); if (hasUserRestrictions()) { UserRestrictionsUtils.writeRestrictions( out, userRestrictions, TAG_USER_RESTRICTIONS); Loading Loading @@ -776,6 +780,8 @@ class ActiveAdmin { meteredDisabledPackages = readPackageList(parser, tag); } else if (TAG_PROTECTED_PACKAGES.equals(tag)) { protectedPackages = readPackageList(parser, tag); } else if (TAG_SUSPENDED_PACKAGES.equals(tag)) { suspendedPackages = readPackageList(parser, tag); } else if (TAG_USER_RESTRICTIONS.equals(tag)) { userRestrictions = UserRestrictionsUtils.readRestrictions(parser); } else if (TAG_DEFAULT_ENABLED_USER_RESTRICTIONS.equals(tag)) { Loading Loading @@ -1225,6 +1231,11 @@ class ActiveAdmin { pw.println(protectedPackages); } if (suspendedPackages != null) { pw.print("suspendedPackages="); pw.println(suspendedPackages); } pw.print("organizationColor="); pw.println(organizationColor); Loading services/devicepolicy/java/com/android/server/devicepolicy/DevicePolicyManagerService.java +44 −3 Original line number Diff line number Diff line Loading @@ -545,7 +545,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 = 3; static final int DPMS_VERSION = 4; static { SECURE_SETTINGS_ALLOWLIST = new ArraySet<>(); Loading Loading @@ -1500,8 +1500,11 @@ public class DevicePolicyManagerService extends BaseIDevicePolicyManager { } PackageManager getPackageManager(int userId) { return mContext .createContextAsUser(UserHandle.of(userId), 0 /* flags */).getPackageManager(); try { return createContextAsUser(UserHandle.of(userId)).getPackageManager(); } catch (NameNotFoundException e) { throw new IllegalStateException(e); } } PowerManagerInternal getPowerManagerInternal() { Loading Loading @@ -3114,6 +3117,20 @@ public class DevicePolicyManagerService extends BaseIDevicePolicyManager { List<UserInfo> allUsers = mUserManager.getUsers(); return allUsers.stream().mapToInt(u -> u.id).toArray(); } @Override public List<String> getPlatformSuspendedPackages(int userId) { PackageManagerInternal pmi = mInjector.getPackageManagerInternal(); return mInjector.getPackageManager(userId) .getInstalledPackages(PackageManager.PackageInfoFlags.of( MATCH_DIRECT_BOOT_AWARE | MATCH_DIRECT_BOOT_UNAWARE)) .stream() .map(packageInfo -> packageInfo.packageName) .filter(pkg -> PLATFORM_PACKAGE_NAME.equals(pmi.getSuspendingPackage(pkg, userId)) ) .collect(Collectors.toList()); } } private void performPolicyVersionUpgrade() { Loading Loading @@ -11386,6 +11403,30 @@ public class DevicePolicyManagerService extends BaseIDevicePolicyManager { Slogf.w(LOG_TAG, "PM failed to suspend packages (%s)", Arrays.toString(packageNames)); return packageNames; } ArraySet<String> changed = new ArraySet<>(packageNames); if (suspended) { // Only save those packages that are actually suspended. If a package is exempt or is // unsuspendable, it is skipped. changed.removeAll(List.of(nonSuspendedPackages)); } else { // If an admin tries to unsuspend a package that is either exempt or is not // suspendable, drop it from the stored list assuming it must be already unsuspended. changed.addAll(exemptApps); } synchronized (getLockObject()) { ActiveAdmin admin = getProfileOwnerOrDeviceOwnerLocked(caller.getUserId()); ArraySet<String> current = new ArraySet<>(admin.suspendedPackages); if (suspended) { current.addAll(changed); } else { current.removeAll(changed); } admin.suspendedPackages = current.isEmpty() ? null : new ArrayList<>(current); saveSettingsLocked(caller.getUserId()); } if (exemptApps.isEmpty()) { return nonSuspendedPackages; } Loading services/devicepolicy/java/com/android/server/devicepolicy/PolicyUpgraderDataProvider.java +6 −0 Original line number Diff line number Diff line Loading @@ -21,6 +21,7 @@ import android.content.ComponentName; import com.android.internal.util.JournaledFile; import java.util.List; import java.util.function.Function; /** Loading Loading @@ -48,4 +49,9 @@ public interface PolicyUpgraderDataProvider { * Returns the users to upgrade. */ int[] getUsersForUpgrade(); /** * Returns packages suspended by platform for a given user. */ List<String> getPlatformSuspendedPackages(int userId); } services/devicepolicy/java/com/android/server/devicepolicy/PolicyVersionUpgrader.java +44 −0 Original line number Diff line number Diff line Loading @@ -104,6 +104,12 @@ public class PolicyVersionUpgrader { currentVersion = 3; } if (currentVersion == 3) { Slog.i(LOG_TAG, String.format("Upgrading from version %d", currentVersion)); upgradePackageSuspension(allUsers, ownersData, allUsersData); currentVersion = 4; } writePoliciesAndVersion(allUsers, allUsersData, ownersData, currentVersion); } Loading Loading @@ -170,6 +176,44 @@ public class PolicyVersionUpgrader { } } /** * This upgrade step stores packages suspended via DPM.setPackagesSuspended() into ActiveAdmin * data structure. Prior to this it was only persisted in PackageManager which doesn't have any * way of knowing which admin suspended it. */ private void upgradePackageSuspension( int[] allUsers, OwnersData ownersData, SparseArray<DevicePolicyData> allUsersData) { if (ownersData.mDeviceOwner != null) { saveSuspendedPackages(allUsersData, ownersData.mDeviceOwnerUserId, ownersData.mDeviceOwner.admin); } for (int i = 0; i < ownersData.mProfileOwners.size(); i++) { int ownerUserId = ownersData.mProfileOwners.keyAt(i); OwnersData.OwnerInfo ownerInfo = ownersData.mProfileOwners.valueAt(i); saveSuspendedPackages(allUsersData, ownerUserId, ownerInfo.admin); } } private void saveSuspendedPackages(SparseArray<DevicePolicyData> allUsersData, int ownerUserId, ComponentName ownerPackage) { DevicePolicyData ownerUserData = allUsersData.get(ownerUserId); if (ownerUserData == null) { Slog.e(LOG_TAG, "No policy data for owner user, cannot migrate suspended packages"); return; } ActiveAdmin ownerAdmin = ownerUserData.mAdminMap.get(ownerPackage); if (ownerAdmin == null) { Slog.e(LOG_TAG, "No admin for owner, cannot migrate suspended packages"); return; } ownerAdmin.suspendedPackages = mProvider.getPlatformSuspendedPackages(ownerUserId); Slog.i(LOG_TAG, String.format("Saved %d packages suspended by %s in user %d", ownerAdmin.suspendedPackages.size(), ownerPackage, ownerUserId)); } private OwnersData loadOwners(int[] allUsers) { OwnersData ownersData = new OwnersData(mPathProvider); ownersData.load(allUsers); Loading services/tests/servicestests/src/com/android/server/devicepolicy/PolicyVersionUpgraderTest.java +81 −1 Original line number Diff line number Diff line Loading @@ -33,6 +33,7 @@ import android.content.pm.ApplicationInfo; import android.os.IpcDataCache; import android.os.Parcel; import android.os.UserHandle; import android.util.ArraySet; import android.util.Xml; import androidx.test.InstrumentationRegistry; Loading @@ -47,29 +48,42 @@ import org.junit.Before; import org.junit.Test; import org.junit.runner.RunWith; import org.junit.runners.JUnit4; import org.w3c.dom.Document; import org.w3c.dom.Element; import org.w3c.dom.NodeList; import org.xmlpull.v1.XmlPullParser; import org.xmlpull.v1.XmlPullParserException; import org.xmlpull.v1.XmlSerializer; import java.io.ByteArrayInputStream; import java.io.ByteArrayOutputStream; import java.io.File; import java.io.FileInputStream; import java.io.IOException; import java.io.InputStream; import java.nio.charset.Charset; import java.nio.charset.StandardCharsets; import java.util.ArrayList; import java.util.HashMap; import java.util.List; import java.util.Map; import java.util.Set; import java.util.function.Function; import javax.xml.parsers.DocumentBuilderFactory; @RunWith(JUnit4.class) 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 = 3; private static final int LATEST_TESTED_VERSION = 4; 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 { Map<ComponentName, DeviceAdminInfo> mComponentToDeviceAdminInfo = new HashMap<>(); ArrayList<String> mPlatformSuspendedPackages = new ArrayList<>(); int[] mUsers; private JournaledFile makeJournaledFile(int userId, String fileName) { Loading Loading @@ -98,6 +112,11 @@ public class PolicyVersionUpgraderTest extends DpmTestBase { public int[] getUsersForUpgrade() { return mUsers; } @Override public List<String> getPlatformSuspendedPackages(int userId) { return mPlatformSuspendedPackages; } } private final Context mRealTestContext = InstrumentationRegistry.getTargetContext(); Loading Loading @@ -256,11 +275,72 @@ public class PolicyVersionUpgraderTest extends DpmTestBase { assertThat(isTagPresent(readPoliciesFileToStream(ownerUser), newTag)).isTrue(); } @Test public void testAdminPackageSuspensionSaved() throws Exception { final int ownerUser = 0; mProvider.mUsers = new int[]{ownerUser}; getServices().addUser(ownerUser, FLAG_PRIMARY, USER_TYPE_FULL_SYSTEM); setUpPackageManagerForAdmin(admin1, UserHandle.getUid(ownerUser, 123 /* admin app ID */)); writeVersionToXml(3); preparePoliciesFile(ownerUser, "device_policies.xml"); prepareDeviceOwnerFile(ownerUser, "device_owner_2.xml"); // Pretend package manager thinks these packages are suspended by the platform. Set<String> suspendedPkgs = Set.of("com.some.app", "foo.bar.baz"); mProvider.mPlatformSuspendedPackages.addAll(suspendedPkgs); mUpgrader.upgradePolicy(4); assertThat(readVersionFromXml()).isAtLeast(4); assertAdminSuspendedPackages(ownerUser, suspendedPkgs); } private void assertAdminSuspendedPackages(int ownerUser, Set<String> suspendedPkgs) throws Exception { Document policies = readPolicies(ownerUser); Element adminElem = (Element) policies.getDocumentElement().getElementsByTagName("admin").item(0); Element suspendedElem = (Element) adminElem.getElementsByTagName("suspended-packages").item(0); NodeList pkgsNodes = suspendedElem.getElementsByTagName("item"); Set<String> storedSuspendedPkgs = new ArraySet<>(); for (int i = 0; i < pkgsNodes.getLength(); i++) { Element item = (Element) pkgsNodes.item(i); storedSuspendedPkgs.add(item.getAttribute("value")); } assertThat(storedSuspendedPkgs).isEqualTo(suspendedPkgs); } @Test public void isLatestVersionTested() { assertThat(DevicePolicyManagerService.DPMS_VERSION).isEqualTo(LATEST_TESTED_VERSION); } /** * Reads ABX binary XML, converts it to text, and returns as an input stream. */ private InputStream abxToXmlStream(File file) throws Exception { FileInputStream fileIn = new FileInputStream(file); XmlPullParser in = Xml.newBinaryPullParser(); in.setInput(fileIn, StandardCharsets.UTF_8.name()); ByteArrayOutputStream byteOut = new ByteArrayOutputStream(); XmlSerializer out = Xml.newSerializer(); out.setOutput(byteOut, StandardCharsets.UTF_8.name()); Xml.copy(in, out); out.flush(); return new ByteArrayInputStream(byteOut.toByteArray()); } private Document readPolicies(int userId) throws Exception { File policiesFile = mProvider.makeDevicePoliciesJournaledFile(userId).chooseForRead(); InputStream is = abxToXmlStream(policiesFile); return DocumentBuilderFactory.newInstance().newDocumentBuilder().parse(is); } private void writeVersionToXml(int dpmsVersion) throws IOException { JournaledFile versionFile = mProvider.makePoliciesVersionJournaledFile(0); Files.asCharSink(versionFile.chooseForWrite(), Charset.defaultCharset()).write( Loading Loading
services/devicepolicy/java/com/android/server/devicepolicy/ActiveAdmin.java +11 −0 Original line number Diff line number Diff line Loading @@ -162,6 +162,7 @@ class ActiveAdmin { 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 TAG_SUSPENDED_PACKAGES = "suspended-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"; Loading Loading @@ -257,6 +258,8 @@ class ActiveAdmin { // List of packages for which the user cannot invoke "clear data" or "force stop". List<String> protectedPackages; List<String> suspendedPackages; // Wi-Fi SSID restriction policy. WifiSsidPolicy mWifiSsidPolicy; Loading Loading @@ -508,6 +511,7 @@ class ActiveAdmin { writePackageListToXml(out, TAG_KEEP_UNINSTALLED_PACKAGES, keepUninstalledPackages); writePackageListToXml(out, TAG_METERED_DATA_DISABLED_PACKAGES, meteredDisabledPackages); writePackageListToXml(out, TAG_PROTECTED_PACKAGES, protectedPackages); writePackageListToXml(out, TAG_SUSPENDED_PACKAGES, suspendedPackages); if (hasUserRestrictions()) { UserRestrictionsUtils.writeRestrictions( out, userRestrictions, TAG_USER_RESTRICTIONS); Loading Loading @@ -776,6 +780,8 @@ class ActiveAdmin { meteredDisabledPackages = readPackageList(parser, tag); } else if (TAG_PROTECTED_PACKAGES.equals(tag)) { protectedPackages = readPackageList(parser, tag); } else if (TAG_SUSPENDED_PACKAGES.equals(tag)) { suspendedPackages = readPackageList(parser, tag); } else if (TAG_USER_RESTRICTIONS.equals(tag)) { userRestrictions = UserRestrictionsUtils.readRestrictions(parser); } else if (TAG_DEFAULT_ENABLED_USER_RESTRICTIONS.equals(tag)) { Loading Loading @@ -1225,6 +1231,11 @@ class ActiveAdmin { pw.println(protectedPackages); } if (suspendedPackages != null) { pw.print("suspendedPackages="); pw.println(suspendedPackages); } pw.print("organizationColor="); pw.println(organizationColor); Loading
services/devicepolicy/java/com/android/server/devicepolicy/DevicePolicyManagerService.java +44 −3 Original line number Diff line number Diff line Loading @@ -545,7 +545,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 = 3; static final int DPMS_VERSION = 4; static { SECURE_SETTINGS_ALLOWLIST = new ArraySet<>(); Loading Loading @@ -1500,8 +1500,11 @@ public class DevicePolicyManagerService extends BaseIDevicePolicyManager { } PackageManager getPackageManager(int userId) { return mContext .createContextAsUser(UserHandle.of(userId), 0 /* flags */).getPackageManager(); try { return createContextAsUser(UserHandle.of(userId)).getPackageManager(); } catch (NameNotFoundException e) { throw new IllegalStateException(e); } } PowerManagerInternal getPowerManagerInternal() { Loading Loading @@ -3114,6 +3117,20 @@ public class DevicePolicyManagerService extends BaseIDevicePolicyManager { List<UserInfo> allUsers = mUserManager.getUsers(); return allUsers.stream().mapToInt(u -> u.id).toArray(); } @Override public List<String> getPlatformSuspendedPackages(int userId) { PackageManagerInternal pmi = mInjector.getPackageManagerInternal(); return mInjector.getPackageManager(userId) .getInstalledPackages(PackageManager.PackageInfoFlags.of( MATCH_DIRECT_BOOT_AWARE | MATCH_DIRECT_BOOT_UNAWARE)) .stream() .map(packageInfo -> packageInfo.packageName) .filter(pkg -> PLATFORM_PACKAGE_NAME.equals(pmi.getSuspendingPackage(pkg, userId)) ) .collect(Collectors.toList()); } } private void performPolicyVersionUpgrade() { Loading Loading @@ -11386,6 +11403,30 @@ public class DevicePolicyManagerService extends BaseIDevicePolicyManager { Slogf.w(LOG_TAG, "PM failed to suspend packages (%s)", Arrays.toString(packageNames)); return packageNames; } ArraySet<String> changed = new ArraySet<>(packageNames); if (suspended) { // Only save those packages that are actually suspended. If a package is exempt or is // unsuspendable, it is skipped. changed.removeAll(List.of(nonSuspendedPackages)); } else { // If an admin tries to unsuspend a package that is either exempt or is not // suspendable, drop it from the stored list assuming it must be already unsuspended. changed.addAll(exemptApps); } synchronized (getLockObject()) { ActiveAdmin admin = getProfileOwnerOrDeviceOwnerLocked(caller.getUserId()); ArraySet<String> current = new ArraySet<>(admin.suspendedPackages); if (suspended) { current.addAll(changed); } else { current.removeAll(changed); } admin.suspendedPackages = current.isEmpty() ? null : new ArrayList<>(current); saveSettingsLocked(caller.getUserId()); } if (exemptApps.isEmpty()) { return nonSuspendedPackages; } Loading
services/devicepolicy/java/com/android/server/devicepolicy/PolicyUpgraderDataProvider.java +6 −0 Original line number Diff line number Diff line Loading @@ -21,6 +21,7 @@ import android.content.ComponentName; import com.android.internal.util.JournaledFile; import java.util.List; import java.util.function.Function; /** Loading Loading @@ -48,4 +49,9 @@ public interface PolicyUpgraderDataProvider { * Returns the users to upgrade. */ int[] getUsersForUpgrade(); /** * Returns packages suspended by platform for a given user. */ List<String> getPlatformSuspendedPackages(int userId); }
services/devicepolicy/java/com/android/server/devicepolicy/PolicyVersionUpgrader.java +44 −0 Original line number Diff line number Diff line Loading @@ -104,6 +104,12 @@ public class PolicyVersionUpgrader { currentVersion = 3; } if (currentVersion == 3) { Slog.i(LOG_TAG, String.format("Upgrading from version %d", currentVersion)); upgradePackageSuspension(allUsers, ownersData, allUsersData); currentVersion = 4; } writePoliciesAndVersion(allUsers, allUsersData, ownersData, currentVersion); } Loading Loading @@ -170,6 +176,44 @@ public class PolicyVersionUpgrader { } } /** * This upgrade step stores packages suspended via DPM.setPackagesSuspended() into ActiveAdmin * data structure. Prior to this it was only persisted in PackageManager which doesn't have any * way of knowing which admin suspended it. */ private void upgradePackageSuspension( int[] allUsers, OwnersData ownersData, SparseArray<DevicePolicyData> allUsersData) { if (ownersData.mDeviceOwner != null) { saveSuspendedPackages(allUsersData, ownersData.mDeviceOwnerUserId, ownersData.mDeviceOwner.admin); } for (int i = 0; i < ownersData.mProfileOwners.size(); i++) { int ownerUserId = ownersData.mProfileOwners.keyAt(i); OwnersData.OwnerInfo ownerInfo = ownersData.mProfileOwners.valueAt(i); saveSuspendedPackages(allUsersData, ownerUserId, ownerInfo.admin); } } private void saveSuspendedPackages(SparseArray<DevicePolicyData> allUsersData, int ownerUserId, ComponentName ownerPackage) { DevicePolicyData ownerUserData = allUsersData.get(ownerUserId); if (ownerUserData == null) { Slog.e(LOG_TAG, "No policy data for owner user, cannot migrate suspended packages"); return; } ActiveAdmin ownerAdmin = ownerUserData.mAdminMap.get(ownerPackage); if (ownerAdmin == null) { Slog.e(LOG_TAG, "No admin for owner, cannot migrate suspended packages"); return; } ownerAdmin.suspendedPackages = mProvider.getPlatformSuspendedPackages(ownerUserId); Slog.i(LOG_TAG, String.format("Saved %d packages suspended by %s in user %d", ownerAdmin.suspendedPackages.size(), ownerPackage, ownerUserId)); } private OwnersData loadOwners(int[] allUsers) { OwnersData ownersData = new OwnersData(mPathProvider); ownersData.load(allUsers); Loading
services/tests/servicestests/src/com/android/server/devicepolicy/PolicyVersionUpgraderTest.java +81 −1 Original line number Diff line number Diff line Loading @@ -33,6 +33,7 @@ import android.content.pm.ApplicationInfo; import android.os.IpcDataCache; import android.os.Parcel; import android.os.UserHandle; import android.util.ArraySet; import android.util.Xml; import androidx.test.InstrumentationRegistry; Loading @@ -47,29 +48,42 @@ import org.junit.Before; import org.junit.Test; import org.junit.runner.RunWith; import org.junit.runners.JUnit4; import org.w3c.dom.Document; import org.w3c.dom.Element; import org.w3c.dom.NodeList; import org.xmlpull.v1.XmlPullParser; import org.xmlpull.v1.XmlPullParserException; import org.xmlpull.v1.XmlSerializer; import java.io.ByteArrayInputStream; import java.io.ByteArrayOutputStream; import java.io.File; import java.io.FileInputStream; import java.io.IOException; import java.io.InputStream; import java.nio.charset.Charset; import java.nio.charset.StandardCharsets; import java.util.ArrayList; import java.util.HashMap; import java.util.List; import java.util.Map; import java.util.Set; import java.util.function.Function; import javax.xml.parsers.DocumentBuilderFactory; @RunWith(JUnit4.class) 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 = 3; private static final int LATEST_TESTED_VERSION = 4; 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 { Map<ComponentName, DeviceAdminInfo> mComponentToDeviceAdminInfo = new HashMap<>(); ArrayList<String> mPlatformSuspendedPackages = new ArrayList<>(); int[] mUsers; private JournaledFile makeJournaledFile(int userId, String fileName) { Loading Loading @@ -98,6 +112,11 @@ public class PolicyVersionUpgraderTest extends DpmTestBase { public int[] getUsersForUpgrade() { return mUsers; } @Override public List<String> getPlatformSuspendedPackages(int userId) { return mPlatformSuspendedPackages; } } private final Context mRealTestContext = InstrumentationRegistry.getTargetContext(); Loading Loading @@ -256,11 +275,72 @@ public class PolicyVersionUpgraderTest extends DpmTestBase { assertThat(isTagPresent(readPoliciesFileToStream(ownerUser), newTag)).isTrue(); } @Test public void testAdminPackageSuspensionSaved() throws Exception { final int ownerUser = 0; mProvider.mUsers = new int[]{ownerUser}; getServices().addUser(ownerUser, FLAG_PRIMARY, USER_TYPE_FULL_SYSTEM); setUpPackageManagerForAdmin(admin1, UserHandle.getUid(ownerUser, 123 /* admin app ID */)); writeVersionToXml(3); preparePoliciesFile(ownerUser, "device_policies.xml"); prepareDeviceOwnerFile(ownerUser, "device_owner_2.xml"); // Pretend package manager thinks these packages are suspended by the platform. Set<String> suspendedPkgs = Set.of("com.some.app", "foo.bar.baz"); mProvider.mPlatformSuspendedPackages.addAll(suspendedPkgs); mUpgrader.upgradePolicy(4); assertThat(readVersionFromXml()).isAtLeast(4); assertAdminSuspendedPackages(ownerUser, suspendedPkgs); } private void assertAdminSuspendedPackages(int ownerUser, Set<String> suspendedPkgs) throws Exception { Document policies = readPolicies(ownerUser); Element adminElem = (Element) policies.getDocumentElement().getElementsByTagName("admin").item(0); Element suspendedElem = (Element) adminElem.getElementsByTagName("suspended-packages").item(0); NodeList pkgsNodes = suspendedElem.getElementsByTagName("item"); Set<String> storedSuspendedPkgs = new ArraySet<>(); for (int i = 0; i < pkgsNodes.getLength(); i++) { Element item = (Element) pkgsNodes.item(i); storedSuspendedPkgs.add(item.getAttribute("value")); } assertThat(storedSuspendedPkgs).isEqualTo(suspendedPkgs); } @Test public void isLatestVersionTested() { assertThat(DevicePolicyManagerService.DPMS_VERSION).isEqualTo(LATEST_TESTED_VERSION); } /** * Reads ABX binary XML, converts it to text, and returns as an input stream. */ private InputStream abxToXmlStream(File file) throws Exception { FileInputStream fileIn = new FileInputStream(file); XmlPullParser in = Xml.newBinaryPullParser(); in.setInput(fileIn, StandardCharsets.UTF_8.name()); ByteArrayOutputStream byteOut = new ByteArrayOutputStream(); XmlSerializer out = Xml.newSerializer(); out.setOutput(byteOut, StandardCharsets.UTF_8.name()); Xml.copy(in, out); out.flush(); return new ByteArrayInputStream(byteOut.toByteArray()); } private Document readPolicies(int userId) throws Exception { File policiesFile = mProvider.makeDevicePoliciesJournaledFile(userId).chooseForRead(); InputStream is = abxToXmlStream(policiesFile); return DocumentBuilderFactory.newInstance().newDocumentBuilder().parse(is); } private void writeVersionToXml(int dpmsVersion) throws IOException { JournaledFile versionFile = mProvider.makePoliciesVersionJournaledFile(0); Files.asCharSink(versionFile.chooseForWrite(), Charset.defaultCharset()).write( Loading