Loading core/proto/android/server/activitymanagerservice.proto +2 −3 Original line number Diff line number Diff line Loading @@ -977,12 +977,11 @@ message UserControllerProto { optional int32 profile = 2; } repeated UserProfile user_profile_group_ids = 4; repeated int32 visible_users_array = 5; // current_user contains the id of the current user, while current_profiles contains the ids of // both the current user and its profiles (if any) optional int32 current_user = 6; repeated int32 current_profiles = 7; optional int32 current_user = 5; repeated int32 current_profiles = 6; } // sync with com.android.server.am.AppTimeTracker.java Loading services/core/java/com/android/server/am/UserController.java +13 −127 Original line number Diff line number Diff line Loading @@ -100,7 +100,6 @@ import android.util.EventLog; import android.util.IntArray; import android.util.Pair; import android.util.SparseArray; import android.util.SparseBooleanArray; import android.util.SparseIntArray; import android.util.proto.ProtoOutputStream; import android.view.Display; Loading Loading @@ -177,7 +176,8 @@ class UserController implements Handler.Callback { static final int START_USER_SWITCH_FG_MSG = 120; static final int COMPLETE_USER_SWITCH_MSG = 130; static final int USER_COMPLETED_EVENT_MSG = 140; static final int USER_VISIBILITY_CHANGED_MSG = 150; private static final int NO_ARG2 = 0; // Message constant to clear {@link UserJourneySession} from {@link mUserIdToUserJourneyMap} if // the user journey, defined in the UserLifecycleJourneyReported atom for statsd, is not Loading Loading @@ -437,20 +437,6 @@ class UserController implements Handler.Callback { /** @see #getLastUserUnlockingUptime */ private volatile long mLastUserUnlockingUptime = 0; // TODO(b/244333150) remove this array and let UserVisibilityMediator call the listeners // directly, as that class should be responsible for all user visibility logic (for example, // when the foreground user is switched out, its profiles also become invisible) /** * List of visible users (as defined by {@link UserManager#isUserVisible()}). * * <p>It's only used to call {@link UserManagerInternal} when the visibility is changed upon * the user starting or stopping. * * <p>Note: only the key is used, not the value. */ @GuardedBy("mLock") private final SparseBooleanArray mVisibleUsers = new SparseBooleanArray(); private final UserLifecycleListener mUserLifecycleListener = new UserLifecycleListener() { @Override public void onUserCreated(UserInfo user, Object token) { Loading Loading @@ -1092,24 +1078,11 @@ class UserController implements Handler.Callback { // instead. userManagerInternal.unassignUserFromDisplayOnStop(userId); final boolean visibilityChanged; boolean visibleBefore; synchronized (mLock) { visibleBefore = mVisibleUsers.get(userId); if (visibleBefore) { deleteVisibleUserLocked(userId); visibilityChanged = true; } else { visibilityChanged = false; } } updateStartedUserArrayLU(); final boolean allowDelayedLockingCopied = allowDelayedLocking; Runnable finishUserStoppingAsync = () -> mHandler.post(() -> finishUserStopping(userId, uss, allowDelayedLockingCopied, visibilityChanged)); mHandler.post(() -> finishUserStopping(userId, uss, allowDelayedLockingCopied)); if (mInjector.getUserManager().isPreCreated(userId)) { finishUserStoppingAsync.run(); Loading Loading @@ -1146,22 +1119,8 @@ class UserController implements Handler.Callback { } } private void addVisibleUserLocked(@UserIdInt int userId) { if (DEBUG_MU) { Slogf.d(TAG, "adding %d to mVisibleUsers", userId); } mVisibleUsers.put(userId, true); } private void deleteVisibleUserLocked(@UserIdInt int userId) { if (DEBUG_MU) { Slogf.d(TAG, "deleting %d from mVisibleUsers", userId); } mVisibleUsers.delete(userId); } private void finishUserStopping(final int userId, final UserState uss, final boolean allowDelayedLocking, final boolean visibilityChanged) { final boolean allowDelayedLocking) { EventLog.writeEvent(EventLogTags.UC_FINISH_USER_STOPPING, userId); synchronized (mLock) { if (uss.state != UserState.STATE_STOPPING) { Loading @@ -1179,9 +1138,6 @@ class UserController implements Handler.Callback { BatteryStats.HistoryItem.EVENT_USER_RUNNING_FINISH, Integer.toString(userId), userId); mInjector.getSystemServiceManager().onUserStopping(userId); if (visibilityChanged) { mInjector.onUserVisibilityChanged(userId, /* visible= */ false); } Runnable finishUserStoppedAsync = () -> mHandler.post(() -> finishUserStopped(uss, allowDelayedLocking)); Loading Loading @@ -1655,25 +1611,13 @@ class UserController implements Handler.Callback { userInfo.profileGroupId, foreground, displayId); t.traceEnd(); boolean visible; switch (result) { case UserManagerInternal.USER_ASSIGNMENT_RESULT_SUCCESS_VISIBLE: visible = true; break; case UserManagerInternal.USER_ASSIGNMENT_RESULT_SUCCESS_INVISIBLE: visible = false; break; default: Slogf.wtf(TAG, "Wrong result from assignUserToDisplayOnStart(): %d", result); // Fall through case UserManagerInternal.USER_ASSIGNMENT_RESULT_FAILURE: if (result == UserManagerInternal.USER_ASSIGNMENT_RESULT_FAILURE) { Slogf.e(TAG, "%s user(%d) / display (%d) assignment failed: %s", (foreground ? "fg" : "bg"), userId, displayId, UserManagerInternal.userAssignmentResultToString(result)); return false; } // TODO(b/239982558): might need something similar for bg users on secondary display if (foreground && isUserSwitchUiEnabled()) { t.traceBegin("startFreezingScreen"); Loading Loading @@ -1724,15 +1668,7 @@ class UserController implements Handler.Callback { // Make sure the old user is no longer considering the display to be on. mInjector.reportGlobalUsageEvent(UsageEvents.Event.SCREEN_NON_INTERACTIVE); boolean userSwitchUiEnabled; // TODO(b/244333150): temporary state until the callback logic is moved to // UserVisibilityManager int previousCurrentUserId; boolean notifyPreviousCurrentUserId; synchronized (mLock) { previousCurrentUserId = mCurrentUserId; notifyPreviousCurrentUserId = mVisibleUsers.get(previousCurrentUserId); if (notifyPreviousCurrentUserId) { deleteVisibleUserLocked(previousCurrentUserId); } mCurrentUserId = userId; mTargetUserId = UserHandle.USER_NULL; // reset, mCurrentUserId has caught up userSwitchUiEnabled = mUserSwitchUiEnabled; Loading @@ -1753,10 +1689,6 @@ class UserController implements Handler.Callback { mInjector.getWindowManager().lockNow(null); } } if (notifyPreviousCurrentUserId) { mHandler.sendMessage(mHandler.obtainMessage(USER_VISIBILITY_CHANGED_MSG, previousCurrentUserId, 0)); } } else { final Integer currentUserIdInt = mCurrentUserId; Loading @@ -1768,12 +1700,6 @@ class UserController implements Handler.Callback { } t.traceEnd(); if (visible) { synchronized (mLock) { addVisibleUserLocked(userId); } } // Make sure user is in the started state. If it is currently // stopping, we need to knock that off. if (uss.state == UserState.STATE_STOPPING) { Loading Loading @@ -1810,20 +1736,10 @@ class UserController implements Handler.Callback { // Booting up a new user, need to tell system services about it. // Note that this is on the same handler as scheduling of broadcasts, // which is important because it needs to go first. mHandler.sendMessage(mHandler.obtainMessage(USER_START_MSG, userId, visible ? 1 : 0)); mHandler.sendMessage(mHandler.obtainMessage(USER_START_MSG, userId, NO_ARG2)); t.traceEnd(); } if (visible) { // User was already running and became visible (for example, when switching to a // user that was started in the background before), so it's necessary to explicitly // notify the services (while when the user starts from BOOTING, USER_START_MSG // takes care of that. mHandler.sendMessage( mHandler.obtainMessage(USER_VISIBILITY_CHANGED_MSG, userId, 1)); } t.traceBegin("sendMessages"); if (foreground) { mHandler.sendMessage(mHandler.obtainMessage(USER_CURRENT_MSG, userId, oldUserId)); Loading Loading @@ -2248,11 +2164,6 @@ class UserController implements Handler.Callback { uss.switching = false; stopGuestOrEphemeralUserIfBackground(oldUserId); stopUserOnSwitchIfEnforced(oldUserId); if (oldUserId == UserHandle.USER_SYSTEM) { // System user is never stopped, but its visibility is changed (as it is brought to the // background) updateSystemUserVisibility(t, /* visible= */ false); } t.traceEnd(); // end continueUserSwitch } Loading Loading @@ -2614,27 +2525,10 @@ class UserController implements Handler.Callback { // Don't need to call on HSUM because it will be called when the system user is // restarted on background mInjector.onUserStarting(UserHandle.USER_SYSTEM); mInjector.onUserVisibilityChanged(UserHandle.USER_SYSTEM, /* visible= */ true); mInjector.onSystemUserVisibilityChanged(/* visible= */ true); } } private void updateSystemUserVisibility(TimingsTraceAndSlog t, boolean visible) { t.traceBegin("update-system-userVisibility-" + visible); if (DEBUG_MU) { Slogf.d(TAG, "updateSystemUserVisibility(): visible=%b", visible); } int userId = UserHandle.USER_SYSTEM; synchronized (mLock) { if (visible) { addVisibleUserLocked(userId); } else { deleteVisibleUserLocked(userId); } } mInjector.onUserVisibilityChanged(userId, visible); t.traceEnd(); } /** * Refreshes the internal caches related to user profiles. * Loading Loading @@ -3032,9 +2926,6 @@ class UserController implements Handler.Callback { proto.end(uToken); } } for (int i = 0; i < mVisibleUsers.size(); i++) { proto.write(UserControllerProto.VISIBLE_USERS_ARRAY, mVisibleUsers.keyAt(i)); } proto.write(UserControllerProto.CURRENT_USER, mCurrentUserId); for (int i = 0; i < mCurrentProfileIds.length; i++) { proto.write(UserControllerProto.CURRENT_PROFILES, mCurrentProfileIds[i]); Loading Loading @@ -3094,7 +2985,6 @@ class UserController implements Handler.Callback { pw.println(" mSwitchingToSystemUserMessage: " + mSwitchingToSystemUserMessage); } pw.println(" mLastUserUnlockingUptime: " + mLastUserUnlockingUptime); pw.println(" mVisibleUsers: " + mVisibleUsers); } } Loading Loading @@ -3212,10 +3102,6 @@ class UserController implements Handler.Callback { case COMPLETE_USER_SWITCH_MSG: completeUserSwitch(msg.arg1); break; case USER_VISIBILITY_CHANGED_MSG: mInjector.onUserVisibilityChanged(/* userId= */ msg.arg1, /* visible= */ msg.arg2 == 1); break; } return false; } Loading Loading @@ -3750,8 +3636,8 @@ class UserController implements Handler.Callback { getSystemServiceManager().onUserStarting(TimingsTraceAndSlog.newAsyncLog(), userId); } void onUserVisibilityChanged(@UserIdInt int userId, boolean visible) { getUserManagerInternal().onUserVisibilityChanged(userId, visible); void onSystemUserVisibilityChanged(boolean visible) { getUserManagerInternal().onSystemUserVisibilityChanged(visible); } } } services/core/java/com/android/server/pm/UserManagerInternal.java +4 −2 Original line number Diff line number Diff line Loading @@ -435,8 +435,10 @@ public abstract class UserManagerInternal { /** Removes a {@link UserVisibilityListener}. */ public abstract void removeUserVisibilityListener(UserVisibilityListener listener); /** TODO(b/244333150): temporary method until UserVisibilityMediator handles that logic */ public abstract void onUserVisibilityChanged(@UserIdInt int userId, boolean visible); // TODO(b/242195409): remove this method if not needed anymore /** Notify {@link UserVisibilityListener listeners} that the visibility of the * {@link android.os.UserHandle#USER_SYSTEM} changed. */ public abstract void onSystemUserVisibilityChanged(boolean visible); /** Return the integer types of the given user IDs. Only used for reporting metrics to statsd. */ Loading services/core/java/com/android/server/pm/UserManagerService.java +4 −27 Original line number Diff line number Diff line Loading @@ -97,7 +97,6 @@ import android.text.TextUtils; import android.util.ArrayMap; import android.util.ArraySet; import android.util.AtomicFile; import android.util.EventLog; import android.util.IndentingPrintWriter; import android.util.IntArray; import android.util.Slog; Loading Loading @@ -126,7 +125,6 @@ import com.android.server.BundleUtils; import com.android.server.LocalServices; import com.android.server.LockGuard; import com.android.server.SystemService; import com.android.server.am.EventLogTags; import com.android.server.am.UserState; import com.android.server.pm.UserManagerInternal.UserLifecycleListener; import com.android.server.pm.UserManagerInternal.UserRestrictionsListener; Loading Loading @@ -512,10 +510,6 @@ public class UserManagerService extends IUserManager.Stub { @GuardedBy("mUserLifecycleListeners") private final ArrayList<UserLifecycleListener> mUserLifecycleListeners = new ArrayList<>(); // TODO(b/244333150): temporary array, should belong to UserVisibilityMediator @GuardedBy("mUserVisibilityListeners") private final ArrayList<UserVisibilityListener> mUserVisibilityListeners = new ArrayList<>(); private final LockPatternUtils mLockPatternUtils; private final String ACTION_DISABLE_QUIET_MODE_AFTER_UNLOCK = Loading Loading @@ -6383,9 +6377,6 @@ public class UserManagerService extends IUserManager.Stub { synchronized (mUserLifecycleListeners) { pw.println(" user lifecycle events: " + mUserLifecycleListeners.size()); } synchronized (mUserVisibilityListeners) { pw.println(" user visibility events: " + mUserVisibilityListeners.size()); } // Dump UserTypes pw.println(); Loading Loading @@ -6961,31 +6952,17 @@ public class UserManagerService extends IUserManager.Stub { @Override public void addUserVisibilityListener(UserVisibilityListener listener) { synchronized (mUserVisibilityListeners) { mUserVisibilityListeners.add(listener); } mUserVisibilityMediator.addListener(listener); } @Override public void removeUserVisibilityListener(UserVisibilityListener listener) { synchronized (mUserVisibilityListeners) { mUserVisibilityListeners.remove(listener); } mUserVisibilityMediator.removeListener(listener); } @Override public void onUserVisibilityChanged(@UserIdInt int userId, boolean visible) { EventLog.writeEvent(EventLogTags.UM_USER_VISIBILITY_CHANGED, userId, visible ? 1 : 0); mHandler.post(() -> { UserVisibilityListener[] listeners; synchronized (mUserVisibilityListeners) { listeners = new UserVisibilityListener[mUserVisibilityListeners.size()]; mUserVisibilityListeners.toArray(listeners); } for (UserVisibilityListener listener : listeners) { listener.onUserVisibilityChanged(userId, visible); } }); public void onSystemUserVisibilityChanged(boolean visible) { mUserVisibilityMediator.onSystemUserVisibilityChanged(visible); } @Override Loading services/core/java/com/android/server/pm/UserVisibilityMediator.java +16 −4 Original line number Diff line number Diff line Loading @@ -32,6 +32,7 @@ import android.os.Handler; import android.os.UserHandle; import android.os.UserManager; import android.util.Dumpable; import android.util.EventLog; import android.util.IndentingPrintWriter; import android.util.IntArray; import android.util.SparseIntArray; Loading @@ -40,6 +41,7 @@ import android.view.Display; import com.android.internal.annotations.GuardedBy; import com.android.internal.annotations.VisibleForTesting; import com.android.internal.util.Preconditions; import com.android.server.am.EventLogTags; import com.android.server.pm.UserManagerInternal.UserAssignmentResult; import com.android.server.pm.UserManagerInternal.UserVisibilityListener; import com.android.server.utils.Slogf; Loading Loading @@ -68,6 +70,7 @@ import java.util.concurrent.CopyOnWriteArrayList; public final class UserVisibilityMediator implements Dumpable { private static final boolean DBG = false; // DO NOT SUBMIT WITH TRUE private static final boolean VERBOSE = false; // DO NOT SUBMIT WITH TRUE private static final String TAG = UserVisibilityMediator.class.getSimpleName(); Loading Loading @@ -381,8 +384,8 @@ public final class UserVisibilityMediator implements Dumpable { public boolean isUserVisible(@UserIdInt int userId) { // First check current foreground user and their profiles (on main display) if (isCurrentUserOrRunningProfileOfCurrentUser(userId)) { if (DBG) { Slogf.d(TAG, "isUserVisible(%d): true to current user or profile", userId); if (VERBOSE) { Slogf.v(TAG, "isUserVisible(%d): true to current user or profile", userId); } return true; } Loading Loading @@ -517,6 +520,14 @@ public final class UserVisibilityMediator implements Dumpable { } } // TODO(b/242195409): remove this method if not needed anymore /** * Nofify all listeners that the system user visibility changed. */ void onSystemUserVisibilityChanged(boolean visible) { dispatchVisibilityChanged(mListeners, USER_SYSTEM, visible); } /** * Nofify all listeners about the visibility changes from before / after a change of state. */ Loading @@ -534,7 +545,7 @@ public final class UserVisibilityMediator implements Dumpable { Slogf.d(TAG, "dispatchVisibilityChanged(): visibleUsersBefore=%s, visibleUsersAfter=%s, " + "%d listeners (%s)", visibleUsersBefore, visibleUsersAfter, listeners.size(), mListeners); listeners); } for (int i = 0; i < visibleUsersBefore.size(); i++) { int userId = visibleUsersBefore.get(i); Loading @@ -552,13 +563,14 @@ public final class UserVisibilityMediator implements Dumpable { private void dispatchVisibilityChanged(CopyOnWriteArrayList<UserVisibilityListener> listeners, @UserIdInt int userId, boolean visible) { EventLog.writeEvent(EventLogTags.UM_USER_VISIBILITY_CHANGED, userId, visible ? 1 : 0); if (DBG) { Slogf.d(TAG, "dispatchVisibilityChanged(%d -> %b): sending to %d listeners", userId, visible, listeners.size()); } for (int i = 0; i < mListeners.size(); i++) { UserVisibilityListener listener = mListeners.get(i); if (DBG) { if (VERBOSE) { Slogf.v(TAG, "dispatchVisibilityChanged(%d -> %b): sending to %s", userId, visible, listener); } Loading Loading
core/proto/android/server/activitymanagerservice.proto +2 −3 Original line number Diff line number Diff line Loading @@ -977,12 +977,11 @@ message UserControllerProto { optional int32 profile = 2; } repeated UserProfile user_profile_group_ids = 4; repeated int32 visible_users_array = 5; // current_user contains the id of the current user, while current_profiles contains the ids of // both the current user and its profiles (if any) optional int32 current_user = 6; repeated int32 current_profiles = 7; optional int32 current_user = 5; repeated int32 current_profiles = 6; } // sync with com.android.server.am.AppTimeTracker.java Loading
services/core/java/com/android/server/am/UserController.java +13 −127 Original line number Diff line number Diff line Loading @@ -100,7 +100,6 @@ import android.util.EventLog; import android.util.IntArray; import android.util.Pair; import android.util.SparseArray; import android.util.SparseBooleanArray; import android.util.SparseIntArray; import android.util.proto.ProtoOutputStream; import android.view.Display; Loading Loading @@ -177,7 +176,8 @@ class UserController implements Handler.Callback { static final int START_USER_SWITCH_FG_MSG = 120; static final int COMPLETE_USER_SWITCH_MSG = 130; static final int USER_COMPLETED_EVENT_MSG = 140; static final int USER_VISIBILITY_CHANGED_MSG = 150; private static final int NO_ARG2 = 0; // Message constant to clear {@link UserJourneySession} from {@link mUserIdToUserJourneyMap} if // the user journey, defined in the UserLifecycleJourneyReported atom for statsd, is not Loading Loading @@ -437,20 +437,6 @@ class UserController implements Handler.Callback { /** @see #getLastUserUnlockingUptime */ private volatile long mLastUserUnlockingUptime = 0; // TODO(b/244333150) remove this array and let UserVisibilityMediator call the listeners // directly, as that class should be responsible for all user visibility logic (for example, // when the foreground user is switched out, its profiles also become invisible) /** * List of visible users (as defined by {@link UserManager#isUserVisible()}). * * <p>It's only used to call {@link UserManagerInternal} when the visibility is changed upon * the user starting or stopping. * * <p>Note: only the key is used, not the value. */ @GuardedBy("mLock") private final SparseBooleanArray mVisibleUsers = new SparseBooleanArray(); private final UserLifecycleListener mUserLifecycleListener = new UserLifecycleListener() { @Override public void onUserCreated(UserInfo user, Object token) { Loading Loading @@ -1092,24 +1078,11 @@ class UserController implements Handler.Callback { // instead. userManagerInternal.unassignUserFromDisplayOnStop(userId); final boolean visibilityChanged; boolean visibleBefore; synchronized (mLock) { visibleBefore = mVisibleUsers.get(userId); if (visibleBefore) { deleteVisibleUserLocked(userId); visibilityChanged = true; } else { visibilityChanged = false; } } updateStartedUserArrayLU(); final boolean allowDelayedLockingCopied = allowDelayedLocking; Runnable finishUserStoppingAsync = () -> mHandler.post(() -> finishUserStopping(userId, uss, allowDelayedLockingCopied, visibilityChanged)); mHandler.post(() -> finishUserStopping(userId, uss, allowDelayedLockingCopied)); if (mInjector.getUserManager().isPreCreated(userId)) { finishUserStoppingAsync.run(); Loading Loading @@ -1146,22 +1119,8 @@ class UserController implements Handler.Callback { } } private void addVisibleUserLocked(@UserIdInt int userId) { if (DEBUG_MU) { Slogf.d(TAG, "adding %d to mVisibleUsers", userId); } mVisibleUsers.put(userId, true); } private void deleteVisibleUserLocked(@UserIdInt int userId) { if (DEBUG_MU) { Slogf.d(TAG, "deleting %d from mVisibleUsers", userId); } mVisibleUsers.delete(userId); } private void finishUserStopping(final int userId, final UserState uss, final boolean allowDelayedLocking, final boolean visibilityChanged) { final boolean allowDelayedLocking) { EventLog.writeEvent(EventLogTags.UC_FINISH_USER_STOPPING, userId); synchronized (mLock) { if (uss.state != UserState.STATE_STOPPING) { Loading @@ -1179,9 +1138,6 @@ class UserController implements Handler.Callback { BatteryStats.HistoryItem.EVENT_USER_RUNNING_FINISH, Integer.toString(userId), userId); mInjector.getSystemServiceManager().onUserStopping(userId); if (visibilityChanged) { mInjector.onUserVisibilityChanged(userId, /* visible= */ false); } Runnable finishUserStoppedAsync = () -> mHandler.post(() -> finishUserStopped(uss, allowDelayedLocking)); Loading Loading @@ -1655,25 +1611,13 @@ class UserController implements Handler.Callback { userInfo.profileGroupId, foreground, displayId); t.traceEnd(); boolean visible; switch (result) { case UserManagerInternal.USER_ASSIGNMENT_RESULT_SUCCESS_VISIBLE: visible = true; break; case UserManagerInternal.USER_ASSIGNMENT_RESULT_SUCCESS_INVISIBLE: visible = false; break; default: Slogf.wtf(TAG, "Wrong result from assignUserToDisplayOnStart(): %d", result); // Fall through case UserManagerInternal.USER_ASSIGNMENT_RESULT_FAILURE: if (result == UserManagerInternal.USER_ASSIGNMENT_RESULT_FAILURE) { Slogf.e(TAG, "%s user(%d) / display (%d) assignment failed: %s", (foreground ? "fg" : "bg"), userId, displayId, UserManagerInternal.userAssignmentResultToString(result)); return false; } // TODO(b/239982558): might need something similar for bg users on secondary display if (foreground && isUserSwitchUiEnabled()) { t.traceBegin("startFreezingScreen"); Loading Loading @@ -1724,15 +1668,7 @@ class UserController implements Handler.Callback { // Make sure the old user is no longer considering the display to be on. mInjector.reportGlobalUsageEvent(UsageEvents.Event.SCREEN_NON_INTERACTIVE); boolean userSwitchUiEnabled; // TODO(b/244333150): temporary state until the callback logic is moved to // UserVisibilityManager int previousCurrentUserId; boolean notifyPreviousCurrentUserId; synchronized (mLock) { previousCurrentUserId = mCurrentUserId; notifyPreviousCurrentUserId = mVisibleUsers.get(previousCurrentUserId); if (notifyPreviousCurrentUserId) { deleteVisibleUserLocked(previousCurrentUserId); } mCurrentUserId = userId; mTargetUserId = UserHandle.USER_NULL; // reset, mCurrentUserId has caught up userSwitchUiEnabled = mUserSwitchUiEnabled; Loading @@ -1753,10 +1689,6 @@ class UserController implements Handler.Callback { mInjector.getWindowManager().lockNow(null); } } if (notifyPreviousCurrentUserId) { mHandler.sendMessage(mHandler.obtainMessage(USER_VISIBILITY_CHANGED_MSG, previousCurrentUserId, 0)); } } else { final Integer currentUserIdInt = mCurrentUserId; Loading @@ -1768,12 +1700,6 @@ class UserController implements Handler.Callback { } t.traceEnd(); if (visible) { synchronized (mLock) { addVisibleUserLocked(userId); } } // Make sure user is in the started state. If it is currently // stopping, we need to knock that off. if (uss.state == UserState.STATE_STOPPING) { Loading Loading @@ -1810,20 +1736,10 @@ class UserController implements Handler.Callback { // Booting up a new user, need to tell system services about it. // Note that this is on the same handler as scheduling of broadcasts, // which is important because it needs to go first. mHandler.sendMessage(mHandler.obtainMessage(USER_START_MSG, userId, visible ? 1 : 0)); mHandler.sendMessage(mHandler.obtainMessage(USER_START_MSG, userId, NO_ARG2)); t.traceEnd(); } if (visible) { // User was already running and became visible (for example, when switching to a // user that was started in the background before), so it's necessary to explicitly // notify the services (while when the user starts from BOOTING, USER_START_MSG // takes care of that. mHandler.sendMessage( mHandler.obtainMessage(USER_VISIBILITY_CHANGED_MSG, userId, 1)); } t.traceBegin("sendMessages"); if (foreground) { mHandler.sendMessage(mHandler.obtainMessage(USER_CURRENT_MSG, userId, oldUserId)); Loading Loading @@ -2248,11 +2164,6 @@ class UserController implements Handler.Callback { uss.switching = false; stopGuestOrEphemeralUserIfBackground(oldUserId); stopUserOnSwitchIfEnforced(oldUserId); if (oldUserId == UserHandle.USER_SYSTEM) { // System user is never stopped, but its visibility is changed (as it is brought to the // background) updateSystemUserVisibility(t, /* visible= */ false); } t.traceEnd(); // end continueUserSwitch } Loading Loading @@ -2614,27 +2525,10 @@ class UserController implements Handler.Callback { // Don't need to call on HSUM because it will be called when the system user is // restarted on background mInjector.onUserStarting(UserHandle.USER_SYSTEM); mInjector.onUserVisibilityChanged(UserHandle.USER_SYSTEM, /* visible= */ true); mInjector.onSystemUserVisibilityChanged(/* visible= */ true); } } private void updateSystemUserVisibility(TimingsTraceAndSlog t, boolean visible) { t.traceBegin("update-system-userVisibility-" + visible); if (DEBUG_MU) { Slogf.d(TAG, "updateSystemUserVisibility(): visible=%b", visible); } int userId = UserHandle.USER_SYSTEM; synchronized (mLock) { if (visible) { addVisibleUserLocked(userId); } else { deleteVisibleUserLocked(userId); } } mInjector.onUserVisibilityChanged(userId, visible); t.traceEnd(); } /** * Refreshes the internal caches related to user profiles. * Loading Loading @@ -3032,9 +2926,6 @@ class UserController implements Handler.Callback { proto.end(uToken); } } for (int i = 0; i < mVisibleUsers.size(); i++) { proto.write(UserControllerProto.VISIBLE_USERS_ARRAY, mVisibleUsers.keyAt(i)); } proto.write(UserControllerProto.CURRENT_USER, mCurrentUserId); for (int i = 0; i < mCurrentProfileIds.length; i++) { proto.write(UserControllerProto.CURRENT_PROFILES, mCurrentProfileIds[i]); Loading Loading @@ -3094,7 +2985,6 @@ class UserController implements Handler.Callback { pw.println(" mSwitchingToSystemUserMessage: " + mSwitchingToSystemUserMessage); } pw.println(" mLastUserUnlockingUptime: " + mLastUserUnlockingUptime); pw.println(" mVisibleUsers: " + mVisibleUsers); } } Loading Loading @@ -3212,10 +3102,6 @@ class UserController implements Handler.Callback { case COMPLETE_USER_SWITCH_MSG: completeUserSwitch(msg.arg1); break; case USER_VISIBILITY_CHANGED_MSG: mInjector.onUserVisibilityChanged(/* userId= */ msg.arg1, /* visible= */ msg.arg2 == 1); break; } return false; } Loading Loading @@ -3750,8 +3636,8 @@ class UserController implements Handler.Callback { getSystemServiceManager().onUserStarting(TimingsTraceAndSlog.newAsyncLog(), userId); } void onUserVisibilityChanged(@UserIdInt int userId, boolean visible) { getUserManagerInternal().onUserVisibilityChanged(userId, visible); void onSystemUserVisibilityChanged(boolean visible) { getUserManagerInternal().onSystemUserVisibilityChanged(visible); } } }
services/core/java/com/android/server/pm/UserManagerInternal.java +4 −2 Original line number Diff line number Diff line Loading @@ -435,8 +435,10 @@ public abstract class UserManagerInternal { /** Removes a {@link UserVisibilityListener}. */ public abstract void removeUserVisibilityListener(UserVisibilityListener listener); /** TODO(b/244333150): temporary method until UserVisibilityMediator handles that logic */ public abstract void onUserVisibilityChanged(@UserIdInt int userId, boolean visible); // TODO(b/242195409): remove this method if not needed anymore /** Notify {@link UserVisibilityListener listeners} that the visibility of the * {@link android.os.UserHandle#USER_SYSTEM} changed. */ public abstract void onSystemUserVisibilityChanged(boolean visible); /** Return the integer types of the given user IDs. Only used for reporting metrics to statsd. */ Loading
services/core/java/com/android/server/pm/UserManagerService.java +4 −27 Original line number Diff line number Diff line Loading @@ -97,7 +97,6 @@ import android.text.TextUtils; import android.util.ArrayMap; import android.util.ArraySet; import android.util.AtomicFile; import android.util.EventLog; import android.util.IndentingPrintWriter; import android.util.IntArray; import android.util.Slog; Loading Loading @@ -126,7 +125,6 @@ import com.android.server.BundleUtils; import com.android.server.LocalServices; import com.android.server.LockGuard; import com.android.server.SystemService; import com.android.server.am.EventLogTags; import com.android.server.am.UserState; import com.android.server.pm.UserManagerInternal.UserLifecycleListener; import com.android.server.pm.UserManagerInternal.UserRestrictionsListener; Loading Loading @@ -512,10 +510,6 @@ public class UserManagerService extends IUserManager.Stub { @GuardedBy("mUserLifecycleListeners") private final ArrayList<UserLifecycleListener> mUserLifecycleListeners = new ArrayList<>(); // TODO(b/244333150): temporary array, should belong to UserVisibilityMediator @GuardedBy("mUserVisibilityListeners") private final ArrayList<UserVisibilityListener> mUserVisibilityListeners = new ArrayList<>(); private final LockPatternUtils mLockPatternUtils; private final String ACTION_DISABLE_QUIET_MODE_AFTER_UNLOCK = Loading Loading @@ -6383,9 +6377,6 @@ public class UserManagerService extends IUserManager.Stub { synchronized (mUserLifecycleListeners) { pw.println(" user lifecycle events: " + mUserLifecycleListeners.size()); } synchronized (mUserVisibilityListeners) { pw.println(" user visibility events: " + mUserVisibilityListeners.size()); } // Dump UserTypes pw.println(); Loading Loading @@ -6961,31 +6952,17 @@ public class UserManagerService extends IUserManager.Stub { @Override public void addUserVisibilityListener(UserVisibilityListener listener) { synchronized (mUserVisibilityListeners) { mUserVisibilityListeners.add(listener); } mUserVisibilityMediator.addListener(listener); } @Override public void removeUserVisibilityListener(UserVisibilityListener listener) { synchronized (mUserVisibilityListeners) { mUserVisibilityListeners.remove(listener); } mUserVisibilityMediator.removeListener(listener); } @Override public void onUserVisibilityChanged(@UserIdInt int userId, boolean visible) { EventLog.writeEvent(EventLogTags.UM_USER_VISIBILITY_CHANGED, userId, visible ? 1 : 0); mHandler.post(() -> { UserVisibilityListener[] listeners; synchronized (mUserVisibilityListeners) { listeners = new UserVisibilityListener[mUserVisibilityListeners.size()]; mUserVisibilityListeners.toArray(listeners); } for (UserVisibilityListener listener : listeners) { listener.onUserVisibilityChanged(userId, visible); } }); public void onSystemUserVisibilityChanged(boolean visible) { mUserVisibilityMediator.onSystemUserVisibilityChanged(visible); } @Override Loading
services/core/java/com/android/server/pm/UserVisibilityMediator.java +16 −4 Original line number Diff line number Diff line Loading @@ -32,6 +32,7 @@ import android.os.Handler; import android.os.UserHandle; import android.os.UserManager; import android.util.Dumpable; import android.util.EventLog; import android.util.IndentingPrintWriter; import android.util.IntArray; import android.util.SparseIntArray; Loading @@ -40,6 +41,7 @@ import android.view.Display; import com.android.internal.annotations.GuardedBy; import com.android.internal.annotations.VisibleForTesting; import com.android.internal.util.Preconditions; import com.android.server.am.EventLogTags; import com.android.server.pm.UserManagerInternal.UserAssignmentResult; import com.android.server.pm.UserManagerInternal.UserVisibilityListener; import com.android.server.utils.Slogf; Loading Loading @@ -68,6 +70,7 @@ import java.util.concurrent.CopyOnWriteArrayList; public final class UserVisibilityMediator implements Dumpable { private static final boolean DBG = false; // DO NOT SUBMIT WITH TRUE private static final boolean VERBOSE = false; // DO NOT SUBMIT WITH TRUE private static final String TAG = UserVisibilityMediator.class.getSimpleName(); Loading Loading @@ -381,8 +384,8 @@ public final class UserVisibilityMediator implements Dumpable { public boolean isUserVisible(@UserIdInt int userId) { // First check current foreground user and their profiles (on main display) if (isCurrentUserOrRunningProfileOfCurrentUser(userId)) { if (DBG) { Slogf.d(TAG, "isUserVisible(%d): true to current user or profile", userId); if (VERBOSE) { Slogf.v(TAG, "isUserVisible(%d): true to current user or profile", userId); } return true; } Loading Loading @@ -517,6 +520,14 @@ public final class UserVisibilityMediator implements Dumpable { } } // TODO(b/242195409): remove this method if not needed anymore /** * Nofify all listeners that the system user visibility changed. */ void onSystemUserVisibilityChanged(boolean visible) { dispatchVisibilityChanged(mListeners, USER_SYSTEM, visible); } /** * Nofify all listeners about the visibility changes from before / after a change of state. */ Loading @@ -534,7 +545,7 @@ public final class UserVisibilityMediator implements Dumpable { Slogf.d(TAG, "dispatchVisibilityChanged(): visibleUsersBefore=%s, visibleUsersAfter=%s, " + "%d listeners (%s)", visibleUsersBefore, visibleUsersAfter, listeners.size(), mListeners); listeners); } for (int i = 0; i < visibleUsersBefore.size(); i++) { int userId = visibleUsersBefore.get(i); Loading @@ -552,13 +563,14 @@ public final class UserVisibilityMediator implements Dumpable { private void dispatchVisibilityChanged(CopyOnWriteArrayList<UserVisibilityListener> listeners, @UserIdInt int userId, boolean visible) { EventLog.writeEvent(EventLogTags.UM_USER_VISIBILITY_CHANGED, userId, visible ? 1 : 0); if (DBG) { Slogf.d(TAG, "dispatchVisibilityChanged(%d -> %b): sending to %d listeners", userId, visible, listeners.size()); } for (int i = 0; i < mListeners.size(); i++) { UserVisibilityListener listener = mListeners.get(i); if (DBG) { if (VERBOSE) { Slogf.v(TAG, "dispatchVisibilityChanged(%d -> %b): sending to %s", userId, visible, listener); } Loading