Loading services/supervision/java/com/android/server/supervision/SupervisionService.java +46 −12 Original line number Diff line number Diff line Loading @@ -69,7 +69,6 @@ import android.util.SparseArray; import com.android.internal.R; import com.android.internal.annotations.GuardedBy; import com.android.internal.annotations.VisibleForTesting; import com.android.internal.os.BackgroundThread; import com.android.internal.util.DumpUtils; import com.android.internal.util.FunctionalUtils.RemoteExceptionIgnoringConsumer; import com.android.internal.util.IndentingPrintWriter; Loading Loading @@ -491,11 +490,7 @@ public class SupervisionService extends ISupervisionManager.Stub { List<String> supervisionPackagesPerRole = mInjector.getRoleHoldersAsUser(role, UserHandle.of(userId)); supervisionPackages.addAll(supervisionPackagesPerRole); // TODO(b/432705581): Consider adding a method that takes a list of packages to clear // suspension for, instead of calling for each package in a loop. for (String supervisionPackage : supervisionPackagesPerRole) { clearSuspendedPackagesFor(userId, supervisionPackage, role); } clearSuspendedPackagesFor(userId, supervisionPackagesPerRole, role); } DevicePolicyManagerInternal dpmi = mInjector.getDpmInternal(); Loading @@ -512,13 +507,17 @@ public class SupervisionService extends ISupervisionManager.Stub { } } private void clearSuspendedPackagesFor(int userId, String supervisionPackage, String roleName) { private void clearSuspendedPackagesFor(int userId, List<String> supervisionPackages, @Nullable String role) { PackageManagerInternal pmi = mInjector.getPackageManagerInternal(); for (String supervisionPackage: supervisionPackages) { if (pmi != null) { pmi.unsuspendForSuspendingPackage(supervisionPackage, userId, userId); } mInjector.removeRoleHoldersAsUser(roleName, supervisionPackage, UserHandle.of(userId)); if (RoleManager.ROLE_SUPERVISION.equals(role)) { mInjector.removeRoleHoldersAsUser(role, supervisionPackage, UserHandle.of(userId)); } } } private void maybeApplyUserRestrictions() { Loading Loading @@ -659,6 +658,37 @@ public class SupervisionService extends ISupervisionManager.Stub { return UserHandle.isSameApp(Binder.getCallingUid(), Process.SYSTEM_UID); } private void updateSupervisionRoleHolders(@UserIdInt int userId) { List<String> roleHolders = mInjector.getRoleHoldersAsUser(RoleManager.ROLE_SUPERVISION, UserHandle.of(userId)); synchronized (getLockObject()) { SupervisionUserData data = getUserDataLocked(userId); data.supervisionRoleHolders.clear(); data.supervisionRoleHolders.addAll(roleHolders); if (Flags.persistentSupervisionSettings()) { mSupervisionSettings.saveUserData(); } } } private List<String> getRemovedSupervisionRoleHolders(@UserIdInt int userId) { List<String> newRoleHolders = mInjector.getRoleHoldersAsUser(RoleManager.ROLE_SUPERVISION, UserHandle.of(userId)); synchronized (getLockObject()) { SupervisionUserData data = getUserDataLocked(userId); List<String> removedRoleHolders = new ArrayList<>(data.supervisionRoleHolders); removedRoleHolders.removeAll(newRoleHolders); data.supervisionRoleHolders.clear(); data.supervisionRoleHolders.addAll(newRoleHolders); if (Flags.persistentSupervisionSettings()) { mSupervisionSettings.saveUserData(); } return removedRoleHolders; } } /** Provides local services in a lazy manner. */ static class Injector { public Context context; Loading Loading @@ -799,6 +829,7 @@ public class SupervisionService extends ISupervisionManager.Stub { @Override public void onUserStarting(@NonNull TargetUser user) { mSupervisionService.updateSupervisionRoleHolders(user.getUserIdentifier()); if (Flags.enableSyncWithDpm() && !user.isPreCreated()) { mSupervisionService.syncStateWithDevicePolicyManager(user.getUserIdentifier()); } Loading Loading @@ -869,13 +900,16 @@ public class SupervisionService extends ISupervisionManager.Stub { void register() { mInjector.addOnRoleHoldersChangedListenerAsUser( BackgroundThread.getExecutor(), this, UserHandle.ALL); mServiceThread.getThreadExecutor(), this, UserHandle.ALL); } @Override public void onRoleHoldersChanged(@NonNull String roleName, @NonNull UserHandle user) { if (RoleManager.ROLE_SUPERVISION.equals(roleName)) { maybeApplyUserRestrictionsFor(user); List<String> removedRoleHolders = getRemovedSupervisionRoleHolders(user.getIdentifier()); clearSuspendedPackagesFor(user.getIdentifier(), removedRoleHolders, null); } } } Loading services/supervision/java/com/android/server/supervision/SupervisionSettings.java +21 −0 Original line number Diff line number Diff line Loading @@ -21,6 +21,7 @@ import android.annotation.UserIdInt; import android.app.supervision.SupervisionRecoveryInfo; import android.os.Environment; import android.os.PersistableBundle; import android.util.ArraySet; import android.util.AtomicFile; import android.util.Slog; import android.util.SparseArray; Loading Loading @@ -62,6 +63,8 @@ public class SupervisionSettings { private static final String KEY_USER_ID = "user_id"; private static final String KEY_ENABLED = "supervision_enabled"; private static final String KEY_APP_PACKAGE = "supervision_app_package"; private static final String KEY_ROLE_HOLDERS_LIST = "supervision_role_holders_list"; private static final String KEY_ROLE_HOLDER = "supervision_role_holder"; private static final String KEY_LOCK_SCREEN_ENABLED = "supervision_lockscreen_enabled"; private static final String KEY_LOCK_SCREEN_OPTIONS = "supervision_lockscreen_options"; Loading Loading @@ -138,6 +141,7 @@ public class SupervisionSettings { if (parser.getName().equals(PREF_USER_DATA)) { int userId = parser.getAttributeInt(null, KEY_USER_ID); SupervisionUserData data = getUserData(userId); data.supervisionRoleHolders = new ArraySet<>(); data.supervisionEnabled = parser.getAttributeBoolean(null, KEY_ENABLED); data.supervisionAppPackage = parser.getAttributeValue(null, KEY_APP_PACKAGE); if (data.supervisionAppPackage.isEmpty()) { Loading @@ -149,6 +153,14 @@ public class SupervisionSettings { if (parser.getName().equals(KEY_LOCK_SCREEN_OPTIONS)) { data.supervisionLockScreenOptions = PersistableBundle.restoreFromXml(parser); } else if (parser.getName().equals(KEY_ROLE_HOLDERS_LIST)) { final int roleHoldersDepth = parser.getDepth(); while (XmlUtils.nextElementWithin(parser, roleHoldersDepth)) { if (parser.getName().equals(KEY_ROLE_HOLDER)) { String roleHolder = parser.getAttributeValue(null, "package"); data.supervisionRoleHolders.add(roleHolder); } } } } } Loading Loading @@ -179,6 +191,15 @@ public class SupervisionSettings { data.supervisionAppPackage == null ? "" : data.supervisionAppPackage); xml.attributeBoolean( null, KEY_LOCK_SCREEN_ENABLED, data.supervisionLockScreenEnabled); if (data.supervisionRoleHolders != null && !data.supervisionRoleHolders.isEmpty()) { xml.startTag(null, KEY_ROLE_HOLDERS_LIST); for (String roleHolder : data.supervisionRoleHolders) { xml.startTag(null, KEY_ROLE_HOLDER); xml.attribute(null, "package", roleHolder); xml.endTag(null, KEY_ROLE_HOLDER); } xml.endTag(null, KEY_ROLE_HOLDERS_LIST); } if (data.supervisionLockScreenOptions != null) { xml.startTag(null, KEY_LOCK_SCREEN_OPTIONS); data.supervisionLockScreenOptions.saveToXml(xml); Loading services/supervision/java/com/android/server/supervision/SupervisionUserData.java +3 −0 Original line number Diff line number Diff line Loading @@ -20,6 +20,7 @@ import android.annotation.NonNull; import android.annotation.Nullable; import android.annotation.UserIdInt; import android.os.PersistableBundle; import android.util.ArraySet; import android.util.IndentingPrintWriter; /** User specific data, used internally by the {@link SupervisionService}. */ Loading @@ -29,6 +30,7 @@ public class SupervisionUserData { @Nullable public String supervisionAppPackage; public boolean supervisionLockScreenEnabled; @Nullable public PersistableBundle supervisionLockScreenOptions; ArraySet<String> supervisionRoleHolders = new ArraySet<>(); public SupervisionUserData(@UserIdInt int userId) { this.userId = userId; Loading @@ -40,6 +42,7 @@ public class SupervisionUserData { pw.increaseIndent(); pw.println("supervisionEnabled: " + supervisionEnabled); pw.println("supervisionAppPackage: " + supervisionAppPackage); pw.println("supervisionRoleHolders: " + supervisionRoleHolders); pw.println("supervisionLockScreenEnabled: " + supervisionLockScreenEnabled); pw.println("supervisionLockScreenOptions: " + supervisionLockScreenOptions); pw.decreaseIndent(); Loading services/tests/servicestests/src/com/android/server/supervision/SupervisionServiceTest.kt +24 −3 Original line number Diff line number Diff line Loading @@ -383,8 +383,9 @@ class SupervisionServiceTest { UserHandle.of(USER_ID), listOf("com.example.supervisionapp1"), ) setSupervisionRecoveryInfo(state = STATE_VERIFIED) clearInvocations(mockDpmInternal) setSupervisionEnabledForUser(USER_ID, true) setSupervisionRecoveryInfo(state = STATE_VERIFIED) assertThat(service.isSupervisionEnabledForUser(USER_ID)).isTrue() verify(mockDpmInternal) Loading Loading @@ -562,12 +563,13 @@ class SupervisionServiceTest { @RequiresFlagsEnabled(Flags.FLAG_PERSISTENT_SUPERVISION_SETTINGS) fun setSupervisionRecoveryInfo_supervisionEnabled_hasSupervisionRoleHolders_doesNotRestrictFactoryReset() { addDefaultAndTestUsers() setSupervisionEnabledForUser(USER_ID, true) injector.setRoleHoldersAsUser( RoleManager.ROLE_SUPERVISION, UserHandle.of(USER_ID), listOf("com.example.supervisionapp1"), ) clearInvocations(mockDpmInternal) setSupervisionEnabledForUser(USER_ID, true) setSupervisionRecoveryInfo(state = STATE_VERIFIED) // Once for the initial setSupervisionEnabledForUser, and again for the Loading Loading @@ -636,6 +638,21 @@ class SupervisionServiceTest { } } @Test @RequiresFlagsEnabled(Flags.FLAG_ENABLE_REMOVE_POLICIES_ON_SUPERVISION_DISABLE) fun onRoleHoldersChanged_removesPackageSuspensionForRemovedRoleHolder() { val packageName = "com.example.supervisionapp" val roleName = RoleManager.ROLE_SUPERVISION injector.setRoleHoldersAsUser(roleName, UserHandle.of(USER_ID), listOf(packageName, "com.example.supervisionapp2", "com.example.supervisionapp3")) injector.setRoleHoldersAsUser(roleName, UserHandle.of(USER_ID), emptyList()) injector.awaitServiceThreadIdle() verify(mockPackageManagerInternal) .unsuspendForSuspendingPackage(eq(packageName), eq(USER_ID), eq(USER_ID)) } private fun registerSupervisionListenerForUser( userId: Int ): Pair<ISupervisionListener, IBinder> { Loading Loading @@ -814,12 +831,15 @@ typealias SupervisionListenerMap = Map<Int, Pair<ISupervisionListener, IBinder>> private class TestInjector(val context: Context, private val serviceThread: ServiceThread) : SupervisionService.Injector(context) { private val roleHolders = mutableMapOf<Pair<String, UserHandle>, List<String>>() private var roleHoldersChangedListener: OnRoleHoldersChangedListener? = null override fun addOnRoleHoldersChangedListenerAsUser( executor: Executor, listener: OnRoleHoldersChangedListener, user: UserHandle, ) {} ) { this.roleHoldersChangedListener = listener } override fun getRoleHoldersAsUser(roleName: String, user: UserHandle): List<String> { return roleHolders[Pair(roleName, user)] ?: emptyList() Loading @@ -827,6 +847,7 @@ private class TestInjector(val context: Context, private val serviceThread: Serv fun setRoleHoldersAsUser(roleName: String, user: UserHandle, packages: List<String>) { roleHolders[Pair(roleName, user)] = packages roleHoldersChangedListener?.onRoleHoldersChanged(roleName, user) } override fun getServiceThread(): ServiceThread { Loading services/tests/servicestests/src/com/android/server/supervision/SupervisionSettingsTest.kt +23 −0 Original line number Diff line number Diff line Loading @@ -21,6 +21,7 @@ import android.app.supervision.flags.Flags import android.os.PersistableBundle import android.platform.test.annotations.RequiresFlagsEnabled import android.platform.test.flag.junit.DeviceFlagsValueProvider import android.util.ArraySet import androidx.test.ext.junit.runners.AndroidJUnit4 import com.google.common.truth.Truth.assertThat import java.nio.file.Files Loading Loading @@ -144,6 +145,24 @@ class SupervisionSettingsTest { mSupervisionSettings.getUserData(1).checkUserData(true, "package1", true, null) } @Test fun saveAndLoadSupervisionUserData_hasSupervisionRoleHolders_retrievesUserDataCorrectly() { // Get and set user data val userData1 = mSupervisionSettings.getUserData(1) val roleHolders = ArraySet<String>(setOf("package2", "package3", "package4")) userData1.changeUserData(true, "package1", true, null, roleHolders) // Save, change and load user data mSupervisionSettings.saveUserData() userData1.changeUserData(false, null, false, BUNDLE_2) mSupervisionSettings.loadUserData() // Check if user data was loaded correctly mSupervisionSettings.getUserData(1).checkUserData(true, "package1", true, null, roleHolders) } @Test fun saveAndLoadSupervisionUserData_manyUsers_retrievesUserDataCorrectly() { // Get and set user data Loading Loading @@ -218,11 +237,13 @@ class SupervisionSettingsTest { appPackage: String?, lockScreenEnabled: Boolean, lockScreenOptions: PersistableBundle?, roleHolders: ArraySet<String> = ArraySet<String>(), ) { this.supervisionEnabled = enabled this.supervisionAppPackage = appPackage this.supervisionLockScreenEnabled = lockScreenEnabled this.supervisionLockScreenOptions = lockScreenOptions this.supervisionRoleHolders = roleHolders } fun SupervisionUserData.checkUserData( Loading @@ -230,6 +251,7 @@ class SupervisionSettingsTest { appPackage: String?, lockScreenEnabled: Boolean, lockScreenOptions: PersistableBundle?, roleHolders: ArraySet<String> = ArraySet<String>(), ) { assertThat(this.supervisionEnabled).isEqualTo(enabled) assertThat(this.supervisionAppPackage).isEqualTo(appPackage) Loading @@ -240,6 +262,7 @@ class SupervisionSettingsTest { assertThat(this.supervisionLockScreenOptions.toString()) .isEqualTo(lockScreenOptions.toString()) } assertThat(this.supervisionRoleHolders).containsExactlyElementsIn(roleHolders) } } } Loading
services/supervision/java/com/android/server/supervision/SupervisionService.java +46 −12 Original line number Diff line number Diff line Loading @@ -69,7 +69,6 @@ import android.util.SparseArray; import com.android.internal.R; import com.android.internal.annotations.GuardedBy; import com.android.internal.annotations.VisibleForTesting; import com.android.internal.os.BackgroundThread; import com.android.internal.util.DumpUtils; import com.android.internal.util.FunctionalUtils.RemoteExceptionIgnoringConsumer; import com.android.internal.util.IndentingPrintWriter; Loading Loading @@ -491,11 +490,7 @@ public class SupervisionService extends ISupervisionManager.Stub { List<String> supervisionPackagesPerRole = mInjector.getRoleHoldersAsUser(role, UserHandle.of(userId)); supervisionPackages.addAll(supervisionPackagesPerRole); // TODO(b/432705581): Consider adding a method that takes a list of packages to clear // suspension for, instead of calling for each package in a loop. for (String supervisionPackage : supervisionPackagesPerRole) { clearSuspendedPackagesFor(userId, supervisionPackage, role); } clearSuspendedPackagesFor(userId, supervisionPackagesPerRole, role); } DevicePolicyManagerInternal dpmi = mInjector.getDpmInternal(); Loading @@ -512,13 +507,17 @@ public class SupervisionService extends ISupervisionManager.Stub { } } private void clearSuspendedPackagesFor(int userId, String supervisionPackage, String roleName) { private void clearSuspendedPackagesFor(int userId, List<String> supervisionPackages, @Nullable String role) { PackageManagerInternal pmi = mInjector.getPackageManagerInternal(); for (String supervisionPackage: supervisionPackages) { if (pmi != null) { pmi.unsuspendForSuspendingPackage(supervisionPackage, userId, userId); } mInjector.removeRoleHoldersAsUser(roleName, supervisionPackage, UserHandle.of(userId)); if (RoleManager.ROLE_SUPERVISION.equals(role)) { mInjector.removeRoleHoldersAsUser(role, supervisionPackage, UserHandle.of(userId)); } } } private void maybeApplyUserRestrictions() { Loading Loading @@ -659,6 +658,37 @@ public class SupervisionService extends ISupervisionManager.Stub { return UserHandle.isSameApp(Binder.getCallingUid(), Process.SYSTEM_UID); } private void updateSupervisionRoleHolders(@UserIdInt int userId) { List<String> roleHolders = mInjector.getRoleHoldersAsUser(RoleManager.ROLE_SUPERVISION, UserHandle.of(userId)); synchronized (getLockObject()) { SupervisionUserData data = getUserDataLocked(userId); data.supervisionRoleHolders.clear(); data.supervisionRoleHolders.addAll(roleHolders); if (Flags.persistentSupervisionSettings()) { mSupervisionSettings.saveUserData(); } } } private List<String> getRemovedSupervisionRoleHolders(@UserIdInt int userId) { List<String> newRoleHolders = mInjector.getRoleHoldersAsUser(RoleManager.ROLE_SUPERVISION, UserHandle.of(userId)); synchronized (getLockObject()) { SupervisionUserData data = getUserDataLocked(userId); List<String> removedRoleHolders = new ArrayList<>(data.supervisionRoleHolders); removedRoleHolders.removeAll(newRoleHolders); data.supervisionRoleHolders.clear(); data.supervisionRoleHolders.addAll(newRoleHolders); if (Flags.persistentSupervisionSettings()) { mSupervisionSettings.saveUserData(); } return removedRoleHolders; } } /** Provides local services in a lazy manner. */ static class Injector { public Context context; Loading Loading @@ -799,6 +829,7 @@ public class SupervisionService extends ISupervisionManager.Stub { @Override public void onUserStarting(@NonNull TargetUser user) { mSupervisionService.updateSupervisionRoleHolders(user.getUserIdentifier()); if (Flags.enableSyncWithDpm() && !user.isPreCreated()) { mSupervisionService.syncStateWithDevicePolicyManager(user.getUserIdentifier()); } Loading Loading @@ -869,13 +900,16 @@ public class SupervisionService extends ISupervisionManager.Stub { void register() { mInjector.addOnRoleHoldersChangedListenerAsUser( BackgroundThread.getExecutor(), this, UserHandle.ALL); mServiceThread.getThreadExecutor(), this, UserHandle.ALL); } @Override public void onRoleHoldersChanged(@NonNull String roleName, @NonNull UserHandle user) { if (RoleManager.ROLE_SUPERVISION.equals(roleName)) { maybeApplyUserRestrictionsFor(user); List<String> removedRoleHolders = getRemovedSupervisionRoleHolders(user.getIdentifier()); clearSuspendedPackagesFor(user.getIdentifier(), removedRoleHolders, null); } } } Loading
services/supervision/java/com/android/server/supervision/SupervisionSettings.java +21 −0 Original line number Diff line number Diff line Loading @@ -21,6 +21,7 @@ import android.annotation.UserIdInt; import android.app.supervision.SupervisionRecoveryInfo; import android.os.Environment; import android.os.PersistableBundle; import android.util.ArraySet; import android.util.AtomicFile; import android.util.Slog; import android.util.SparseArray; Loading Loading @@ -62,6 +63,8 @@ public class SupervisionSettings { private static final String KEY_USER_ID = "user_id"; private static final String KEY_ENABLED = "supervision_enabled"; private static final String KEY_APP_PACKAGE = "supervision_app_package"; private static final String KEY_ROLE_HOLDERS_LIST = "supervision_role_holders_list"; private static final String KEY_ROLE_HOLDER = "supervision_role_holder"; private static final String KEY_LOCK_SCREEN_ENABLED = "supervision_lockscreen_enabled"; private static final String KEY_LOCK_SCREEN_OPTIONS = "supervision_lockscreen_options"; Loading Loading @@ -138,6 +141,7 @@ public class SupervisionSettings { if (parser.getName().equals(PREF_USER_DATA)) { int userId = parser.getAttributeInt(null, KEY_USER_ID); SupervisionUserData data = getUserData(userId); data.supervisionRoleHolders = new ArraySet<>(); data.supervisionEnabled = parser.getAttributeBoolean(null, KEY_ENABLED); data.supervisionAppPackage = parser.getAttributeValue(null, KEY_APP_PACKAGE); if (data.supervisionAppPackage.isEmpty()) { Loading @@ -149,6 +153,14 @@ public class SupervisionSettings { if (parser.getName().equals(KEY_LOCK_SCREEN_OPTIONS)) { data.supervisionLockScreenOptions = PersistableBundle.restoreFromXml(parser); } else if (parser.getName().equals(KEY_ROLE_HOLDERS_LIST)) { final int roleHoldersDepth = parser.getDepth(); while (XmlUtils.nextElementWithin(parser, roleHoldersDepth)) { if (parser.getName().equals(KEY_ROLE_HOLDER)) { String roleHolder = parser.getAttributeValue(null, "package"); data.supervisionRoleHolders.add(roleHolder); } } } } } Loading Loading @@ -179,6 +191,15 @@ public class SupervisionSettings { data.supervisionAppPackage == null ? "" : data.supervisionAppPackage); xml.attributeBoolean( null, KEY_LOCK_SCREEN_ENABLED, data.supervisionLockScreenEnabled); if (data.supervisionRoleHolders != null && !data.supervisionRoleHolders.isEmpty()) { xml.startTag(null, KEY_ROLE_HOLDERS_LIST); for (String roleHolder : data.supervisionRoleHolders) { xml.startTag(null, KEY_ROLE_HOLDER); xml.attribute(null, "package", roleHolder); xml.endTag(null, KEY_ROLE_HOLDER); } xml.endTag(null, KEY_ROLE_HOLDERS_LIST); } if (data.supervisionLockScreenOptions != null) { xml.startTag(null, KEY_LOCK_SCREEN_OPTIONS); data.supervisionLockScreenOptions.saveToXml(xml); Loading
services/supervision/java/com/android/server/supervision/SupervisionUserData.java +3 −0 Original line number Diff line number Diff line Loading @@ -20,6 +20,7 @@ import android.annotation.NonNull; import android.annotation.Nullable; import android.annotation.UserIdInt; import android.os.PersistableBundle; import android.util.ArraySet; import android.util.IndentingPrintWriter; /** User specific data, used internally by the {@link SupervisionService}. */ Loading @@ -29,6 +30,7 @@ public class SupervisionUserData { @Nullable public String supervisionAppPackage; public boolean supervisionLockScreenEnabled; @Nullable public PersistableBundle supervisionLockScreenOptions; ArraySet<String> supervisionRoleHolders = new ArraySet<>(); public SupervisionUserData(@UserIdInt int userId) { this.userId = userId; Loading @@ -40,6 +42,7 @@ public class SupervisionUserData { pw.increaseIndent(); pw.println("supervisionEnabled: " + supervisionEnabled); pw.println("supervisionAppPackage: " + supervisionAppPackage); pw.println("supervisionRoleHolders: " + supervisionRoleHolders); pw.println("supervisionLockScreenEnabled: " + supervisionLockScreenEnabled); pw.println("supervisionLockScreenOptions: " + supervisionLockScreenOptions); pw.decreaseIndent(); Loading
services/tests/servicestests/src/com/android/server/supervision/SupervisionServiceTest.kt +24 −3 Original line number Diff line number Diff line Loading @@ -383,8 +383,9 @@ class SupervisionServiceTest { UserHandle.of(USER_ID), listOf("com.example.supervisionapp1"), ) setSupervisionRecoveryInfo(state = STATE_VERIFIED) clearInvocations(mockDpmInternal) setSupervisionEnabledForUser(USER_ID, true) setSupervisionRecoveryInfo(state = STATE_VERIFIED) assertThat(service.isSupervisionEnabledForUser(USER_ID)).isTrue() verify(mockDpmInternal) Loading Loading @@ -562,12 +563,13 @@ class SupervisionServiceTest { @RequiresFlagsEnabled(Flags.FLAG_PERSISTENT_SUPERVISION_SETTINGS) fun setSupervisionRecoveryInfo_supervisionEnabled_hasSupervisionRoleHolders_doesNotRestrictFactoryReset() { addDefaultAndTestUsers() setSupervisionEnabledForUser(USER_ID, true) injector.setRoleHoldersAsUser( RoleManager.ROLE_SUPERVISION, UserHandle.of(USER_ID), listOf("com.example.supervisionapp1"), ) clearInvocations(mockDpmInternal) setSupervisionEnabledForUser(USER_ID, true) setSupervisionRecoveryInfo(state = STATE_VERIFIED) // Once for the initial setSupervisionEnabledForUser, and again for the Loading Loading @@ -636,6 +638,21 @@ class SupervisionServiceTest { } } @Test @RequiresFlagsEnabled(Flags.FLAG_ENABLE_REMOVE_POLICIES_ON_SUPERVISION_DISABLE) fun onRoleHoldersChanged_removesPackageSuspensionForRemovedRoleHolder() { val packageName = "com.example.supervisionapp" val roleName = RoleManager.ROLE_SUPERVISION injector.setRoleHoldersAsUser(roleName, UserHandle.of(USER_ID), listOf(packageName, "com.example.supervisionapp2", "com.example.supervisionapp3")) injector.setRoleHoldersAsUser(roleName, UserHandle.of(USER_ID), emptyList()) injector.awaitServiceThreadIdle() verify(mockPackageManagerInternal) .unsuspendForSuspendingPackage(eq(packageName), eq(USER_ID), eq(USER_ID)) } private fun registerSupervisionListenerForUser( userId: Int ): Pair<ISupervisionListener, IBinder> { Loading Loading @@ -814,12 +831,15 @@ typealias SupervisionListenerMap = Map<Int, Pair<ISupervisionListener, IBinder>> private class TestInjector(val context: Context, private val serviceThread: ServiceThread) : SupervisionService.Injector(context) { private val roleHolders = mutableMapOf<Pair<String, UserHandle>, List<String>>() private var roleHoldersChangedListener: OnRoleHoldersChangedListener? = null override fun addOnRoleHoldersChangedListenerAsUser( executor: Executor, listener: OnRoleHoldersChangedListener, user: UserHandle, ) {} ) { this.roleHoldersChangedListener = listener } override fun getRoleHoldersAsUser(roleName: String, user: UserHandle): List<String> { return roleHolders[Pair(roleName, user)] ?: emptyList() Loading @@ -827,6 +847,7 @@ private class TestInjector(val context: Context, private val serviceThread: Serv fun setRoleHoldersAsUser(roleName: String, user: UserHandle, packages: List<String>) { roleHolders[Pair(roleName, user)] = packages roleHoldersChangedListener?.onRoleHoldersChanged(roleName, user) } override fun getServiceThread(): ServiceThread { Loading
services/tests/servicestests/src/com/android/server/supervision/SupervisionSettingsTest.kt +23 −0 Original line number Diff line number Diff line Loading @@ -21,6 +21,7 @@ import android.app.supervision.flags.Flags import android.os.PersistableBundle import android.platform.test.annotations.RequiresFlagsEnabled import android.platform.test.flag.junit.DeviceFlagsValueProvider import android.util.ArraySet import androidx.test.ext.junit.runners.AndroidJUnit4 import com.google.common.truth.Truth.assertThat import java.nio.file.Files Loading Loading @@ -144,6 +145,24 @@ class SupervisionSettingsTest { mSupervisionSettings.getUserData(1).checkUserData(true, "package1", true, null) } @Test fun saveAndLoadSupervisionUserData_hasSupervisionRoleHolders_retrievesUserDataCorrectly() { // Get and set user data val userData1 = mSupervisionSettings.getUserData(1) val roleHolders = ArraySet<String>(setOf("package2", "package3", "package4")) userData1.changeUserData(true, "package1", true, null, roleHolders) // Save, change and load user data mSupervisionSettings.saveUserData() userData1.changeUserData(false, null, false, BUNDLE_2) mSupervisionSettings.loadUserData() // Check if user data was loaded correctly mSupervisionSettings.getUserData(1).checkUserData(true, "package1", true, null, roleHolders) } @Test fun saveAndLoadSupervisionUserData_manyUsers_retrievesUserDataCorrectly() { // Get and set user data Loading Loading @@ -218,11 +237,13 @@ class SupervisionSettingsTest { appPackage: String?, lockScreenEnabled: Boolean, lockScreenOptions: PersistableBundle?, roleHolders: ArraySet<String> = ArraySet<String>(), ) { this.supervisionEnabled = enabled this.supervisionAppPackage = appPackage this.supervisionLockScreenEnabled = lockScreenEnabled this.supervisionLockScreenOptions = lockScreenOptions this.supervisionRoleHolders = roleHolders } fun SupervisionUserData.checkUserData( Loading @@ -230,6 +251,7 @@ class SupervisionSettingsTest { appPackage: String?, lockScreenEnabled: Boolean, lockScreenOptions: PersistableBundle?, roleHolders: ArraySet<String> = ArraySet<String>(), ) { assertThat(this.supervisionEnabled).isEqualTo(enabled) assertThat(this.supervisionAppPackage).isEqualTo(appPackage) Loading @@ -240,6 +262,7 @@ class SupervisionSettingsTest { assertThat(this.supervisionLockScreenOptions.toString()) .isEqualTo(lockScreenOptions.toString()) } assertThat(this.supervisionRoleHolders).containsExactlyElementsIn(roleHolders) } } }