summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--PermissionController/res/xml/roles.xml2
-rw-r--r--PermissionController/role-controller/java/com/android/role/controller/behavior/ReservedForTestingProfileGroupExclusivityRoleBehavior.java43
-rw-r--r--PermissionController/role-controller/java/com/android/role/controller/model/Role.java21
-rw-r--r--PermissionController/role-controller/java/com/android/role/controller/service/RoleControllerServiceImpl.java14
-rw-r--r--PermissionController/role-controller/java/com/android/role/controller/util/RoleFlags.java13
-rw-r--r--tests/cts/role/src/android/app/role/cts/RoleManagerTest.java5
-rw-r--r--tests/cts/role/src/android/app/role/cts/RoleShellCommandTest.kt3
-rw-r--r--tests/cts/rolemultiuser/src/android/app/rolemultiuser/cts/RoleManagerMultiUserTest.kt171
8 files changed, 246 insertions, 26 deletions
diff --git a/PermissionController/res/xml/roles.xml b/PermissionController/res/xml/roles.xml
index 787e19e55..23f5d8344 100644
--- a/PermissionController/res/xml/roles.xml
+++ b/PermissionController/res/xml/roles.xml
@@ -1871,8 +1871,10 @@
-->
<role
name="android.app.role.RESERVED_FOR_TESTING_PROFILE_GROUP_EXCLUSIVITY"
+ behavior="ReservedForTestingProfileGroupExclusivityRoleBehavior"
exclusive="true"
exclusivity="profileGroup"
+ fallBackToDefaultHolder="true"
featureFlag="com.android.permission.flags.Flags.crossUserRoleEnabled"
showNone="true"
visible="false"/>
diff --git a/PermissionController/role-controller/java/com/android/role/controller/behavior/ReservedForTestingProfileGroupExclusivityRoleBehavior.java b/PermissionController/role-controller/java/com/android/role/controller/behavior/ReservedForTestingProfileGroupExclusivityRoleBehavior.java
new file mode 100644
index 000000000..71f988279
--- /dev/null
+++ b/PermissionController/role-controller/java/com/android/role/controller/behavior/ReservedForTestingProfileGroupExclusivityRoleBehavior.java
@@ -0,0 +1,43 @@
+/*
+ * Copyright (C) 2024 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.role.controller.behavior;
+
+import android.content.Context;
+import android.os.UserHandle;
+
+import androidx.annotation.NonNull;
+import androidx.annotation.Nullable;
+
+import com.android.role.controller.model.Role;
+import com.android.role.controller.model.RoleBehavior;
+
+import java.util.Arrays;
+import java.util.List;
+
+public class ReservedForTestingProfileGroupExclusivityRoleBehavior implements RoleBehavior {
+ // TODO(b/381315745): Update to use API for setting and getting test role default holders.
+ // This role doesn't grant any privileges, so this should be ok.
+ private static final List<String> DEFAULT_HOLDERS =
+ Arrays.asList("android.app.rolemultiuser.cts.app");
+
+ @Nullable
+ @Override
+ public List<String> getDefaultHoldersAsUser(@NonNull Role role, @NonNull UserHandle user,
+ @NonNull Context context) {
+ return DEFAULT_HOLDERS;
+ }
+}
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 48bc34b8f..c551c37dc 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
@@ -520,6 +520,12 @@ public class Role {
@NonNull
public List<String> getDefaultHoldersAsUser(@NonNull UserHandle user,
@NonNull Context context) {
+ // Do not allow default role holder for non-active user if the role is exclusive to profile
+ // group
+ if (isNonActiveUserForProfileGroupExclusiveRole(user, context)) {
+ return Collections.emptyList();
+ }
+
if (mBehavior != null) {
List<String> defaultHolders = mBehavior.getDefaultHoldersAsUser(this, user, context);
if (defaultHolders != null) {
@@ -631,6 +637,10 @@ public class Role {
if (!RoleManagerCompat.isRoleFallbackEnabledAsUser(this, user, context)) {
return null;
}
+ // Do not fall back for non-active user if the role is exclusive to profile group
+ if (isNonActiveUserForProfileGroupExclusiveRole(user, context)) {
+ return null;
+ }
if (mFallBackToDefaultHolder) {
return CollectionUtils.firstOrNull(getDefaultHoldersAsUser(user, context));
}
@@ -640,6 +650,17 @@ public class Role {
return null;
}
+ private boolean isNonActiveUserForProfileGroupExclusiveRole(@NonNull UserHandle user,
+ @NonNull Context context) {
+ if (RoleFlags.isProfileGroupExclusivityAvailable()
+ && getExclusivity() == Role.EXCLUSIVITY_PROFILE_GROUP) {
+ Context userContext = UserUtils.getUserContext(context, user);
+ RoleManager userRoleManager = userContext.getSystemService(RoleManager.class);
+ return !Objects.equals(userRoleManager.getActiveUserForRole(mName), user);
+ }
+ return false;
+ }
+
/**
* Check whether this role is allowed to bypass qualification, if enabled globally.
*
diff --git a/PermissionController/role-controller/java/com/android/role/controller/service/RoleControllerServiceImpl.java b/PermissionController/role-controller/java/com/android/role/controller/service/RoleControllerServiceImpl.java
index a5ac5700e..d00fd47af 100644
--- a/PermissionController/role-controller/java/com/android/role/controller/service/RoleControllerServiceImpl.java
+++ b/PermissionController/role-controller/java/com/android/role/controller/service/RoleControllerServiceImpl.java
@@ -35,6 +35,7 @@ import com.android.role.controller.model.Roles;
import com.android.role.controller.util.CollectionUtils;
import com.android.role.controller.util.LegacyRoleFallbackEnabledUtils;
import com.android.role.controller.util.PackageUtils;
+import com.android.role.controller.util.RoleFlags;
import com.android.role.controller.util.UserUtils;
import java.util.ArrayList;
@@ -132,6 +133,19 @@ public class RoleControllerServiceImpl extends RoleControllerService {
String roleName = role.getName();
+ if (RoleFlags.isProfileGroupExclusivityAvailable()
+ && role.getExclusivity() == Role.EXCLUSIVITY_PROFILE_GROUP) {
+ if (mUserRoleManager.getActiveUserForRole(roleName) == null) {
+ UserHandle profileParent = UserUtils.getProfileParentOrSelf(mUser, mContext);
+ if (Objects.equals(mUser, profileParent)) {
+ Log.i(LOG_TAG, "No active user for role: " + roleName + ", setting "
+ + "active user to user: " + mUser.getIdentifier());
+ sSetActiveUserForRoleMethod.setActiveUserForRole(roleName,
+ mUser.getIdentifier(), 0);
+ }
+ }
+ }
+
// For each of the current holders, check if it is still qualified, redo grant if so, or
// remove it otherwise.
List<String> currentPackageNames = mUserRoleManager.getRoleHolders(roleName);
diff --git a/PermissionController/role-controller/java/com/android/role/controller/util/RoleFlags.java b/PermissionController/role-controller/java/com/android/role/controller/util/RoleFlags.java
index f8a8502cd..2c5a247b6 100644
--- a/PermissionController/role-controller/java/com/android/role/controller/util/RoleFlags.java
+++ b/PermissionController/role-controller/java/com/android/role/controller/util/RoleFlags.java
@@ -20,7 +20,7 @@ import android.os.Build;
import androidx.annotation.ChecksSdkIntAtLeast;
-import com.android.modules.utils.build.SdkLevel;
+import java.util.Objects;
/** Util class for getting shared feature flag check logic. */
public final class RoleFlags {
@@ -30,9 +30,16 @@ public final class RoleFlags {
* Returns whether profile group exclusive roles are available. Profile exclusive roles are
* available on B+
*/
- @ChecksSdkIntAtLeast(api = Build.VERSION_CODES.VANILLA_ICE_CREAM)
+ @ChecksSdkIntAtLeast(api = Build.VERSION_CODES.BAKLAVA)
public static boolean isProfileGroupExclusivityAvailable() {
// TODO(b/372743073): change to isAtLeastB once available
- return SdkLevel.isAtLeastV() && com.android.permission.flags.Flags.crossUserRoleEnabled();
+ return isAtLeastB() && com.android.permission.flags.Flags.crossUserRoleEnabled();
+ }
+
+ // TODO(b/372743073): remove once SdkLevel.isAtLeastB available
+ @ChecksSdkIntAtLeast(api = 36 /* BUILD_VERSION_CODES.Baklava */)
+ public static boolean isAtLeastB() {
+ return Build.VERSION.SDK_INT >= Build.VERSION_CODES.BAKLAVA
+ || Objects.equals(Build.VERSION.CODENAME, "Baklava");
}
}
diff --git a/tests/cts/role/src/android/app/role/cts/RoleManagerTest.java b/tests/cts/role/src/android/app/role/cts/RoleManagerTest.java
index 9f89140d7..92ea5d98c 100644
--- a/tests/cts/role/src/android/app/role/cts/RoleManagerTest.java
+++ b/tests/cts/role/src/android/app/role/cts/RoleManagerTest.java
@@ -1352,6 +1352,7 @@ public class RoleManagerTest {
}
@RequiresFlagsEnabled(com.android.permission.flags.Flags.FLAG_CROSS_USER_ROLE_ENABLED)
+ @SdkSuppress(minSdkVersion = Build.VERSION_CODES.BAKLAVA, codeName = "Baklava")
@Test
public void cannotGetActiveUserForRoleWithoutPermission() throws Exception {
assertThrows(SecurityException.class, ()->
@@ -1359,6 +1360,7 @@ public class RoleManagerTest {
}
@RequiresFlagsEnabled(com.android.permission.flags.Flags.FLAG_CROSS_USER_ROLE_ENABLED)
+ @SdkSuppress(minSdkVersion = Build.VERSION_CODES.BAKLAVA, codeName = "Baklava")
@Test
public void cannotGetActiveUserForNonProfileGroupExclusiveRole() throws Exception {
runWithShellPermissionIdentity(() ->
@@ -1368,6 +1370,7 @@ public class RoleManagerTest {
}
@RequiresFlagsEnabled(com.android.permission.flags.Flags.FLAG_CROSS_USER_ROLE_ENABLED)
+ @SdkSuppress(minSdkVersion = Build.VERSION_CODES.BAKLAVA, codeName = "Baklava")
@Test
public void cannotSetActiveUserForRoleWithoutPermission() throws Exception {
assertThrows(SecurityException.class, ()->
@@ -1376,6 +1379,7 @@ public class RoleManagerTest {
}
@RequiresFlagsEnabled(com.android.permission.flags.Flags.FLAG_CROSS_USER_ROLE_ENABLED)
+ @SdkSuppress(minSdkVersion = Build.VERSION_CODES.BAKLAVA, codeName = "Baklava")
@Test
public void cannotSetActiveUserForNonProfileGroupExclusiveRole() throws Exception {
runWithShellPermissionIdentity(() ->
@@ -1386,6 +1390,7 @@ public class RoleManagerTest {
}
@RequiresFlagsEnabled(com.android.permission.flags.Flags.FLAG_CROSS_USER_ROLE_ENABLED)
+ @SdkSuppress(minSdkVersion = Build.VERSION_CODES.BAKLAVA, codeName = "Baklava")
@Test
public void setAndGetActiveUserForRole() throws Exception {
runWithShellPermissionIdentity(() -> {
diff --git a/tests/cts/role/src/android/app/role/cts/RoleShellCommandTest.kt b/tests/cts/role/src/android/app/role/cts/RoleShellCommandTest.kt
index f615f0f4b..c9dc97b8f 100644
--- a/tests/cts/role/src/android/app/role/cts/RoleShellCommandTest.kt
+++ b/tests/cts/role/src/android/app/role/cts/RoleShellCommandTest.kt
@@ -163,6 +163,7 @@ class RoleShellCommandTest {
}
@RequiresFlagsEnabled(Flags.FLAG_CROSS_USER_ROLE_ENABLED)
+ @SdkSuppress(minSdkVersion = Build.VERSION_CODES.BAKLAVA, codeName = "Baklava")
@Test
fun setActiveUserForProfileGroupExclusiveRoleAsUser() {
val activeUser = userId
@@ -173,12 +174,14 @@ class RoleShellCommandTest {
}
@RequiresFlagsEnabled(Flags.FLAG_CROSS_USER_ROLE_ENABLED)
+ @SdkSuppress(minSdkVersion = Build.VERSION_CODES.BAKLAVA, codeName = "Baklava")
@Test
fun setActiveUserForNonProfileGroupExclusiveRoleThenFails() {
assertThrows(AssertionError::class.java) { setActiveUserForRole(ROLE_NAME, userId) }
}
@RequiresFlagsEnabled(Flags.FLAG_CROSS_USER_ROLE_ENABLED)
+ @SdkSuppress(minSdkVersion = Build.VERSION_CODES.BAKLAVA, codeName = "Baklava")
@Test
fun getActiveUserForNonProfileGroupExclusiveRoleThenFails() {
assertThrows(AssertionError::class.java) { getActiveUserForRole(ROLE_NAME) }
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 6c9cdfcb8..e4f9ce55c 100644
--- a/tests/cts/rolemultiuser/src/android/app/rolemultiuser/cts/RoleManagerMultiUserTest.kt
+++ b/tests/cts/rolemultiuser/src/android/app/rolemultiuser/cts/RoleManagerMultiUserTest.kt
@@ -19,6 +19,7 @@ import android.app.role.RoleManager
import android.content.Context
import android.os.Build
import android.os.Process
+import android.os.UserHandle
import androidx.test.filters.SdkSuppress
import com.android.bedstead.enterprise.annotations.EnsureHasWorkProfile
import com.android.bedstead.enterprise.annotations.RequireRunOnWorkProfile
@@ -43,7 +44,10 @@ import com.android.bedstead.permissions.CommonPermissions.MANAGE_ROLE_HOLDERS
import com.android.bedstead.permissions.annotations.EnsureDoesNotHavePermission
import com.android.bedstead.permissions.annotations.EnsureHasPermission
import com.android.compatibility.common.util.SystemUtil
+import com.android.compatibility.common.util.SystemUtil.eventually
import com.google.common.truth.Truth.assertThat
+import com.google.common.truth.Truth.assertWithMessage
+import java.util.Objects
import java.util.concurrent.CompletableFuture
import java.util.concurrent.TimeUnit
import java.util.function.Consumer
@@ -56,7 +60,7 @@ import org.junit.Rule
import org.junit.Test
import org.junit.runner.RunWith
-@SdkSuppress(minSdkVersion = Build.VERSION_CODES.VANILLA_ICE_CREAM)
+@SdkSuppress(minSdkVersion = Build.VERSION_CODES.BAKLAVA, codeName = "Baklava")
@RunWith(BedsteadJUnit4::class)
class RoleManagerMultiUserTest {
@Before
@@ -189,6 +193,45 @@ class RoleManagerMultiUserTest {
@RequireFlagsEnabled(com.android.permission.flags.Flags.FLAG_CROSS_USER_ROLE_ENABLED)
@EnsureHasPermission(INTERACT_ACROSS_USERS_FULL, MANAGE_ROLE_HOLDERS)
+ @EnsureHasWorkProfile
+ @EnsureHasAdditionalUser(installInstrumentedApp = OptionalBoolean.TRUE)
+ @EnsureHasSecondaryUser
+ @RequireRunNotOnSecondaryUser
+ @Test
+ @Throws(java.lang.Exception::class)
+ fun ensureRoleHasActiveUser() {
+ val primaryUser = deviceState.initialUser().userHandle()
+ val primaryUserRoleManager = getRoleManagerForUser(primaryUser)
+ val secondaryUser = deviceState.secondaryUser().userHandle()
+ val secondaryUserRoleManager = getRoleManagerForUser(secondaryUser)
+
+ assertWithMessage(
+ "Expected active user in profile group for user ${primaryUser.identifier}"
+ )
+ .that(primaryUserRoleManager.getActiveUserForRole(PROFILE_GROUP_EXCLUSIVITY_ROLE_NAME))
+ .isNotNull()
+ assertWithMessage(
+ "Expected active user in profile group for user ${secondaryUser.identifier}"
+ )
+ .that(
+ secondaryUserRoleManager.getActiveUserForRole(PROFILE_GROUP_EXCLUSIVITY_ROLE_NAME)
+ )
+ .isNotNull()
+ }
+
+ @RequireFlagsEnabled(com.android.permission.flags.Flags.FLAG_CROSS_USER_ROLE_ENABLED)
+ @EnsureHasPermission(INTERACT_ACROSS_USERS_FULL, MANAGE_ROLE_HOLDERS)
+ @EnsureHasWorkProfile
+ @Test
+ @Throws(java.lang.Exception::class)
+ fun ensureOnlyActiveUserIsRoleHolder() {
+ val activeUser = roleManager.getActiveUserForRole(PROFILE_GROUP_EXCLUSIVITY_ROLE_NAME)!!
+ // Test app install might take a moment
+ eventually { assertExpectedProfileHasRoleUsingGetRoleHoldersAsUser(activeUser) }
+ }
+
+ @RequireFlagsEnabled(com.android.permission.flags.Flags.FLAG_CROSS_USER_ROLE_ENABLED)
+ @EnsureHasPermission(INTERACT_ACROSS_USERS_FULL, MANAGE_ROLE_HOLDERS)
@EnsureDoesNotHavePermission(MANAGE_DEFAULT_APPLICATIONS)
@EnsureHasWorkProfile(installInstrumentedApp = OptionalBoolean.TRUE)
@Test
@@ -228,12 +271,41 @@ class RoleManagerMultiUserTest {
@EnsureHasWorkProfile(installInstrumentedApp = OptionalBoolean.TRUE)
@Test
@Throws(Exception::class)
+ fun setAndGetActiveUserForRoleSetCurrentUserEnsureRoleNotHeldByInactiveUser() {
+ assumeFalse(
+ "setActiveUser not supported for private profile",
+ users().current().type().name() == PRIVATE_PROFILE_TYPE_NAME,
+ )
+ // initialUser needs to be not the targetUser
+ val targetActiveUser = users().current().userHandle()
+ val initialUser =
+ if (Objects.equals(targetActiveUser, deviceState.initialUser())) {
+ deviceState.workProfile().userHandle()
+ } else {
+ deviceState.initialUser().userHandle()
+ }
+ roleManager.setActiveUserForRole(PROFILE_GROUP_EXCLUSIVITY_ROLE_NAME, initialUser, 0)
+
+ roleManager.setActiveUserForRole(PROFILE_GROUP_EXCLUSIVITY_ROLE_NAME, targetActiveUser, 0)
+ assertThat(roleManager.getActiveUserForRole(PROFILE_GROUP_EXCLUSIVITY_ROLE_NAME))
+ .isEqualTo(targetActiveUser)
+ // We can assume targetActiveUser is role holder since fallback is enabled
+ assertExpectedProfileHasRoleUsingGetRoleHoldersAsUser(targetActiveUser)
+ }
+
+ @RequireFlagsEnabled(com.android.permission.flags.Flags.FLAG_CROSS_USER_ROLE_ENABLED)
+ @EnsureHasPermission(INTERACT_ACROSS_USERS_FULL, MANAGE_ROLE_HOLDERS)
+ @EnsureHasWorkProfile(installInstrumentedApp = OptionalBoolean.TRUE)
+ @Test
+ @Throws(Exception::class)
fun setAndGetActiveUserForRoleSetWorkProfile() {
val targetActiveUser = deviceState.workProfile().userHandle()
roleManager.setActiveUserForRole(PROFILE_GROUP_EXCLUSIVITY_ROLE_NAME, targetActiveUser, 0)
assertThat(roleManager.getActiveUserForRole(PROFILE_GROUP_EXCLUSIVITY_ROLE_NAME))
.isEqualTo(targetActiveUser)
+ // We can assume targetActiveUser is role holder since fallback is enabled
+ assertExpectedProfileHasRoleUsingGetRoleHoldersAsUser(targetActiveUser)
}
@RequireFlagsEnabled(com.android.permission.flags.Flags.FLAG_CROSS_USER_ROLE_ENABLED)
@@ -285,10 +357,9 @@ 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 addRoleHolderAsUserSetsPrimaryUserAsActive() {
+ fun addRoleHolderAsUserSetsCurrentUserAsActive() {
// Set other user as active
val initialUser = deviceState.workProfile().userHandle()
roleManager.setActiveUserForRole(PROFILE_GROUP_EXCLUSIVITY_ROLE_NAME, initialUser, 0)
@@ -306,14 +377,9 @@ class RoleManagerMultiUserTest {
future,
)
assertThat(future.get(TIMEOUT_MILLIS, TimeUnit.MILLISECONDS)).isTrue()
- assertThat(
- roleManager
- .getRoleHoldersAsUser(PROFILE_GROUP_EXCLUSIVITY_ROLE_NAME, targetActiveUser)
- .first()
- )
- .isEqualTo(APP_PACKAGE_NAME)
assertThat(roleManager.getActiveUserForRole(PROFILE_GROUP_EXCLUSIVITY_ROLE_NAME))
.isEqualTo(targetActiveUser)
+ assertExpectedProfileHasRoleUsingGetRoleHoldersAsUser(targetActiveUser)
}
@RequireFlagsEnabled(com.android.permission.flags.Flags.FLAG_CROSS_USER_ROLE_ENABLED)
@@ -330,6 +396,8 @@ class RoleManagerMultiUserTest {
.isEqualTo(initialUser)
val targetActiveUser = deviceState.workProfile().userHandle()
+
+ assertThat(targetActiveUser).isNotEqualTo(initialUser)
val future = CallbackFuture()
roleManager.addRoleHolderAsUser(
PROFILE_GROUP_EXCLUSIVITY_ROLE_NAME,
@@ -340,14 +408,9 @@ class RoleManagerMultiUserTest {
future,
)
assertThat(future.get(TIMEOUT_MILLIS, TimeUnit.MILLISECONDS)).isTrue()
- assertThat(
- roleManager
- .getRoleHoldersAsUser(PROFILE_GROUP_EXCLUSIVITY_ROLE_NAME, targetActiveUser)
- .first()
- )
- .isEqualTo(APP_PACKAGE_NAME)
assertThat(roleManager.getActiveUserForRole(PROFILE_GROUP_EXCLUSIVITY_ROLE_NAME))
.isEqualTo(targetActiveUser)
+ assertExpectedProfileHasRoleUsingGetRoleHoldersAsUser(targetActiveUser)
}
@RequireFlagsEnabled(com.android.permission.flags.Flags.FLAG_CROSS_USER_ROLE_ENABLED)
@@ -391,16 +454,16 @@ class RoleManagerMultiUserTest {
@RequireFlagsEnabled(com.android.permission.flags.Flags.FLAG_CROSS_USER_ROLE_ENABLED)
@EnsureHasPermission(INTERACT_ACROSS_USERS_FULL, MANAGE_DEFAULT_APPLICATIONS)
@EnsureHasWorkProfile
- @RequireRunOnPrimaryUser
@Test
@Throws(java.lang.Exception::class)
- fun setDefaultApplicationSetsPrimaryUserAsActive() {
+ fun setDefaultApplicationSetsCurrentUserAsActive() {
// Set other user as active
val initialUser = deviceState.workProfile().userHandle()
roleManager.setActiveUserForRole(PROFILE_GROUP_EXCLUSIVITY_ROLE_NAME, initialUser, 0)
assertThat(roleManager.getActiveUserForRole(PROFILE_GROUP_EXCLUSIVITY_ROLE_NAME))
.isEqualTo(initialUser)
+ val targetActiveUser = users().current().userHandle()
val future = CallbackFuture()
roleManager.setDefaultApplication(
PROFILE_GROUP_EXCLUSIVITY_ROLE_NAME,
@@ -410,10 +473,9 @@ class RoleManagerMultiUserTest {
future,
)
assertThat(future.get(TIMEOUT_MILLIS, TimeUnit.MILLISECONDS)).isTrue()
- assertThat(roleManager.getDefaultApplication(PROFILE_GROUP_EXCLUSIVITY_ROLE_NAME))
- .isEqualTo(APP_PACKAGE_NAME)
assertThat(roleManager.getActiveUserForRole(PROFILE_GROUP_EXCLUSIVITY_ROLE_NAME))
- .isEqualTo(users().current().userHandle())
+ .isEqualTo(targetActiveUser)
+ assertExpectedProfileHasRoleUsingGetDefaultApplication(targetActiveUser)
}
@RequireFlagsEnabled(com.android.permission.flags.Flags.FLAG_CROSS_USER_ROLE_ENABLED)
@@ -429,6 +491,8 @@ class RoleManagerMultiUserTest {
assertThat(roleManager.getActiveUserForRole(PROFILE_GROUP_EXCLUSIVITY_ROLE_NAME))
.isEqualTo(initialUser)
+ val targetActiveUser = deviceState.workProfile().userHandle()
+ assertThat(targetActiveUser).isNotEqualTo(initialUser)
val future = CallbackFuture()
roleManager.setDefaultApplication(
PROFILE_GROUP_EXCLUSIVITY_ROLE_NAME,
@@ -438,10 +502,9 @@ class RoleManagerMultiUserTest {
future,
)
assertThat(future.get(TIMEOUT_MILLIS, TimeUnit.MILLISECONDS)).isTrue()
- assertThat(roleManager.getDefaultApplication(PROFILE_GROUP_EXCLUSIVITY_ROLE_NAME))
- .isEqualTo(APP_PACKAGE_NAME)
assertThat(roleManager.getActiveUserForRole(PROFILE_GROUP_EXCLUSIVITY_ROLE_NAME))
- .isEqualTo(deviceState.workProfile().userHandle())
+ .isEqualTo(targetActiveUser)
+ assertExpectedProfileHasRoleUsingGetDefaultApplication(targetActiveUser)
}
@Throws(java.lang.Exception::class)
@@ -453,6 +516,68 @@ class RoleManagerMultiUserTest {
SystemUtil.runShellCommand("pm uninstall $APP_PACKAGE_NAME")
}
+ private fun assertExpectedProfileHasRoleUsingGetRoleHoldersAsUser(
+ expectedActiveUser: UserHandle
+ ) {
+ users().profileGroup().forEach { userReference ->
+ val user = userReference.userHandle()
+ if (Objects.equals(user, expectedActiveUser)) {
+ val roleHolders =
+ roleManager.getRoleHoldersAsUser(PROFILE_GROUP_EXCLUSIVITY_ROLE_NAME, user)
+ assertWithMessage(
+ "Expected user ${user.identifier} to have a role holder for" +
+ " $PROFILE_GROUP_EXCLUSIVITY_ROLE_NAME"
+ )
+ .that(roleHolders)
+ .isNotEmpty()
+ assertWithMessage(
+ "Expected user ${user.identifier} to have $APP_PACKAGE_NAME as role " +
+ "holder for $PROFILE_GROUP_EXCLUSIVITY_ROLE_NAME"
+ )
+ .that(roleHolders.first())
+ .isEqualTo(APP_PACKAGE_NAME)
+ } else {
+ // 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 assertExpectedProfileHasRoleUsingGetDefaultApplication(
+ expectedActiveUser: UserHandle
+ ) {
+ users().profileGroup().forEach { userReference ->
+ val user = userReference.userHandle()
+ val userRoleManager = getRoleManagerForUser(user)
+ if (Objects.equals(user, expectedActiveUser)) {
+ assertWithMessage("Expected default application for user ${user.identifier}")
+ .that(
+ userRoleManager.getDefaultApplication(PROFILE_GROUP_EXCLUSIVITY_ROLE_NAME)
+ )
+ .isEqualTo(APP_PACKAGE_NAME)
+ } else {
+ // Verify the non-active user does not hold the role
+ assertWithMessage("Expected no default application for user ${user.identifier}")
+ .that(
+ userRoleManager.getDefaultApplication(PROFILE_GROUP_EXCLUSIVITY_ROLE_NAME)
+ )
+ .isNull()
+ }
+ }
+ }
+
+ private fun getRoleManagerForUser(user: UserHandle): RoleManager {
+ val userContext = context.createContextAsUser(user, 0)
+ return userContext.getSystemService(RoleManager::class.java)
+ }
+
class CallbackFuture : CompletableFuture<Boolean?>(), Consumer<Boolean?> {
override fun accept(successful: Boolean?) {
complete(successful)