summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--PermissionController/role-controller/java/com/android/role/controller/model/Role.java5
-rw-r--r--PermissionController/src/com/android/permissioncontroller/role/ui/DefaultAppViewModel.java7
-rw-r--r--PermissionController/src/com/android/permissioncontroller/role/ui/RequestRoleFragment.java6
-rw-r--r--PermissionController/src/com/android/permissioncontroller/role/ui/wear/WearRequestRoleFragment.kt9
-rw-r--r--tests/cts/rolemultiuser/src/android/app/rolemultiuser/cts/RoleManagerMultiUserTest.kt386
5 files changed, 407 insertions, 6 deletions
diff --git a/PermissionController/role-controller/java/com/android/role/controller/model/Role.java b/PermissionController/role-controller/java/com/android/role/controller/model/Role.java
index 118cb25a1..c09cb197d 100644
--- a/PermissionController/role-controller/java/com/android/role/controller/model/Role.java
+++ b/PermissionController/role-controller/java/com/android/role/controller/model/Role.java
@@ -1086,6 +1086,11 @@ public class Role {
*/
public void onNoneHolderSelectedAsUser(@NonNull UserHandle user, @NonNull Context context) {
RoleManagerCompat.setRoleFallbackEnabledAsUser(this, false, user, context);
+ if (RoleFlags.isProfileGroupExclusivityAvailable()
+ && getExclusivity() == Role.EXCLUSIVITY_PROFILE_GROUP) {
+ RoleManager roleManager = context.getSystemService(RoleManager.class);
+ roleManager.setActiveUserForRole(mName, user, 0);
+ }
}
/**
diff --git a/PermissionController/src/com/android/permissioncontroller/role/ui/DefaultAppViewModel.java b/PermissionController/src/com/android/permissioncontroller/role/ui/DefaultAppViewModel.java
index a8bc44877..cdee94b13 100644
--- a/PermissionController/src/com/android/permissioncontroller/role/ui/DefaultAppViewModel.java
+++ b/PermissionController/src/com/android/permissioncontroller/role/ui/DefaultAppViewModel.java
@@ -110,12 +110,15 @@ public class DefaultAppViewModel extends AndroidViewModel {
*/
public void setNoneDefaultApp() {
Context context = getApplication();
- mRole.onNoneHolderSelectedAsUser(mUser, context);
+ UserHandle user = mRole.getExclusivity() == Role.EXCLUSIVITY_PROFILE_GROUP
+ ? UserUtils.getProfileParentOrSelf(mUser, context)
+ : mUser;
+ mRole.onNoneHolderSelectedAsUser(user, context);
if (mManageRoleHolderStateLiveData.getValue() != ManageRoleHolderStateLiveData.STATE_IDLE) {
Log.i(LOG_TAG, "Trying to set default app while another request is on-going");
return;
}
- mManageRoleHolderStateLiveData.clearRoleHoldersAsUser(mRole.getName(), 0, mUser, context);
+ mManageRoleHolderStateLiveData.clearRoleHoldersAsUser(mRole.getName(), 0, user, context);
}
/**
diff --git a/PermissionController/src/com/android/permissioncontroller/role/ui/RequestRoleFragment.java b/PermissionController/src/com/android/permissioncontroller/role/ui/RequestRoleFragment.java
index e7b6dcc4c..234554193 100644
--- a/PermissionController/src/com/android/permissioncontroller/role/ui/RequestRoleFragment.java
+++ b/PermissionController/src/com/android/permissioncontroller/role/ui/RequestRoleFragment.java
@@ -57,6 +57,7 @@ import com.android.permissioncontroller.role.model.UserDeniedManager;
import com.android.permissioncontroller.role.utils.PackageUtils;
import com.android.permissioncontroller.role.utils.RoleUiBehaviorUtils;
import com.android.permissioncontroller.role.utils.UiUtils;
+import com.android.permissioncontroller.role.utils.UserUtils;
import com.android.role.controller.model.Role;
import com.android.role.controller.model.Roles;
@@ -301,8 +302,9 @@ public class RequestRoleFragment extends DialogFragment {
reportRequestResult(PermissionControllerStatsLog
.ROLE_REQUEST_RESULT_REPORTED__RESULT__USER_DENIED_GRANTED_ANOTHER,
null);
- // TODO(b/382688491): add support for "none" for profile group exclusive roles
- UserHandle user = Process.myUserHandle();
+ UserHandle user = mRole.getExclusivity() == Role.EXCLUSIVITY_PROFILE_GROUP
+ ? UserUtils.getProfileParentOrSelf(Process.myUserHandle(), context)
+ : Process.myUserHandle();
mRole.onNoneHolderSelectedAsUser(user, context);
mViewModel.getManageRoleHolderStateLiveData().clearRoleHoldersAsUser(mRoleName, 0, user,
context);
diff --git a/PermissionController/src/com/android/permissioncontroller/role/ui/wear/WearRequestRoleFragment.kt b/PermissionController/src/com/android/permissioncontroller/role/ui/wear/WearRequestRoleFragment.kt
index 5406fc904..af8dc5e92 100644
--- a/PermissionController/src/com/android/permissioncontroller/role/ui/wear/WearRequestRoleFragment.kt
+++ b/PermissionController/src/com/android/permissioncontroller/role/ui/wear/WearRequestRoleFragment.kt
@@ -39,6 +39,7 @@ import com.android.permissioncontroller.role.ui.RequestRoleViewModel
import com.android.permissioncontroller.role.ui.wear.model.WearRequestRoleViewModel
import com.android.permissioncontroller.role.ui.wear.model.WearRequestRoleViewModelFactory
import com.android.permissioncontroller.role.utils.PackageUtils
+import com.android.permissioncontroller.role.utils.UserUtils
import com.android.role.controller.model.Role
import com.android.role.controller.model.Roles
import java.util.Objects
@@ -276,8 +277,12 @@ class WearRequestRoleFragment : Fragment() {
.ROLE_REQUEST_RESULT_REPORTED__RESULT__USER_DENIED_GRANTED_ANOTHER,
null,
)
- // TODO(b/382688491): add support for "none" for profile group exclusive roles
- val user: UserHandle = Process.myUserHandle()
+ val user: UserHandle =
+ if (role.exclusivity == Role.EXCLUSIVITY_PROFILE_GROUP) {
+ UserUtils.getProfileParentOrSelf(Process.myUserHandle(), context)
+ } else {
+ Process.myUserHandle()
+ }
role.onNoneHolderSelectedAsUser(user, context)
viewModel.manageRoleHolderStateLiveData.clearRoleHoldersAsUser(
roleName,
diff --git a/tests/cts/rolemultiuser/src/android/app/rolemultiuser/cts/RoleManagerMultiUserTest.kt b/tests/cts/rolemultiuser/src/android/app/rolemultiuser/cts/RoleManagerMultiUserTest.kt
index cb8d0c6c9..ee00c2c39 100644
--- a/tests/cts/rolemultiuser/src/android/app/rolemultiuser/cts/RoleManagerMultiUserTest.kt
+++ b/tests/cts/rolemultiuser/src/android/app/rolemultiuser/cts/RoleManagerMultiUserTest.kt
@@ -711,6 +711,136 @@ class RoleManagerMultiUserTest {
@RequireRunOnPrimaryUser
@Test
@Throws(java.lang.Exception::class)
+ fun openDefaultAppListAndSetDefaultAppThenSetNoneThenHasNoneDefaultApp() {
+ try {
+ // Set test default role holder. Ensures fallbacks to a default holder
+ setDefaultHoldersForTestForAllUsers()
+ setRoleVisibleForTestForAllUsers()
+
+ context.startActivity(
+ Intent(Settings.ACTION_MANAGE_DEFAULT_APPS_SETTINGS)
+ .addCategory(Intent.CATEGORY_DEFAULT)
+ .addFlags(Intent.FLAG_ACTIVITY_NEW_TASK or Intent.FLAG_ACTIVITY_CLEAR_TASK)
+ )
+ getUiDevice().waitForIdle()
+ waitFindObject(By.text(PROFILE_GROUP_EXCLUSIVITY_ROLE_SHORT_LABEL)).click()
+ getUiDevice().waitForIdle()
+
+ val targetActiveUser = users().current().userHandle()
+ val targetAppLabel = "$APP_LABEL@${targetActiveUser.identifier}"
+ if (isWatch) {
+ waitFindObject(By.clickable(true).hasDescendant(By.text(targetAppLabel))).click()
+ getUiDevice().waitForIdle()
+ waitFindObject(By.clickable(true).hasDescendant(By.text(NONE_LABEL))).click()
+ } else {
+ waitFindObject(
+ By.clickable(true)
+ .hasDescendant(By.checkable(true))
+ .hasDescendant(By.text(targetAppLabel))
+ )
+ .click()
+ getUiDevice().waitForIdle()
+ waitFindObject(
+ By.clickable(true)
+ .hasDescendant(By.checkable(true))
+ .hasDescendant(By.text(NONE_LABEL))
+ )
+ .click()
+ }
+
+ if (isWatch) {
+ waitFindObject(By.clickable(true).checked(true).hasDescendant(By.text(NONE_LABEL)))
+ } else {
+ waitFindObject(
+ By.clickable(true)
+ .hasDescendant(By.checkable(true).checked(true))
+ .hasDescendant(By.text(NONE_LABEL))
+ )
+ }
+
+ assertThat(roleManager.getActiveUserForRole(PROFILE_GROUP_EXCLUSIVITY_ROLE_NAME))
+ .isEqualTo(deviceState.initialUser().userHandle())
+ assertNoRoleHoldersUsingGetRoleHoldersAsUser()
+
+ pressBack()
+ pressBack()
+ } finally {
+ clearDefaultHoldersForTestForAllUsers()
+ clearRoleVisibleForTestForAllUsers()
+ }
+ }
+
+ @RequireFlagsEnabled(com.android.permission.flags.Flags.FLAG_CROSS_USER_ROLE_ENABLED)
+ @EnsureHasPermission(INTERACT_ACROSS_USERS_FULL, MANAGE_ROLE_HOLDERS)
+ @EnsureHasWorkProfile
+ @RequireRunOnPrimaryUser
+ @Test
+ @Throws(java.lang.Exception::class)
+ fun openDefaultAppListAndSetWorkDefaultAppThenSetNoneThenHasNoneDefaultApp() {
+ try {
+ // Set test default role holder. Ensures fallbacks to a default holder
+ setDefaultHoldersForTestForAllUsers()
+ setRoleVisibleForTestForAllUsers()
+
+ context.startActivity(
+ Intent(Settings.ACTION_MANAGE_DEFAULT_APPS_SETTINGS)
+ .addCategory(Intent.CATEGORY_DEFAULT)
+ .addFlags(Intent.FLAG_ACTIVITY_NEW_TASK or Intent.FLAG_ACTIVITY_CLEAR_TASK)
+ )
+ getUiDevice().waitForIdle()
+ waitFindObject(By.text(PROFILE_GROUP_EXCLUSIVITY_ROLE_SHORT_LABEL)).click()
+ getUiDevice().waitForIdle()
+
+ val targetActiveUser = deviceState.workProfile().userHandle()
+ val targetAppLabel = "$APP_LABEL@${targetActiveUser.identifier}"
+ if (isWatch) {
+ waitFindObject(By.clickable(true).hasDescendant(By.text(targetAppLabel))).click()
+ getUiDevice().waitForIdle()
+ waitFindObject(By.clickable(true).hasDescendant(By.text(NONE_LABEL))).click()
+ } else {
+ waitFindObject(
+ By.clickable(true)
+ .hasDescendant(By.checkable(true))
+ .hasDescendant(By.text(targetAppLabel))
+ )
+ .click()
+ getUiDevice().waitForIdle()
+ waitFindObject(
+ By.clickable(true)
+ .hasDescendant(By.checkable(true))
+ .hasDescendant(By.text(NONE_LABEL))
+ )
+ .click()
+ }
+
+ if (isWatch) {
+ waitFindObject(By.clickable(true).checked(true).hasDescendant(By.text(NONE_LABEL)))
+ } else {
+ waitFindObject(
+ By.clickable(true)
+ .hasDescendant(By.checkable(true).checked(true))
+ .hasDescendant(By.text(NONE_LABEL))
+ )
+ }
+
+ assertThat(roleManager.getActiveUserForRole(PROFILE_GROUP_EXCLUSIVITY_ROLE_NAME))
+ .isEqualTo(deviceState.initialUser().userHandle())
+ assertNoRoleHoldersUsingGetRoleHoldersAsUser()
+
+ pressBack()
+ pressBack()
+ } finally {
+ clearDefaultHoldersForTestForAllUsers()
+ clearRoleVisibleForTestForAllUsers()
+ }
+ }
+
+ @RequireFlagsEnabled(com.android.permission.flags.Flags.FLAG_CROSS_USER_ROLE_ENABLED)
+ @EnsureHasPermission(INTERACT_ACROSS_USERS_FULL, MANAGE_ROLE_HOLDERS)
+ @EnsureHasWorkProfile
+ @RequireRunOnPrimaryUser
+ @Test
+ @Throws(java.lang.Exception::class)
fun openDefaultAppListAndSetDefaultAppThenIsDefaultAppInList() {
try {
// Set test default role holder. Ensures fallbacks to a default holder
@@ -818,6 +948,140 @@ class RoleManagerMultiUserTest {
}
@RequireFlagsEnabled(com.android.permission.flags.Flags.FLAG_CROSS_USER_ROLE_ENABLED)
+ @EnsureHasPermission(INTERACT_ACROSS_USERS_FULL, MANAGE_ROLE_HOLDERS)
+ @EnsureHasWorkProfile
+ @RequireRunOnPrimaryUser
+ @Test
+ @Throws(java.lang.Exception::class)
+ fun openDefaultAppListAndSetDefaultAppThenSetNoneThenIsNoneDefaultAppInList() {
+ try {
+ // Set test default role holder. Ensures fallbacks to a default holder
+ setDefaultHoldersForTestForAllUsers()
+ setRoleVisibleForTestForAllUsers()
+
+ context.startActivity(
+ Intent(Settings.ACTION_MANAGE_DEFAULT_APPS_SETTINGS)
+ .addCategory(Intent.CATEGORY_DEFAULT)
+ .addFlags(Intent.FLAG_ACTIVITY_NEW_TASK or Intent.FLAG_ACTIVITY_CLEAR_TASK)
+ )
+ getUiDevice().waitForIdle()
+ waitFindObject(By.text(PROFILE_GROUP_EXCLUSIVITY_ROLE_SHORT_LABEL)).click()
+ getUiDevice().waitForIdle()
+
+ val targetActiveUser = users().current().userHandle()
+ val targetAppLabel = "$APP_LABEL@${targetActiveUser.identifier}"
+ if (isWatch) {
+ waitFindObject(By.clickable(true).hasDescendant(By.text(targetAppLabel))).click()
+ getUiDevice().waitForIdle()
+ waitFindObject(By.clickable(true).hasDescendant(By.text(NONE_LABEL))).click()
+ waitFindObject(By.clickable(true).checked(true).hasDescendant(By.text(NONE_LABEL)))
+ } else {
+ waitFindObject(
+ By.clickable(true)
+ .hasDescendant(By.checkable(true))
+ .hasDescendant(By.text(targetAppLabel))
+ )
+ .click()
+ getUiDevice().waitForIdle()
+ waitFindObject(
+ By.clickable(true)
+ .hasDescendant(By.checkable(true))
+ .hasDescendant(By.text(NONE_LABEL))
+ )
+ .click()
+ waitFindObject(
+ By.clickable(true)
+ .hasDescendant(By.checkable(true).checked(true))
+ .hasDescendant(By.text(NONE_LABEL))
+ )
+ }
+ pressBack()
+
+ waitFindObject(
+ By.clickable(true)
+ .hasDescendant(By.text(PROFILE_GROUP_EXCLUSIVITY_ROLE_SHORT_LABEL))
+ .hasDescendant(By.text(NONE_LABEL))
+ )
+
+ assertThat(roleManager.getActiveUserForRole(PROFILE_GROUP_EXCLUSIVITY_ROLE_NAME))
+ .isEqualTo(deviceState.initialUser().userHandle())
+ assertNoRoleHoldersUsingGetRoleHoldersAsUser()
+
+ pressBack()
+ } finally {
+ clearDefaultHoldersForTestForAllUsers()
+ clearRoleVisibleForTestForAllUsers()
+ }
+ }
+
+ @RequireFlagsEnabled(com.android.permission.flags.Flags.FLAG_CROSS_USER_ROLE_ENABLED)
+ @EnsureHasPermission(INTERACT_ACROSS_USERS_FULL, MANAGE_ROLE_HOLDERS)
+ @EnsureHasWorkProfile
+ @RequireRunOnPrimaryUser
+ @Test
+ @Throws(java.lang.Exception::class)
+ fun openDefaultAppListAndSetWorkDefaultAppThenSetNoneThenIsNoneDefaultAppInList() {
+ try {
+ // Set test default role holder. Ensures fallbacks to a default holder
+ setDefaultHoldersForTestForAllUsers()
+ setRoleVisibleForTestForAllUsers()
+
+ context.startActivity(
+ Intent(Settings.ACTION_MANAGE_DEFAULT_APPS_SETTINGS)
+ .addCategory(Intent.CATEGORY_DEFAULT)
+ .addFlags(Intent.FLAG_ACTIVITY_NEW_TASK or Intent.FLAG_ACTIVITY_CLEAR_TASK)
+ )
+ getUiDevice().waitForIdle()
+ waitFindObject(By.text(PROFILE_GROUP_EXCLUSIVITY_ROLE_SHORT_LABEL)).click()
+ getUiDevice().waitForIdle()
+
+ val targetActiveUser = deviceState.workProfile().userHandle()
+ val targetAppLabel = "$APP_LABEL@${targetActiveUser.identifier}"
+ if (isWatch) {
+ waitFindObject(By.clickable(true).hasDescendant(By.text(targetAppLabel))).click()
+ getUiDevice().waitForIdle()
+ waitFindObject(By.clickable(true).hasDescendant(By.text(NONE_LABEL))).click()
+ waitFindObject(By.clickable(true).checked(true).hasDescendant(By.text(NONE_LABEL)))
+ } else {
+ waitFindObject(
+ By.clickable(true)
+ .hasDescendant(By.checkable(true))
+ .hasDescendant(By.text(targetAppLabel))
+ )
+ .click()
+ getUiDevice().waitForIdle()
+ waitFindObject(
+ By.clickable(true)
+ .hasDescendant(By.checkable(true))
+ .hasDescendant(By.text(NONE_LABEL))
+ )
+ .click()
+ waitFindObject(
+ By.clickable(true)
+ .hasDescendant(By.checkable(true).checked(true))
+ .hasDescendant(By.text(NONE_LABEL))
+ )
+ }
+ pressBack()
+
+ waitFindObject(
+ By.clickable(true)
+ .hasDescendant(By.text(PROFILE_GROUP_EXCLUSIVITY_ROLE_SHORT_LABEL))
+ .hasDescendant(By.text(NONE_LABEL))
+ )
+
+ assertThat(roleManager.getActiveUserForRole(PROFILE_GROUP_EXCLUSIVITY_ROLE_NAME))
+ .isEqualTo(deviceState.initialUser().userHandle())
+ assertNoRoleHoldersUsingGetRoleHoldersAsUser()
+
+ pressBack()
+ } finally {
+ clearDefaultHoldersForTestForAllUsers()
+ clearRoleVisibleForTestForAllUsers()
+ }
+ }
+
+ @RequireFlagsEnabled(com.android.permission.flags.Flags.FLAG_CROSS_USER_ROLE_ENABLED)
@EnsureHasWorkProfile
@RequireRunOnPrimaryUser
@Test
@@ -925,6 +1189,57 @@ class RoleManagerMultiUserTest {
@RequireFlagsEnabled(com.android.permission.flags.Flags.FLAG_CROSS_USER_ROLE_ENABLED)
@EnsureHasWorkProfile
+ @RequireRunOnPrimaryUser
+ @Test
+ @Throws(java.lang.Exception::class)
+ fun requestRoleAndSelectNoneThenIsNoneRoleHolder() {
+ try {
+ // setDefaultHoldersForTestForAllUsers and setRoleVisibleForTestForAllUsers require
+ // INTERACT_ACROSS_USERS_FULL and MANAGE_ROLE_HOLDERS permissions to validate cross user
+ // role active user and role holder states
+ permissions().withPermission(INTERACT_ACROSS_USERS_FULL, MANAGE_ROLE_HOLDERS).use { _ ->
+ // Set test default role holder. Ensures fallbacks to a default holder
+ setDefaultHoldersForTestForAllUsers()
+ setRoleVisibleForTestForAllUsers()
+
+ // Ensure non-primary selected first. Request exits early if user and package
+ // already the role holder
+ val future = CallbackFuture()
+ roleManager.addRoleHolderAsUser(
+ PROFILE_GROUP_EXCLUSIVITY_ROLE_NAME,
+ APP_PACKAGE_NAME,
+ 0,
+ deviceState.workProfile().userHandle(),
+ context.mainExecutor,
+ future,
+ )
+ assertThat(future.get(TIMEOUT_MILLIS, TimeUnit.MILLISECONDS)).isTrue()
+ }
+
+ requestRole(PROFILE_GROUP_EXCLUSIVITY_ROLE_NAME)
+ respondNoneToRoleRequest()
+
+ // getActiveUserForRole and getRoleHoldersAsUser require INTERACT_ACROSS_USERS_FULL and
+ // MANAGE_ROLE_HOLDERS permissions to validate cross user role active user and role
+ // holder states
+ permissions().withPermission(INTERACT_ACROSS_USERS_FULL, MANAGE_ROLE_HOLDERS).use { _ ->
+ assertThat(roleManager.getActiveUserForRole(PROFILE_GROUP_EXCLUSIVITY_ROLE_NAME))
+ .isEqualTo(deviceState.initialUser().userHandle())
+ assertNoRoleHoldersUsingGetRoleHoldersAsUser()
+ }
+ } finally {
+ // clearDefaultHoldersForTestForAllUsers and clearRoleVisibleForTestForAllUsers require
+ // INTERACT_ACROSS_USERS_FULL and MANAGE_ROLE_HOLDERS permissions to validate cross user
+ // role active user and role holder states
+ permissions().withPermission(INTERACT_ACROSS_USERS_FULL, MANAGE_ROLE_HOLDERS).use { _ ->
+ clearDefaultHoldersForTestForAllUsers()
+ clearRoleVisibleForTestForAllUsers()
+ }
+ }
+ }
+
+ @RequireFlagsEnabled(com.android.permission.flags.Flags.FLAG_CROSS_USER_ROLE_ENABLED)
+ @EnsureHasWorkProfile
@RequireRunOnWorkProfile
@Test
@Throws(java.lang.Exception::class)
@@ -1029,6 +1344,57 @@ class RoleManagerMultiUserTest {
}
}
+ @RequireFlagsEnabled(com.android.permission.flags.Flags.FLAG_CROSS_USER_ROLE_ENABLED)
+ @EnsureHasWorkProfile
+ @RequireRunOnWorkProfile
+ @Test
+ @Throws(java.lang.Exception::class)
+ fun requestRoleFromWorkProfileAndSelectNoneThenIsNoneRoleHolder() {
+ try {
+ // setDefaultHoldersForTestForAllUsers and setRoleVisibleForTestForAllUsers require
+ // INTERACT_ACROSS_USERS_FULL and MANAGE_ROLE_HOLDERS permissions to validate cross user
+ // role active user and role holder states
+ permissions().withPermission(INTERACT_ACROSS_USERS_FULL, MANAGE_ROLE_HOLDERS).use { _ ->
+ // Set test default role holder. Ensures fallbacks to a default holder
+ setDefaultHoldersForTestForAllUsers()
+ setRoleVisibleForTestForAllUsers()
+
+ // Ensure non-work selected first. Request exits early if user and package
+ // already the role holder
+ val future = CallbackFuture()
+ roleManager.addRoleHolderAsUser(
+ PROFILE_GROUP_EXCLUSIVITY_ROLE_NAME,
+ APP_PACKAGE_NAME,
+ 0,
+ deviceState.initialUser().userHandle(),
+ context.mainExecutor,
+ future,
+ )
+ assertThat(future.get(TIMEOUT_MILLIS, TimeUnit.MILLISECONDS)).isTrue()
+ }
+
+ requestRole(PROFILE_GROUP_EXCLUSIVITY_ROLE_NAME)
+ respondNoneToRoleRequest()
+
+ // getActiveUserForRole and getRoleHoldersAsUser require INTERACT_ACROSS_USERS_FULL and
+ // MANAGE_ROLE_HOLDERS permissions to validate cross user role active user and role
+ // holder states
+ permissions().withPermission(INTERACT_ACROSS_USERS_FULL, MANAGE_ROLE_HOLDERS).use { _ ->
+ assertThat(roleManager.getActiveUserForRole(PROFILE_GROUP_EXCLUSIVITY_ROLE_NAME))
+ .isEqualTo(deviceState.initialUser().userHandle())
+ assertNoRoleHoldersUsingGetRoleHoldersAsUser()
+ }
+ } finally {
+ // clearDefaultHoldersForTestForAllUsers and clearRoleVisibleForTestForAllUsers require
+ // INTERACT_ACROSS_USERS_FULL and MANAGE_ROLE_HOLDERS permissions to validate cross user
+ // role active user and role holder states
+ permissions().withPermission(INTERACT_ACROSS_USERS_FULL, MANAGE_ROLE_HOLDERS).use { _ ->
+ clearDefaultHoldersForTestForAllUsers()
+ clearRoleVisibleForTestForAllUsers()
+ }
+ }
+ }
+
@Throws(java.lang.Exception::class)
private fun installAppForAllUsers() {
SystemUtil.runShellCommandOrThrow("pm install -r --user all $APP_APK_PATH")
@@ -1066,6 +1432,12 @@ class RoleManagerMultiUserTest {
assertThat(result.first).isEqualTo(expectedResult)
}
+ private fun respondNoneToRoleRequest() {
+ waitFindObject(By.text(NONE_LABEL)).click()
+ val result: Pair<Int, Intent?> = clickButtonAndWaitForResult(true)
+ assertThat(result.first).isEqualTo(Activity.RESULT_CANCELED)
+ }
+
private fun clickButtonAndWaitForResult(positive: Boolean): Pair<Int, Intent?> {
waitFindObject(if (positive) POSITIVE_BUTTON_SELECTOR else NEGATIVE_BUTTON_SELECTOR).click()
return waitForResult()
@@ -1076,6 +1448,19 @@ class RoleManagerMultiUserTest {
return activityRule.getActivity().waitForActivityResult(TIMEOUT_MILLIS)
}
+ private fun assertNoRoleHoldersUsingGetRoleHoldersAsUser() {
+ for (userReference in users().profileGroup(deviceState.initialUser())) {
+ val user = userReference.userHandle()
+ // Verify the non-active user does not hold the role
+ assertWithMessage(
+ "Expected user ${user.identifier} to not have a role holder for" +
+ " $PROFILE_GROUP_EXCLUSIVITY_ROLE_NAME"
+ )
+ .that(roleManager.getRoleHoldersAsUser(PROFILE_GROUP_EXCLUSIVITY_ROLE_NAME, user))
+ .isEmpty()
+ }
+ }
+
private fun assertExpectedProfileHasRoleUsingGetRoleHoldersAsUser(
expectedActiveUser: UserHandle
) {
@@ -1193,6 +1578,7 @@ class RoleManagerMultiUserTest {
private const val APP_PACKAGE_NAME = "android.app.role.cts.app"
private const val APP_LABEL = "CtsRoleTestApp"
private const val APP_REQUEST_ROLE_ACTIVITY_NAME = APP_PACKAGE_NAME + ".RequestRoleActivity"
+ private const val NONE_LABEL = "None"
private val context: Context = context().instrumentedContext()
private val roleManager: RoleManager = context.getSystemService(RoleManager::class.java)