Loading core/java/android/os/UserManager.java +28 −5 Original line number Diff line number Diff line Loading @@ -34,6 +34,7 @@ import android.annotation.WorkerThread; import android.app.Activity; import android.app.ActivityManager; import android.app.admin.DevicePolicyManager; import android.app.PropertyInvalidatedCache; import android.compat.annotation.UnsupportedAppUsage; import android.content.ComponentName; import android.content.Context; Loading Loading @@ -2150,16 +2151,38 @@ public class UserManager { return isUserUnlocked(user.getIdentifier()); } private static final String CACHE_KEY_IS_USER_UNLOCKED_PROPERTY = "cache_key.is_user_unlocked"; private final PropertyInvalidatedCache<Integer, Boolean> mIsUserUnlockedCache = new PropertyInvalidatedCache<Integer, Boolean>( 32, CACHE_KEY_IS_USER_UNLOCKED_PROPERTY) { @Override protected Boolean recompute(Integer query) { try { return mService.isUserUnlocked(query); } catch (RemoteException re) { throw re.rethrowFromSystemServer(); } } }; /** {@hide} */ @UnsupportedAppUsage @RequiresPermission(anyOf = {Manifest.permission.MANAGE_USERS, Manifest.permission.INTERACT_ACROSS_USERS}, conditional = true) public boolean isUserUnlocked(@UserIdInt int userId) { try { return mService.isUserUnlocked(userId); } catch (RemoteException re) { throw re.rethrowFromSystemServer(); return mIsUserUnlockedCache.query(userId); } /** {@hide} */ public void disableIsUserUnlockedCache() { mIsUserUnlockedCache.disableLocal(); } /** {@hide} */ public static final void invalidateIsUserUnlockedCache() { PropertyInvalidatedCache.invalidateCache(CACHE_KEY_IS_USER_UNLOCKED_PROPERTY); } /** Loading services/core/java/com/android/server/StorageManagerService.java +39 −5 Original line number Diff line number Diff line Loading @@ -342,9 +342,43 @@ class StorageManagerService extends IStorageManager.Stub */ private final Object mPackagesLock = new Object(); /** * mLocalUnlockedUsers affects the return value of isUserUnlocked. If * any value in the array changes, then the binder cache for * isUserUnlocked must be invalidated. When adding mutating methods to * WatchedLockedUsers, be sure to invalidate the cache in the new * methods. */ private class WatchedLockedUsers { private int[] users = EmptyArray.INT; public WatchedLockedUsers() { } public void append(int userId) { users = ArrayUtils.appendInt(users, userId); invalidateIsUserUnlockedCache(); } public void remove(int userId) { users = ArrayUtils.removeInt(users, userId); invalidateIsUserUnlockedCache(); } public boolean contains(int userId) { return ArrayUtils.contains(users, userId); } public int[] all() { return users; } @Override public String toString() { return Arrays.toString(users); } private void invalidateIsUserUnlockedCache() { UserManager.invalidateIsUserUnlockedCache(); } } /** Set of users that we know are unlocked. */ @GuardedBy("mLock") private int[] mLocalUnlockedUsers = EmptyArray.INT; private WatchedLockedUsers mLocalUnlockedUsers = new WatchedLockedUsers(); /** Set of users that system knows are unlocked. */ @GuardedBy("mLock") private int[] mSystemUnlockedUsers = EmptyArray.INT; Loading Loading @@ -3042,7 +3076,7 @@ class StorageManagerService extends IStorageManager.Stub } synchronized (mLock) { mLocalUnlockedUsers = ArrayUtils.appendInt(mLocalUnlockedUsers, userId); mLocalUnlockedUsers.append(userId); } } Loading @@ -3058,14 +3092,14 @@ class StorageManagerService extends IStorageManager.Stub } synchronized (mLock) { mLocalUnlockedUsers = ArrayUtils.removeInt(mLocalUnlockedUsers, userId); mLocalUnlockedUsers.remove(userId); } } @Override public boolean isUserKeyUnlocked(int userId) { synchronized (mLock) { return ArrayUtils.contains(mLocalUnlockedUsers, userId); return mLocalUnlockedUsers.contains(userId); } } Loading Loading @@ -4177,7 +4211,7 @@ class StorageManagerService extends IStorageManager.Stub } pw.println(); pw.println("Local unlocked users: " + Arrays.toString(mLocalUnlockedUsers)); pw.println("Local unlocked users: " + mLocalUnlockedUsers); pw.println("System unlocked users: " + Arrays.toString(mSystemUnlockedUsers)); final ContentResolver cr = mContext.getContentResolver(); Loading services/core/java/com/android/server/pm/UserManagerService.java +40 −1 Original line number Diff line number Diff line Loading @@ -462,8 +462,42 @@ public class UserManagerService extends IUserManager.Stub { @GuardedBy("mUsersLock") private boolean mForceEphemeralUsers; /** * The member mUserStates affects the return value of isUserUnlocked. * If any value in mUserStates changes, then the binder cache for * isUserUnlocked must be invalidated. When adding mutating methods to * WatchedUserStates, be sure to invalidate the cache in the new * methods. */ private class WatchedUserStates { final SparseIntArray states; public WatchedUserStates() { states = new SparseIntArray(); } public int get(int userId) { return states.get(userId); } public int get(int userId, int fallback) { return states.indexOfKey(userId) >= 0 ? states.get(userId) : fallback; } public void put(int userId, int state) { states.put(userId, state); invalidateIsUserUnlockedCache(); } public void delete(int userId) { states.delete(userId); invalidateIsUserUnlockedCache(); } @Override public String toString() { return states.toString(); } private void invalidateIsUserUnlockedCache() { UserManager.invalidateIsUserUnlockedCache(); } } @GuardedBy("mUserStates") private final SparseIntArray mUserStates = new SparseIntArray(); private final WatchedUserStates mUserStates = new WatchedUserStates(); private static UserManagerService sInstance; Loading Loading @@ -4801,6 +4835,11 @@ public class UserManagerService extends IUserManager.Stub { || (state == UserState.STATE_RUNNING_UNLOCKED); } /** * The return values of this method are cached in clients. If the * logic in this function changes then the cache invalidation code * may need to be revisited. */ @Override public boolean isUserUnlocked(@UserIdInt int userId) { int state; Loading Loading
core/java/android/os/UserManager.java +28 −5 Original line number Diff line number Diff line Loading @@ -34,6 +34,7 @@ import android.annotation.WorkerThread; import android.app.Activity; import android.app.ActivityManager; import android.app.admin.DevicePolicyManager; import android.app.PropertyInvalidatedCache; import android.compat.annotation.UnsupportedAppUsage; import android.content.ComponentName; import android.content.Context; Loading Loading @@ -2150,16 +2151,38 @@ public class UserManager { return isUserUnlocked(user.getIdentifier()); } private static final String CACHE_KEY_IS_USER_UNLOCKED_PROPERTY = "cache_key.is_user_unlocked"; private final PropertyInvalidatedCache<Integer, Boolean> mIsUserUnlockedCache = new PropertyInvalidatedCache<Integer, Boolean>( 32, CACHE_KEY_IS_USER_UNLOCKED_PROPERTY) { @Override protected Boolean recompute(Integer query) { try { return mService.isUserUnlocked(query); } catch (RemoteException re) { throw re.rethrowFromSystemServer(); } } }; /** {@hide} */ @UnsupportedAppUsage @RequiresPermission(anyOf = {Manifest.permission.MANAGE_USERS, Manifest.permission.INTERACT_ACROSS_USERS}, conditional = true) public boolean isUserUnlocked(@UserIdInt int userId) { try { return mService.isUserUnlocked(userId); } catch (RemoteException re) { throw re.rethrowFromSystemServer(); return mIsUserUnlockedCache.query(userId); } /** {@hide} */ public void disableIsUserUnlockedCache() { mIsUserUnlockedCache.disableLocal(); } /** {@hide} */ public static final void invalidateIsUserUnlockedCache() { PropertyInvalidatedCache.invalidateCache(CACHE_KEY_IS_USER_UNLOCKED_PROPERTY); } /** Loading
services/core/java/com/android/server/StorageManagerService.java +39 −5 Original line number Diff line number Diff line Loading @@ -342,9 +342,43 @@ class StorageManagerService extends IStorageManager.Stub */ private final Object mPackagesLock = new Object(); /** * mLocalUnlockedUsers affects the return value of isUserUnlocked. If * any value in the array changes, then the binder cache for * isUserUnlocked must be invalidated. When adding mutating methods to * WatchedLockedUsers, be sure to invalidate the cache in the new * methods. */ private class WatchedLockedUsers { private int[] users = EmptyArray.INT; public WatchedLockedUsers() { } public void append(int userId) { users = ArrayUtils.appendInt(users, userId); invalidateIsUserUnlockedCache(); } public void remove(int userId) { users = ArrayUtils.removeInt(users, userId); invalidateIsUserUnlockedCache(); } public boolean contains(int userId) { return ArrayUtils.contains(users, userId); } public int[] all() { return users; } @Override public String toString() { return Arrays.toString(users); } private void invalidateIsUserUnlockedCache() { UserManager.invalidateIsUserUnlockedCache(); } } /** Set of users that we know are unlocked. */ @GuardedBy("mLock") private int[] mLocalUnlockedUsers = EmptyArray.INT; private WatchedLockedUsers mLocalUnlockedUsers = new WatchedLockedUsers(); /** Set of users that system knows are unlocked. */ @GuardedBy("mLock") private int[] mSystemUnlockedUsers = EmptyArray.INT; Loading Loading @@ -3042,7 +3076,7 @@ class StorageManagerService extends IStorageManager.Stub } synchronized (mLock) { mLocalUnlockedUsers = ArrayUtils.appendInt(mLocalUnlockedUsers, userId); mLocalUnlockedUsers.append(userId); } } Loading @@ -3058,14 +3092,14 @@ class StorageManagerService extends IStorageManager.Stub } synchronized (mLock) { mLocalUnlockedUsers = ArrayUtils.removeInt(mLocalUnlockedUsers, userId); mLocalUnlockedUsers.remove(userId); } } @Override public boolean isUserKeyUnlocked(int userId) { synchronized (mLock) { return ArrayUtils.contains(mLocalUnlockedUsers, userId); return mLocalUnlockedUsers.contains(userId); } } Loading Loading @@ -4177,7 +4211,7 @@ class StorageManagerService extends IStorageManager.Stub } pw.println(); pw.println("Local unlocked users: " + Arrays.toString(mLocalUnlockedUsers)); pw.println("Local unlocked users: " + mLocalUnlockedUsers); pw.println("System unlocked users: " + Arrays.toString(mSystemUnlockedUsers)); final ContentResolver cr = mContext.getContentResolver(); Loading
services/core/java/com/android/server/pm/UserManagerService.java +40 −1 Original line number Diff line number Diff line Loading @@ -462,8 +462,42 @@ public class UserManagerService extends IUserManager.Stub { @GuardedBy("mUsersLock") private boolean mForceEphemeralUsers; /** * The member mUserStates affects the return value of isUserUnlocked. * If any value in mUserStates changes, then the binder cache for * isUserUnlocked must be invalidated. When adding mutating methods to * WatchedUserStates, be sure to invalidate the cache in the new * methods. */ private class WatchedUserStates { final SparseIntArray states; public WatchedUserStates() { states = new SparseIntArray(); } public int get(int userId) { return states.get(userId); } public int get(int userId, int fallback) { return states.indexOfKey(userId) >= 0 ? states.get(userId) : fallback; } public void put(int userId, int state) { states.put(userId, state); invalidateIsUserUnlockedCache(); } public void delete(int userId) { states.delete(userId); invalidateIsUserUnlockedCache(); } @Override public String toString() { return states.toString(); } private void invalidateIsUserUnlockedCache() { UserManager.invalidateIsUserUnlockedCache(); } } @GuardedBy("mUserStates") private final SparseIntArray mUserStates = new SparseIntArray(); private final WatchedUserStates mUserStates = new WatchedUserStates(); private static UserManagerService sInstance; Loading Loading @@ -4801,6 +4835,11 @@ public class UserManagerService extends IUserManager.Stub { || (state == UserState.STATE_RUNNING_UNLOCKED); } /** * The return values of this method are cached in clients. If the * logic in this function changes then the cache invalidation code * may need to be revisited. */ @Override public boolean isUserUnlocked(@UserIdInt int userId) { int state; Loading