diff options
author | 2025-01-28 04:09:49 -0800 | |
---|---|---|
committer | 2025-01-28 04:09:49 -0800 | |
commit | f1d8fbadda2fbf86765bd65c36880df09d4d7bae (patch) | |
tree | 1153bda6aeeb47f6a8b9cfb31251d634784f3a0e | |
parent | 90bad16d9a9da0902bcf67d048e53f30be84bd15 (diff) |
Introduce a hidden API in SupervisionManager to set the supervision enabled state for the current user or a specific user.
The intent of this API is to be consumed by Settings when a user
interacts with the main Supervision setting toggle.
Change-Id: I451e08af74b9819e4644ca64bad80ca55c089208
Test: atest SupervisionServiceTest
Bug: 392694561
Flag: android.app.supervision.flags.enable_supervision_settings_screen
4 files changed, 47 insertions, 10 deletions
diff --git a/core/java/android/app/supervision/ISupervisionManager.aidl b/core/java/android/app/supervision/ISupervisionManager.aidl index c3f3b1ced33c..e583302e4d3b 100644 --- a/core/java/android/app/supervision/ISupervisionManager.aidl +++ b/core/java/android/app/supervision/ISupervisionManager.aidl @@ -22,5 +22,6 @@ package android.app.supervision; */ interface ISupervisionManager { boolean isSupervisionEnabledForUser(int userId); + void setSupervisionEnabledForUser(int userId, boolean enabled); String getActiveSupervisionAppPackage(int userId); } diff --git a/core/java/android/app/supervision/SupervisionManager.java b/core/java/android/app/supervision/SupervisionManager.java index 12432ddd0eb9..a4efd77fce75 100644 --- a/core/java/android/app/supervision/SupervisionManager.java +++ b/core/java/android/app/supervision/SupervisionManager.java @@ -101,6 +101,35 @@ public class SupervisionManager { } /** + * Sets whether the device is supervised for the current user. + * + * @hide + */ + @UserHandleAware + public void setSupervisionEnabled(boolean enabled) { + setSupervisionEnabledForUser(mContext.getUserId(), enabled); + } + + /** + * Sets whether the device is supervised for a given user. + * + * <p>The caller must be from the same user as the target or hold the {@link + * android.Manifest.permission#INTERACT_ACROSS_USERS} permission. + * + * @hide + */ + @RequiresPermission( + value = android.Manifest.permission.INTERACT_ACROSS_USERS, + conditional = true) + public void setSupervisionEnabledForUser(@UserIdInt int userId, boolean enabled) { + try { + mService.setSupervisionEnabledForUser(userId, enabled); + } catch (RemoteException e) { + throw e.rethrowFromSystemServer(); + } + } + + /** * Returns the package name of the app that is acting as the active supervision app or null if * supervision is disabled. * diff --git a/services/supervision/java/com/android/server/supervision/SupervisionService.java b/services/supervision/java/com/android/server/supervision/SupervisionService.java index 195c65d6ec45..ea85710eab44 100644 --- a/services/supervision/java/com/android/server/supervision/SupervisionService.java +++ b/services/supervision/java/com/android/server/supervision/SupervisionService.java @@ -94,6 +94,14 @@ public class SupervisionService extends ISupervisionManager.Stub { } } + @Override + public void setSupervisionEnabledForUser(@UserIdInt int userId, boolean enabled) { + if (UserHandle.getUserId(Binder.getCallingUid()) != userId) { + enforcePermission(INTERACT_ACROSS_USERS); + } + setSupervisionEnabledForUserInternal(userId, enabled, getSystemSupervisionPackage()); + } + /** * Returns the package name of the active supervision app or null if supervision is disabled. */ @@ -160,7 +168,7 @@ public class SupervisionService extends ISupervisionManager.Stub { * Sets supervision as enabled or disabled for the given user and, in case supervision is being * enabled, the package of the active supervision app. */ - private void setSupervisionEnabledForUser( + private void setSupervisionEnabledForUserInternal( @UserIdInt int userId, boolean enabled, @Nullable String supervisionAppPackage) { synchronized (getLockObject()) { SupervisionUserData data = getUserDataLocked(userId); @@ -176,16 +184,16 @@ public class SupervisionService extends ISupervisionManager.Stub { dpmInternal != null ? dpmInternal.getProfileOwnerAsUser(userId) : null; if (po != null && po.getPackageName().equals(getSystemSupervisionPackage())) { - setSupervisionEnabledForUser(userId, true, po.getPackageName()); + setSupervisionEnabledForUserInternal(userId, true, po.getPackageName()); } else if (po != null && po.equals(getSupervisionProfileOwnerComponent())) { // TODO(b/392071637): Consider not enabling supervision in case profile owner is given // to the legacy supervision profile owner component. - setSupervisionEnabledForUser(userId, true, po.getPackageName()); + setSupervisionEnabledForUserInternal(userId, true, po.getPackageName()); } else { // TODO(b/381428475): Avoid disabling supervision when the app is not the profile owner. // This might only be possible after introducing specific and public APIs to enable // and disable supervision. - setSupervisionEnabledForUser(userId, false, /* supervisionAppPackage= */ null); + setSupervisionEnabledForUserInternal(userId, false, /* supervisionAppPackage= */ null); } } @@ -327,8 +335,7 @@ public class SupervisionService extends ISupervisionManager.Stub { @Override public void setSupervisionEnabledForUser(@UserIdInt int userId, boolean enabled) { - SupervisionService.this.setSupervisionEnabledForUser( - userId, enabled, getSystemSupervisionPackage()); + SupervisionService.this.setSupervisionEnabledForUser(userId, enabled); } @Override diff --git a/services/tests/servicestests/src/com/android/server/supervision/SupervisionServiceTest.kt b/services/tests/servicestests/src/com/android/server/supervision/SupervisionServiceTest.kt index af50effb7c8e..b150b1495042 100644 --- a/services/tests/servicestests/src/com/android/server/supervision/SupervisionServiceTest.kt +++ b/services/tests/servicestests/src/com/android/server/supervision/SupervisionServiceTest.kt @@ -175,7 +175,7 @@ class SupervisionServiceTest { fun isActiveSupervisionApp_supervisionUid_supervisionEnabled_returnsTrue() { whenever(mockPackageManager.getPackagesForUid(APP_UID)) .thenReturn(arrayOf(systemSupervisionPackage)) - service.mInternal.setSupervisionEnabledForUser(USER_ID, true) + service.setSupervisionEnabledForUser(USER_ID, true) assertThat(service.mInternal.isActiveSupervisionApp(APP_UID)).isTrue() } @@ -184,7 +184,7 @@ class SupervisionServiceTest { fun isActiveSupervisionApp_supervisionUid_supervisionNotEnabled_returnsFalse() { whenever(mockPackageManager.getPackagesForUid(APP_UID)) .thenReturn(arrayOf(systemSupervisionPackage)) - service.mInternal.setSupervisionEnabledForUser(USER_ID, false) + service.setSupervisionEnabledForUser(USER_ID, false) assertThat(service.mInternal.isActiveSupervisionApp(APP_UID)).isFalse() } @@ -200,10 +200,10 @@ class SupervisionServiceTest { fun setSupervisionEnabledForUser() { assertThat(service.isSupervisionEnabledForUser(USER_ID)).isFalse() - service.mInternal.setSupervisionEnabledForUser(USER_ID, true) + service.setSupervisionEnabledForUser(USER_ID, true) assertThat(service.isSupervisionEnabledForUser(USER_ID)).isTrue() - service.mInternal.setSupervisionEnabledForUser(USER_ID, false) + service.setSupervisionEnabledForUser(USER_ID, false) assertThat(service.isSupervisionEnabledForUser(USER_ID)).isFalse() } |