Merge "Cache getProfileIds to reduce high volume of binder calls." into main
diff --git a/core/java/android/os/UserManager.java b/core/java/android/os/UserManager.java
index fa99f35..4bc8fe0 100644
--- a/core/java/android/os/UserManager.java
+++ b/core/java/android/os/UserManager.java
@@ -5502,10 +5502,14 @@
Manifest.permission.CREATE_USERS,
Manifest.permission.QUERY_USERS}, conditional = true)
public @NonNull int[] getProfileIds(@UserIdInt int userId, boolean enabledOnly) {
- try {
- return mService.getProfileIds(userId, enabledOnly);
- } catch (RemoteException re) {
- throw re.rethrowFromSystemServer();
+ if (android.multiuser.Flags.cacheProfileIdsReadOnly()) {
+ return enabledOnly ? getEnabledProfileIds(userId) : getProfileIdsWithDisabled(userId);
+ } else {
+ try {
+ return mService.getProfileIds(userId, enabledOnly);
+ } catch (RemoteException re) {
+ throw re.rethrowFromSystemServer();
+ }
}
}
@@ -5518,8 +5522,14 @@
Manifest.permission.MANAGE_USERS,
Manifest.permission.CREATE_USERS,
Manifest.permission.QUERY_USERS}, conditional = true)
+ @CachedProperty(api = "user_manager_users")
public int[] getProfileIdsWithDisabled(@UserIdInt int userId) {
- return getProfileIds(userId, false /* enabledOnly */);
+ if (android.multiuser.Flags.cacheProfileIdsReadOnly()) {
+ return UserManagerCache.getProfileIdsWithDisabled(
+ (Integer userIdentifuer) -> mService.getProfileIds(userIdentifuer, false), userId);
+ } else {
+ return getProfileIds(userId, false /* enabledOnly */);
+ }
}
/**
@@ -5530,8 +5540,21 @@
Manifest.permission.MANAGE_USERS,
Manifest.permission.CREATE_USERS,
Manifest.permission.QUERY_USERS}, conditional = true)
+ @CachedProperty(api = "user_manager_users_enabled")
public int[] getEnabledProfileIds(@UserIdInt int userId) {
- return getProfileIds(userId, true /* enabledOnly */);
+ if (android.multiuser.Flags.cacheProfileIdsReadOnly()) {
+ return UserManagerCache.getEnabledProfileIds(
+ (Integer userIdentifuer) -> mService.getProfileIds(userIdentifuer, true), userId);
+ } else {
+ return getProfileIds(userId, true /* enabledOnly */);
+ }
+ }
+
+ /** @hide */
+ public static final void invalidateEnabledProfileIds() {
+ if (android.multiuser.Flags.cacheProfileIdsReadOnly()) {
+ UserManagerCache.invalidateEnabledProfileIds();
+ }
}
/**
@@ -6443,6 +6466,21 @@
if (android.multiuser.Flags.cacheProfileParentReadOnly()) {
UserManagerCache.invalidateProfileParent();
}
+ invalidateEnabledProfileIds();
+ }
+
+ /**
+ * Invalidate caches when related to specific user info flags change.
+ *
+ * @param flag a combination of FLAG_ constants, from the list in
+ * {@link UserInfo#UserInfoFlag}, whose value has changed and the associated
+ * invalidations must therefore be performed.
+ * @hide
+ */
+ public static final void invalidateOnUserInfoFlagChange(@UserInfoFlag int flags) {
+ if ((flags & UserInfo.FLAG_DISABLED) > 0) {
+ invalidateEnabledProfileIds();
+ }
}
/**
diff --git a/services/core/java/com/android/server/pm/UserManagerService.java b/services/core/java/com/android/server/pm/UserManagerService.java
index 6c03214..7ecfe7f 100644
--- a/services/core/java/com/android/server/pm/UserManagerService.java
+++ b/services/core/java/com/android/server/pm/UserManagerService.java
@@ -1222,7 +1222,7 @@
// Mark the user for removal.
addRemovingUserIdLocked(ui.id);
ui.partial = true;
- ui.flags |= UserInfo.FLAG_DISABLED;
+ addUserInfoFlags(ui, UserInfo.FLAG_DISABLED);
}
/* Prunes out any partially created or partially removed users. */
@@ -1264,7 +1264,7 @@
if (ui.preCreated) {
preCreatedUsers.add(ui);
addRemovingUserIdLocked(ui.id);
- ui.flags |= UserInfo.FLAG_DISABLED;
+ addUserInfoFlags(ui, UserInfo.FLAG_DISABLED);
ui.partial = true;
}
}
@@ -2120,7 +2120,7 @@
info = getUserInfoLU(userId);
if (info != null && !info.isEnabled()) {
wasUserDisabled = true;
- info.flags ^= UserInfo.FLAG_DISABLED;
+ removeUserInfoFlags(info, UserInfo.FLAG_DISABLED);
writeUserLP(getUserDataLU(info.id));
}
}
@@ -2130,6 +2130,36 @@
}
}
+ /**
+ * This method is for monitoring flag changes on users flags and invalidate cache relevant to
+ * the change. The method add flags and invalidateOnUserInfoFlagChange for the flags which
+ * has changed.
+ * @param userInfo of existing user in mUsers list
+ * @param flags to be added to userInfo
+ */
+ private void addUserInfoFlags(UserInfo userInfo, @UserInfoFlag int flags) {
+ int diff = ~userInfo.flags & flags;
+ if (diff > 0) {
+ userInfo.flags |= diff;
+ UserManager.invalidateOnUserInfoFlagChange(diff);
+ }
+ }
+
+ /**
+ * This method is for monitoring flag changes on users flags and invalidate cache relevant to
+ * the change. The method remove flags and invalidateOnUserInfoFlagChange for the flags which
+ * has changed.
+ * @param userInfo of existing user in mUsers list
+ * @param flags to be removed from userInfo
+ */
+ private void removeUserInfoFlags(UserInfo userInfo, @UserInfoFlag int flags) {
+ int diff = userInfo.flags & flags;
+ if (diff > 0) {
+ userInfo.flags ^= diff;
+ UserManager.invalidateOnUserInfoFlagChange(diff);
+ }
+ }
+
@Override
public void setUserAdmin(@UserIdInt int userId) {
checkManageUserAndAcrossUsersFullPermission("set user admin");
@@ -6245,7 +6275,7 @@
userData.info.guestToRemove = true;
// Mark it as disabled, so that it isn't returned any more when
// profiles are queried.
- userData.info.flags |= UserInfo.FLAG_DISABLED;
+ addUserInfoFlags(userData.info, UserInfo.FLAG_DISABLED);
writeUserLP(userData);
}
} finally {
@@ -6390,7 +6420,7 @@
}
// Mark it as disabled, so that it isn't returned any more when
// profiles are queried.
- userData.info.flags |= UserInfo.FLAG_DISABLED;
+ addUserInfoFlags(userData.info, UserInfo.FLAG_DISABLED);
writeUserLP(userData);
}
@@ -7789,7 +7819,7 @@
if (userInfo != null && userInfo.isEphemeral()) {
// Do not allow switching back to the ephemeral user again as the user is going
// to be deleted.
- userInfo.flags |= UserInfo.FLAG_DISABLED;
+ addUserInfoFlags(userInfo, UserInfo.FLAG_DISABLED);
if (userInfo.isGuest()) {
// Indicate that the guest will be deleted after it stops.
userInfo.guestToRemove = true;