diff options
Diffstat (limited to 'service')
5 files changed, 98 insertions, 7 deletions
diff --git a/service/java/com/android/role/RoleService.java b/service/java/com/android/role/RoleService.java index 20250b4f6..b8e3ad8b1 100644 --- a/service/java/com/android/role/RoleService.java +++ b/service/java/com/android/role/RoleService.java @@ -176,6 +176,7 @@ public class RoleService extends SystemService implements RoleUserState.Callback registerUserRemovedReceiver(); } + // TODO(b/375029649): enforce single active user for all cross-user roles private void registerUserRemovedReceiver() { IntentFilter intentFilter = new IntentFilter(); intentFilter.addAction(Intent.ACTION_USER_REMOVED); @@ -191,6 +192,7 @@ public class RoleService extends SystemService implements RoleUserState.Callback }, intentFilter, null, null); } + // TODO(b/375029649): enforce single active user for all cross-user roles @Override public void onStart() { publishBinderService(Context.ROLE_SERVICE, new Stub()); diff --git a/service/java/com/android/role/RoleUserState.java b/service/java/com/android/role/RoleUserState.java index 81007d65e..cda7fcfa8 100644 --- a/service/java/com/android/role/RoleUserState.java +++ b/service/java/com/android/role/RoleUserState.java @@ -39,6 +39,7 @@ import com.android.role.persistence.RolesState; import com.android.server.role.RoleServicePlatformHelper; import java.util.ArrayList; +import java.util.Collections; import java.util.List; import java.util.Map; import java.util.Objects; @@ -96,6 +97,10 @@ class RoleUserState { private ArraySet<String> mFallbackEnabledRoles = new ArraySet<>(); @GuardedBy("mLock") + @NonNull + private ArrayMap<String, Integer> mActiveUserIds = new ArrayMap<>(); + + @GuardedBy("mLock") private boolean mWriteScheduled; @GuardedBy("mLock") @@ -449,9 +454,15 @@ class RoleUserState { // Force a reconciliation on next boot if we are bypassing role qualification now. String packagesHash = mBypassingRoleQualification ? null : mPackagesHash; - roles = new RolesState(mVersion, packagesHash, - (Map<String, Set<String>>) (Map<String, ?>) snapshotRolesLocked(), - snapshotFallbackEnabledRoles()); + if (com.android.permission.flags.Flags.crossUserRoleEnabled()) { + roles = new RolesState(mVersion, packagesHash, + (Map<String, Set<String>>) (Map<String, ?>) snapshotRolesLocked(), + snapshotFallbackEnabledRoles(), snapshotActiveUserIds()); + } else { + roles = new RolesState(mVersion, packagesHash, + (Map<String, Set<String>>) (Map<String, ?>) snapshotRolesLocked(), + snapshotFallbackEnabledRoles()); + } } mPersistence.writeForUser(roles, UserHandle.of(mUserId)); @@ -463,14 +474,17 @@ class RoleUserState { Map<String, Set<String>> roles; Set<String> fallbackEnabledRoles; + Map<String, Integer> activeUserIds; if (roleState != null) { mVersion = roleState.getVersion(); mPackagesHash = roleState.getPackagesHash(); roles = roleState.getRoles(); fallbackEnabledRoles = roleState.getFallbackEnabledRoles(); + activeUserIds = roleState.getActiveUserIds(); } else { roles = mPlatformHelper.getLegacyRoleState(mUserId); fallbackEnabledRoles = roles.keySet(); + activeUserIds = Collections.emptyMap(); } mRoles.clear(); for (Map.Entry<String, Set<String>> entry : roles.entrySet()) { @@ -480,6 +494,10 @@ class RoleUserState { } mFallbackEnabledRoles.clear(); mFallbackEnabledRoles.addAll(fallbackEnabledRoles); + mActiveUserIds.clear(); + if (com.android.permission.flags.Flags.crossUserRoleEnabled()) { + mActiveUserIds.putAll(activeUserIds); + } if (roleState == null) { scheduleWriteFileLocked(); } @@ -496,12 +514,14 @@ class RoleUserState { int version; String packagesHash; ArrayMap<String, ArraySet<String>> roles; + ArrayMap<String, Integer> activeUserIds; ArraySet<String> fallbackEnabledRoles; synchronized (mLock) { version = mVersion; packagesHash = mPackagesHash; roles = snapshotRolesLocked(); fallbackEnabledRoles = snapshotFallbackEnabledRoles(); + activeUserIds = snapshotActiveUserIds(); } long fieldToken = dumpOutputStream.start(fieldName, fieldId); @@ -514,10 +534,14 @@ class RoleUserState { String roleName = roles.keyAt(rolesIndex); ArraySet<String> roleHolders = roles.valueAt(rolesIndex); boolean fallbackEnabled = fallbackEnabledRoles.contains(roleName); + Integer activeUserId = activeUserIds.get(roleName); long rolesToken = dumpOutputStream.start("roles", RoleUserStateProto.ROLES); dumpOutputStream.write("name", RoleProto.NAME, roleName); dumpOutputStream.write("fallback_enabled", RoleProto.FALLBACK_ENABLED, fallbackEnabled); + if (activeUserId != null) { + dumpOutputStream.write("active_user_id", RoleProto.ACTIVE_USER_ID, activeUserId); + } int roleHoldersSize = roleHolders.size(); for (int roleHoldersIndex = 0; roleHoldersIndex < roleHoldersSize; roleHoldersIndex++) { String roleHolder = roleHolders.valueAt(roleHoldersIndex); @@ -563,6 +587,12 @@ class RoleUserState { return new ArraySet<>(mFallbackEnabledRoles); } + @GuardedBy("mLock") + @NonNull + private ArrayMap<String, Integer> snapshotActiveUserIds() { + return new ArrayMap<>(mActiveUserIds); + } + /** * Destroy this user state and delete the corresponding file. Any pending writes to the file * will be cancelled, and any future interaction with this state will throw an exception. diff --git a/service/java/com/android/role/persistence/RolesPersistenceImpl.java b/service/java/com/android/role/persistence/RolesPersistenceImpl.java index 220a8440b..8382d3632 100644 --- a/service/java/com/android/role/persistence/RolesPersistenceImpl.java +++ b/service/java/com/android/role/persistence/RolesPersistenceImpl.java @@ -67,6 +67,7 @@ public class RolesPersistenceImpl implements RolesPersistence { private static final String ATTRIBUTE_VERSION = "version"; private static final String ATTRIBUTE_NAME = "name"; private static final String ATTRIBUTE_FALLBACK_ENABLED = "fallbackEnabled"; + private static final String ATTRIBUTE_ACTIVE_USER_ID = "activeUserId"; private static final String ATTRIBUTE_PACKAGES_HASH = "packagesHash"; @VisibleForTesting @@ -144,6 +145,7 @@ public class RolesPersistenceImpl implements RolesPersistence { Map<String, Set<String>> roles = new ArrayMap<>(); Set<String> fallbackEnabledRoles = new ArraySet<>(); + Map<String, Integer> activeUserIds = new ArrayMap<>(); int type; int depth; int innerDepth = parser.getDepth() + 1; @@ -159,12 +161,23 @@ public class RolesPersistenceImpl implements RolesPersistence { if (Boolean.parseBoolean(fallbackEnabled)) { fallbackEnabledRoles.add(roleName); } + if (com.android.permission.flags.Flags.crossUserRoleEnabled()) { + String activeUserId = parser.getAttributeValue(null, ATTRIBUTE_ACTIVE_USER_ID); + if (activeUserId != null) { + activeUserIds.put(roleName, Integer.parseInt(activeUserId)); + } + } Set<String> roleHolders = parseRoleHolders(parser); roles.put(roleName, roleHolders); } } - return new RolesState(version, packagesHash, roles, fallbackEnabledRoles); + if (com.android.permission.flags.Flags.crossUserRoleEnabled()) { + return new RolesState(version, packagesHash, roles, fallbackEnabledRoles, + activeUserIds); + } else { + return new RolesState(version, packagesHash, roles, fallbackEnabledRoles); + } } @NonNull @@ -244,15 +257,22 @@ public class RolesPersistenceImpl implements RolesPersistence { } Set<String> fallbackEnabledRoles = roles.getFallbackEnabledRoles(); + Map<String, Integer> activeUserIds = roles.getActiveUserIds(); for (Map.Entry<String, Set<String>> entry : roles.getRoles().entrySet()) { String roleName = entry.getKey(); Set<String> roleHolders = entry.getValue(); boolean isFallbackEnabled = fallbackEnabledRoles.contains(roleName); + Integer activeUserId = com.android.permission.flags.Flags.crossUserRoleEnabled() + ? activeUserIds.get(roleName) : null; serializer.startTag(null, TAG_ROLE); serializer.attribute(null, ATTRIBUTE_NAME, roleName); serializer.attribute(null, ATTRIBUTE_FALLBACK_ENABLED, Boolean.toString(isFallbackEnabled)); + if (activeUserId != null) { + serializer.attribute( + null, ATTRIBUTE_ACTIVE_USER_ID, Integer.toString(activeUserId)); + } serializeRoleHolders(serializer, roleHolders); serializer.endTag(null, TAG_ROLE); } diff --git a/service/java/com/android/role/persistence/RolesState.java b/service/java/com/android/role/persistence/RolesState.java index a189dd4c2..f1b3d8dfa 100644 --- a/service/java/com/android/role/persistence/RolesState.java +++ b/service/java/com/android/role/persistence/RolesState.java @@ -23,12 +23,13 @@ import android.annotation.SystemApi; import android.annotation.SystemApi.Client; import android.permission.flags.Flags; +import java.util.Collections; import java.util.Map; import java.util.Objects; import java.util.Set; /** - * State of all roles. + * State of all roles for a user. * * TODO(b/147914847): Remove @hide when it becomes the default. * @hide @@ -59,6 +60,12 @@ public final class RolesState { private final Set<String> mFallbackEnabledRoles; /** + * The active users for cross user roles. + */ + @NonNull + private final Map<String, Integer> mActiveUserIds; + + /** * Create a new instance of this class. * * @param version the version of the roles @@ -81,10 +88,27 @@ public final class RolesState { @FlaggedApi(Flags.FLAG_SYSTEM_SERVER_ROLE_CONTROLLER_ENABLED) public RolesState(int version, @Nullable String packagesHash, @NonNull Map<String, Set<String>> roles, @NonNull Set<String> fallbackEnabledRoles) { + this(version, packagesHash, roles, fallbackEnabledRoles, Collections.emptyMap()); + } + + /** + * Create a new instance of this class. + * + * @param version the version of the roles + * @param packagesHash the hash of all packages in the system + * @param roles the roles + * @param fallbackEnabledRoles the roles with fallback enabled + * @param activeUserIds the active users for cross user roles + * @hide + */ + public RolesState(int version, @Nullable String packagesHash, + @NonNull Map<String, Set<String>> roles, @NonNull Set<String> fallbackEnabledRoles, + @NonNull Map<String, Integer> activeUserIds) { mVersion = version; mPackagesHash = packagesHash; mRoles = roles; mFallbackEnabledRoles = fallbackEnabledRoles; + mActiveUserIds = activeUserIds; } /** @@ -127,6 +151,17 @@ public final class RolesState { return mFallbackEnabledRoles; } + /** + * Get the active users for cross user roles. + * + * @return active users for cross user roles + * @hide + */ + @NonNull + public Map<String, Integer> getActiveUserIds() { + return mActiveUserIds; + } + @Override public boolean equals(Object object) { if (this == object) { @@ -139,11 +174,12 @@ public final class RolesState { return mVersion == that.mVersion && Objects.equals(mPackagesHash, that.mPackagesHash) && Objects.equals(mRoles, that.mRoles) - && Objects.equals(mFallbackEnabledRoles, that.mFallbackEnabledRoles); + && Objects.equals(mFallbackEnabledRoles, that.mFallbackEnabledRoles) + && Objects.equals(mActiveUserIds, that.mActiveUserIds); } @Override public int hashCode() { - return Objects.hash(mVersion, mPackagesHash, mRoles, mFallbackEnabledRoles); + return Objects.hash(mVersion, mPackagesHash, mRoles, mFallbackEnabledRoles, mActiveUserIds); } } diff --git a/service/proto/role_service.proto b/service/proto/role_service.proto index f982ead5b..fb1866d83 100644 --- a/service/proto/role_service.proto +++ b/service/proto/role_service.proto @@ -56,4 +56,7 @@ message RoleProto { // Whether fallback holders are enabled for this role. optional bool fallback_enabled = 3; + + // The active user id of this cross user role. + optional int32 active_user_id = 4; } |