Loading core/java/android/app/ActivityManager.java +40 −5 Original line number Diff line number Diff line Loading @@ -66,6 +66,7 @@ import android.os.Bundle; import android.os.Debug; import android.os.Handler; import android.os.IBinder; import android.os.IpcDataCache; import android.os.LocaleList; import android.os.Parcel; import android.os.Parcelable; Loading Loading @@ -237,6 +238,44 @@ public class ActivityManager { private static final RateLimitingCache<List<ProcessErrorStateInfo>> mErrorProcessesCache = new RateLimitingCache<>(10, 2); /** * Query handler for mGetCurrentUserIdCache - returns a cached value of the current foreground * user id if the backstage_power/android.app.cache_get_current_user_id flag is enabled. */ private static final IpcDataCache.QueryHandler<Void, Integer> mGetCurrentUserIdQuery = new IpcDataCache.QueryHandler<>() { @Override public Integer apply(Void query) { try { return getService().getCurrentUserId(); } catch (RemoteException e) { throw e.rethrowFromSystemServer(); } } @Override public boolean shouldBypassCache(Void query) { // If the flag to enable the new caching behavior is off, bypass the cache. return !Flags.cacheGetCurrentUserId(); } }; /** A cache which maintains the current foreground user id. */ private static final IpcDataCache<Void, Integer> mGetCurrentUserIdCache = new IpcDataCache<>(1, IpcDataCache.MODULE_SYSTEM, /* api= */ "getCurrentUserId", /* cacheName= */ "CurrentUserIdCache", mGetCurrentUserIdQuery); /** * The current foreground user has changed - invalidate the cache. Currently only called from * UserController when a user switch occurs. * @hide */ public static void invalidateGetCurrentUserIdCache() { IpcDataCache.invalidateCache( IpcDataCache.MODULE_SYSTEM, /* api= */ "getCurrentUserId"); } /** * Map of callbacks that have registered for {@link UidFrozenStateChanged} events. * Will be called when a Uid has become frozen or unfrozen. Loading Loading @@ -5244,11 +5283,7 @@ public class ActivityManager { }) @android.ravenwood.annotation.RavenwoodReplace public static int getCurrentUser() { try { return getService().getCurrentUserId(); } catch (RemoteException e) { throw e.rethrowFromSystemServer(); } return mGetCurrentUserIdCache.query(null); } /** @hide */ Loading core/java/android/app/activity_manager.aconfig +10 −0 Original line number Diff line number Diff line Loading @@ -104,3 +104,13 @@ flag { } } flag { namespace: "backstage_power" name: "cache_get_current_user_id" description: "Add caching for getCurrentUserId" is_fixed_read_only: true bug: "361853873" metadata { purpose: PURPOSE_BUGFIX } } services/core/java/com/android/server/am/UserController.java +9 −0 Original line number Diff line number Diff line Loading @@ -1978,6 +1978,7 @@ class UserController implements Handler.Callback { boolean userSwitchUiEnabled; synchronized (mLock) { mCurrentUserId = userId; ActivityManager.invalidateGetCurrentUserIdCache(); userSwitchUiEnabled = mUserSwitchUiEnabled; } mInjector.updateUserConfiguration(); Loading Loading @@ -2239,6 +2240,7 @@ class UserController implements Handler.Callback { return true; } mTargetUserId = targetUserId; ActivityManager.invalidateGetCurrentUserIdCache(); userSwitchUiEnabled = mUserSwitchUiEnabled; } if (userSwitchUiEnabled) { Loading Loading @@ -2316,6 +2318,7 @@ class UserController implements Handler.Callback { synchronized (mLock) { nextUserId = ObjectUtils.getOrElse(mPendingTargetUserIds.poll(), UserHandle.USER_NULL); mTargetUserId = UserHandle.USER_NULL; ActivityManager.invalidateGetCurrentUserIdCache(); } if (nextUserId != UserHandle.USER_NULL) { switchUser(nextUserId); Loading Loading @@ -3021,6 +3024,9 @@ class UserController implements Handler.Callback { mInjector.getUserManagerInternal().addUserLifecycleListener(mUserLifecycleListener); updateProfileRelatedCaches(); mInjector.reportCurWakefulnessUsageEvent(); // IpcDataCache must be invalidated before it starts caching. ActivityManager.invalidateGetCurrentUserIdCache(); } // TODO(b/266158156): remove this method if initial system user boot logic is refactored? Loading Loading @@ -3184,6 +3190,9 @@ class UserController implements Handler.Callback { @GuardedBy("mLock") private int getCurrentOrTargetUserIdLU() { // Note: this result is currently cached by ActivityManager.getCurrentUser() - changes to // the logic here may require updating how the cache is invalidated. // See ActivityManager.invalidateGetCurrentUserIdCache() for more details. return mTargetUserId != UserHandle.USER_NULL ? mTargetUserId : mCurrentUserId; } Loading services/tests/servicestests/src/com/android/server/am/UserControllerTest.java +4 −0 Original line number Diff line number Diff line Loading @@ -90,6 +90,7 @@ import android.os.Bundle; import android.os.Handler; import android.os.HandlerThread; import android.os.IRemoteCallback; import android.os.IpcDataCache; import android.os.Looper; import android.os.Message; import android.os.PowerManagerInternal; Loading Loading @@ -197,6 +198,9 @@ public class UserControllerTest { @Before public void setUp() throws Exception { runWithDexmakerShareClassLoader(() -> { // Disable binder caches in this process. IpcDataCache.disableForTestMode(); mInjector = spy(new TestInjector(getInstrumentation().getTargetContext())); doNothing().when(mInjector).clearAllLockedTasks(anyString()); doNothing().when(mInjector).startHomeActivity(anyInt(), anyString()); Loading services/tests/servicestests/src/com/android/server/pm/UserManagerTest.java +4 −0 Original line number Diff line number Diff line Loading @@ -34,6 +34,7 @@ import android.content.pm.UserProperties; import android.content.res.Resources; import android.graphics.drawable.Drawable; import android.os.Bundle; import android.os.IpcDataCache; import android.os.PersistableBundle; import android.os.UserHandle; import android.os.UserManager; Loading Loading @@ -100,6 +101,9 @@ public final class UserManagerTest { @Before public void setUp() throws Exception { // Disable binder caches in this process. IpcDataCache.disableForTestMode(); mOriginalCurrentUserId = ActivityManager.getCurrentUser(); mUserManager = UserManager.get(mContext); mActivityManager = mContext.getSystemService(ActivityManager.class); Loading Loading
core/java/android/app/ActivityManager.java +40 −5 Original line number Diff line number Diff line Loading @@ -66,6 +66,7 @@ import android.os.Bundle; import android.os.Debug; import android.os.Handler; import android.os.IBinder; import android.os.IpcDataCache; import android.os.LocaleList; import android.os.Parcel; import android.os.Parcelable; Loading Loading @@ -237,6 +238,44 @@ public class ActivityManager { private static final RateLimitingCache<List<ProcessErrorStateInfo>> mErrorProcessesCache = new RateLimitingCache<>(10, 2); /** * Query handler for mGetCurrentUserIdCache - returns a cached value of the current foreground * user id if the backstage_power/android.app.cache_get_current_user_id flag is enabled. */ private static final IpcDataCache.QueryHandler<Void, Integer> mGetCurrentUserIdQuery = new IpcDataCache.QueryHandler<>() { @Override public Integer apply(Void query) { try { return getService().getCurrentUserId(); } catch (RemoteException e) { throw e.rethrowFromSystemServer(); } } @Override public boolean shouldBypassCache(Void query) { // If the flag to enable the new caching behavior is off, bypass the cache. return !Flags.cacheGetCurrentUserId(); } }; /** A cache which maintains the current foreground user id. */ private static final IpcDataCache<Void, Integer> mGetCurrentUserIdCache = new IpcDataCache<>(1, IpcDataCache.MODULE_SYSTEM, /* api= */ "getCurrentUserId", /* cacheName= */ "CurrentUserIdCache", mGetCurrentUserIdQuery); /** * The current foreground user has changed - invalidate the cache. Currently only called from * UserController when a user switch occurs. * @hide */ public static void invalidateGetCurrentUserIdCache() { IpcDataCache.invalidateCache( IpcDataCache.MODULE_SYSTEM, /* api= */ "getCurrentUserId"); } /** * Map of callbacks that have registered for {@link UidFrozenStateChanged} events. * Will be called when a Uid has become frozen or unfrozen. Loading Loading @@ -5244,11 +5283,7 @@ public class ActivityManager { }) @android.ravenwood.annotation.RavenwoodReplace public static int getCurrentUser() { try { return getService().getCurrentUserId(); } catch (RemoteException e) { throw e.rethrowFromSystemServer(); } return mGetCurrentUserIdCache.query(null); } /** @hide */ Loading
core/java/android/app/activity_manager.aconfig +10 −0 Original line number Diff line number Diff line Loading @@ -104,3 +104,13 @@ flag { } } flag { namespace: "backstage_power" name: "cache_get_current_user_id" description: "Add caching for getCurrentUserId" is_fixed_read_only: true bug: "361853873" metadata { purpose: PURPOSE_BUGFIX } }
services/core/java/com/android/server/am/UserController.java +9 −0 Original line number Diff line number Diff line Loading @@ -1978,6 +1978,7 @@ class UserController implements Handler.Callback { boolean userSwitchUiEnabled; synchronized (mLock) { mCurrentUserId = userId; ActivityManager.invalidateGetCurrentUserIdCache(); userSwitchUiEnabled = mUserSwitchUiEnabled; } mInjector.updateUserConfiguration(); Loading Loading @@ -2239,6 +2240,7 @@ class UserController implements Handler.Callback { return true; } mTargetUserId = targetUserId; ActivityManager.invalidateGetCurrentUserIdCache(); userSwitchUiEnabled = mUserSwitchUiEnabled; } if (userSwitchUiEnabled) { Loading Loading @@ -2316,6 +2318,7 @@ class UserController implements Handler.Callback { synchronized (mLock) { nextUserId = ObjectUtils.getOrElse(mPendingTargetUserIds.poll(), UserHandle.USER_NULL); mTargetUserId = UserHandle.USER_NULL; ActivityManager.invalidateGetCurrentUserIdCache(); } if (nextUserId != UserHandle.USER_NULL) { switchUser(nextUserId); Loading Loading @@ -3021,6 +3024,9 @@ class UserController implements Handler.Callback { mInjector.getUserManagerInternal().addUserLifecycleListener(mUserLifecycleListener); updateProfileRelatedCaches(); mInjector.reportCurWakefulnessUsageEvent(); // IpcDataCache must be invalidated before it starts caching. ActivityManager.invalidateGetCurrentUserIdCache(); } // TODO(b/266158156): remove this method if initial system user boot logic is refactored? Loading Loading @@ -3184,6 +3190,9 @@ class UserController implements Handler.Callback { @GuardedBy("mLock") private int getCurrentOrTargetUserIdLU() { // Note: this result is currently cached by ActivityManager.getCurrentUser() - changes to // the logic here may require updating how the cache is invalidated. // See ActivityManager.invalidateGetCurrentUserIdCache() for more details. return mTargetUserId != UserHandle.USER_NULL ? mTargetUserId : mCurrentUserId; } Loading
services/tests/servicestests/src/com/android/server/am/UserControllerTest.java +4 −0 Original line number Diff line number Diff line Loading @@ -90,6 +90,7 @@ import android.os.Bundle; import android.os.Handler; import android.os.HandlerThread; import android.os.IRemoteCallback; import android.os.IpcDataCache; import android.os.Looper; import android.os.Message; import android.os.PowerManagerInternal; Loading Loading @@ -197,6 +198,9 @@ public class UserControllerTest { @Before public void setUp() throws Exception { runWithDexmakerShareClassLoader(() -> { // Disable binder caches in this process. IpcDataCache.disableForTestMode(); mInjector = spy(new TestInjector(getInstrumentation().getTargetContext())); doNothing().when(mInjector).clearAllLockedTasks(anyString()); doNothing().when(mInjector).startHomeActivity(anyInt(), anyString()); Loading
services/tests/servicestests/src/com/android/server/pm/UserManagerTest.java +4 −0 Original line number Diff line number Diff line Loading @@ -34,6 +34,7 @@ import android.content.pm.UserProperties; import android.content.res.Resources; import android.graphics.drawable.Drawable; import android.os.Bundle; import android.os.IpcDataCache; import android.os.PersistableBundle; import android.os.UserHandle; import android.os.UserManager; Loading Loading @@ -100,6 +101,9 @@ public final class UserManagerTest { @Before public void setUp() throws Exception { // Disable binder caches in this process. IpcDataCache.disableForTestMode(); mOriginalCurrentUserId = ActivityManager.getCurrentUser(); mUserManager = UserManager.get(mContext); mActivityManager = mContext.getSystemService(ActivityManager.class); Loading