Merge "Delegated user visibility changes from UserController to UserVisibilityMediator."
This commit is contained in:
@@ -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
|
||||
|
||||
@@ -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;
|
||||
@@ -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
|
||||
@@ -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) {
|
||||
@@ -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();
|
||||
@@ -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) {
|
||||
@@ -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));
|
||||
@@ -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:
|
||||
Slogf.e(TAG, "%s user(%d) / display (%d) assignment failed: %s",
|
||||
(foreground ? "fg" : "bg"), userId, displayId,
|
||||
UserManagerInternal.userAssignmentResultToString(result));
|
||||
return false;
|
||||
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");
|
||||
@@ -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;
|
||||
@@ -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;
|
||||
@@ -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) {
|
||||
@@ -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));
|
||||
@@ -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
|
||||
}
|
||||
@@ -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.
|
||||
*
|
||||
@@ -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]);
|
||||
@@ -3094,7 +2985,6 @@ class UserController implements Handler.Callback {
|
||||
pw.println(" mSwitchingToSystemUserMessage: " + mSwitchingToSystemUserMessage);
|
||||
}
|
||||
pw.println(" mLastUserUnlockingUptime: " + mLastUserUnlockingUptime);
|
||||
pw.println(" mVisibleUsers: " + mVisibleUsers);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
@@ -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);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -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.
|
||||
*/
|
||||
|
||||
@@ -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;
|
||||
@@ -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;
|
||||
@@ -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 =
|
||||
@@ -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();
|
||||
@@ -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
|
||||
|
||||
@@ -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;
|
||||
@@ -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;
|
||||
@@ -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();
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
@@ -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.
|
||||
*/
|
||||
@@ -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);
|
||||
@@ -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);
|
||||
}
|
||||
|
||||
@@ -30,7 +30,6 @@ import java.util.Collections;
|
||||
import java.util.List;
|
||||
import java.util.concurrent.CountDownLatch;
|
||||
import java.util.concurrent.TimeUnit;
|
||||
|
||||
/**
|
||||
* {@link UserVisibilityListener} implementation that expects callback events to be asynchronously
|
||||
* received.
|
||||
|
||||
@@ -329,6 +329,15 @@ abstract class UserVisibilityMediatorTestCase extends ExtendedMockitoTestCase {
|
||||
listener.verify();
|
||||
}
|
||||
|
||||
@Test
|
||||
public final void testOnSystemUserVisibilityChanged() throws Exception {
|
||||
AsyncUserVisibilityListener listener = addListenerForEvents(onVisible(USER_SYSTEM));
|
||||
|
||||
mMediator.onSystemUserVisibilityChanged(/* visible= */ true);
|
||||
|
||||
listener.verify();
|
||||
}
|
||||
|
||||
/**
|
||||
* Starts a user in foreground on the default display, asserting it was properly started.
|
||||
*
|
||||
|
||||
@@ -38,9 +38,6 @@ import static com.android.server.am.UserController.USER_COMPLETED_EVENT_MSG;
|
||||
import static com.android.server.am.UserController.USER_CURRENT_MSG;
|
||||
import static com.android.server.am.UserController.USER_START_MSG;
|
||||
import static com.android.server.am.UserController.USER_SWITCH_TIMEOUT_MSG;
|
||||
import static com.android.server.am.UserController.USER_VISIBILITY_CHANGED_MSG;
|
||||
import static com.android.server.pm.UserManagerInternal.USER_ASSIGNMENT_RESULT_SUCCESS_INVISIBLE;
|
||||
import static com.android.server.pm.UserManagerInternal.USER_ASSIGNMENT_RESULT_SUCCESS_VISIBLE;
|
||||
|
||||
import static com.google.android.collect.Lists.newArrayList;
|
||||
import static com.google.android.collect.Sets.newHashSet;
|
||||
@@ -102,7 +99,6 @@ import com.android.server.FgThread;
|
||||
import com.android.server.SystemService;
|
||||
import com.android.server.am.UserState.KeyEvictedCallback;
|
||||
import com.android.server.pm.UserManagerInternal;
|
||||
import com.android.server.pm.UserManagerInternal.UserAssignmentResult;
|
||||
import com.android.server.pm.UserManagerService;
|
||||
import com.android.server.wm.WindowManagerService;
|
||||
|
||||
@@ -162,18 +158,12 @@ public class UserControllerTest {
|
||||
REPORT_USER_SWITCH_MSG,
|
||||
USER_SWITCH_TIMEOUT_MSG,
|
||||
USER_START_MSG,
|
||||
USER_VISIBILITY_CHANGED_MSG,
|
||||
USER_CURRENT_MSG);
|
||||
|
||||
private static final Set<Integer> START_INVISIBLE_BACKGROUND_USER_MESSAGE_CODES = newHashSet(
|
||||
private static final Set<Integer> START_BACKGROUND_USER_MESSAGE_CODES = newHashSet(
|
||||
USER_START_MSG,
|
||||
REPORT_LOCKED_BOOT_COMPLETE_MSG);
|
||||
|
||||
private static final Set<Integer> START_VISIBLE_BACKGROUND_USER_MESSAGE_CODES = newHashSet(
|
||||
USER_START_MSG,
|
||||
USER_VISIBILITY_CHANGED_MSG,
|
||||
REPORT_LOCKED_BOOT_COMPLETE_MSG);
|
||||
|
||||
@Before
|
||||
public void setUp() throws Exception {
|
||||
runWithDexmakerShareClassLoader(() -> {
|
||||
@@ -225,14 +215,12 @@ public class UserControllerTest {
|
||||
|
||||
@Test
|
||||
public void testStartUser_background() {
|
||||
mockAssignUserToMainDisplay(TEST_USER_ID, /* foreground= */ false,
|
||||
USER_ASSIGNMENT_RESULT_SUCCESS_INVISIBLE);
|
||||
boolean started = mUserController.startUser(TEST_USER_ID, /* foreground= */ false);
|
||||
assertWithMessage("startUser(%s, foreground=false)", TEST_USER_ID).that(started).isTrue();
|
||||
verify(mInjector.getWindowManager(), never()).startFreezingScreen(anyInt(), anyInt());
|
||||
verify(mInjector.getWindowManager(), never()).setSwitchingUser(anyBoolean());
|
||||
verify(mInjector, never()).clearAllLockedTasks(anyString());
|
||||
startBackgroundUserAssertions(/*visible= */ false);
|
||||
startBackgroundUserAssertions();
|
||||
verifyUserAssignedToDisplay(TEST_USER_ID, Display.DEFAULT_DISPLAY);
|
||||
}
|
||||
|
||||
@@ -267,7 +255,7 @@ public class UserControllerTest {
|
||||
verify(mInjector.getWindowManager(), never()).startFreezingScreen(anyInt(), anyInt());
|
||||
verify(mInjector.getWindowManager(), never()).setSwitchingUser(anyBoolean());
|
||||
verify(mInjector, never()).clearAllLockedTasks(anyString());
|
||||
startBackgroundUserAssertions(/*visible= */ true);
|
||||
startBackgroundUserAssertions();
|
||||
}
|
||||
|
||||
@Test
|
||||
@@ -293,8 +281,6 @@ public class UserControllerTest {
|
||||
|
||||
@Test
|
||||
public void testStartPreCreatedUser_background() throws Exception {
|
||||
mockAssignUserToMainDisplay(TEST_PRE_CREATED_USER_ID, /* foreground= */ false,
|
||||
USER_ASSIGNMENT_RESULT_SUCCESS_INVISIBLE);
|
||||
assertTrue(mUserController.startUser(TEST_PRE_CREATED_USER_ID, /* foreground= */ false));
|
||||
// Make sure no intents have been fired for pre-created users.
|
||||
assertTrue(mInjector.mSentIntents.isEmpty());
|
||||
@@ -322,10 +308,8 @@ public class UserControllerTest {
|
||||
assertEquals("Unexpected message sent", expectedMessageCodes, actualCodes);
|
||||
}
|
||||
|
||||
private void startBackgroundUserAssertions(boolean visible) {
|
||||
startUserAssertions(START_BACKGROUND_USER_ACTIONS,
|
||||
visible ? START_VISIBLE_BACKGROUND_USER_MESSAGE_CODES
|
||||
: START_INVISIBLE_BACKGROUND_USER_MESSAGE_CODES);
|
||||
private void startBackgroundUserAssertions() {
|
||||
startUserAssertions(START_BACKGROUND_USER_ACTIONS, START_BACKGROUND_USER_MESSAGE_CODES);
|
||||
}
|
||||
|
||||
private void startForegroundUserAssertions() {
|
||||
@@ -433,7 +417,7 @@ public class UserControllerTest {
|
||||
verify(mInjector, times(0)).dismissKeyguard(any(), anyString());
|
||||
verify(mInjector.getWindowManager(), times(1)).stopFreezingScreen();
|
||||
continueUserSwitchAssertions(TEST_USER_ID, false);
|
||||
verifySystemUserVisibilityChangedNotified(/* visible= */ false);
|
||||
verifySystemUserVisibilityChangesNeverNotified();
|
||||
}
|
||||
|
||||
@Test
|
||||
@@ -454,7 +438,7 @@ public class UserControllerTest {
|
||||
verify(mInjector, times(1)).dismissKeyguard(any(), anyString());
|
||||
verify(mInjector.getWindowManager(), times(1)).stopFreezingScreen();
|
||||
continueUserSwitchAssertions(TEST_USER_ID, false);
|
||||
verifySystemUserVisibilityChangedNotified(/* visible= */ false);
|
||||
verifySystemUserVisibilityChangesNeverNotified();
|
||||
}
|
||||
|
||||
@Test
|
||||
@@ -561,7 +545,7 @@ public class UserControllerTest {
|
||||
assertFalse(mUserController.canStartMoreUsers());
|
||||
assertEquals(Arrays.asList(new Integer[] {0, TEST_USER_ID1, TEST_USER_ID2}),
|
||||
mUserController.getRunningUsersLU());
|
||||
verifySystemUserVisibilityChangedNotified(/* visible= */ false);
|
||||
verifySystemUserVisibilityChangesNeverNotified();
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -709,24 +693,19 @@ public class UserControllerTest {
|
||||
|
||||
@Test
|
||||
public void testStartProfile() throws Exception {
|
||||
mockAssignUserToMainDisplay(TEST_PRE_CREATED_USER_ID, /* foreground= */ false,
|
||||
USER_ASSIGNMENT_RESULT_SUCCESS_INVISIBLE);
|
||||
setUpAndStartProfileInBackground(TEST_USER_ID1);
|
||||
|
||||
startBackgroundUserAssertions(/*visible= */ true);
|
||||
startBackgroundUserAssertions();
|
||||
verifyUserAssignedToDisplay(TEST_USER_ID1, Display.DEFAULT_DISPLAY);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testStartProfile_whenUsersOnSecondaryDisplaysIsEnabled() throws Exception {
|
||||
mockAssignUserToMainDisplay(TEST_USER_ID1, /* foreground= */ false,
|
||||
USER_ASSIGNMENT_RESULT_SUCCESS_VISIBLE);
|
||||
|
||||
mockIsUsersOnSecondaryDisplaysEnabled(true);
|
||||
|
||||
setUpAndStartProfileInBackground(TEST_USER_ID1);
|
||||
|
||||
startBackgroundUserAssertions(/*visible= */ true);
|
||||
startBackgroundUserAssertions();
|
||||
verifyUserAssignedToDisplay(TEST_USER_ID1, Display.DEFAULT_DISPLAY);
|
||||
}
|
||||
|
||||
@@ -983,13 +962,6 @@ public class UserControllerTest {
|
||||
when(mInjector.isUsersOnSecondaryDisplaysEnabled()).thenReturn(value);
|
||||
}
|
||||
|
||||
private void mockAssignUserToMainDisplay(@UserIdInt int userId, boolean foreground,
|
||||
@UserAssignmentResult int result) {
|
||||
when(mInjector.mUserManagerInternalMock.assignUserToDisplayOnStart(eq(userId),
|
||||
/* profileGroupId= */ anyInt(), eq(foreground), eq(Display.DEFAULT_DISPLAY)))
|
||||
.thenReturn(result);
|
||||
}
|
||||
|
||||
private void verifyUserAssignedToDisplay(@UserIdInt int userId, int displayId) {
|
||||
verify(mInjector.getUserManagerInternal()).assignUserToDisplayOnStart(eq(userId), anyInt(),
|
||||
anyBoolean(), eq(displayId));
|
||||
@@ -1008,8 +980,8 @@ public class UserControllerTest {
|
||||
verify(mInjector.getUserManagerInternal(), never()).unassignUserFromDisplayOnStop(userId);
|
||||
}
|
||||
|
||||
private void verifySystemUserVisibilityChangedNotified(boolean visible) {
|
||||
verify(mInjector).onUserVisibilityChanged(UserHandle.USER_SYSTEM, visible);
|
||||
private void verifySystemUserVisibilityChangesNeverNotified() {
|
||||
verify(mInjector, never()).onSystemUserVisibilityChanged(anyBoolean());
|
||||
}
|
||||
|
||||
// Should be public to allow mocking
|
||||
@@ -1154,8 +1126,8 @@ public class UserControllerTest {
|
||||
}
|
||||
|
||||
@Override
|
||||
void onUserVisibilityChanged(@UserIdInt int userId, boolean visible) {
|
||||
Log.i(TAG, "onUserVisibilityChanged(" + userId + ", " + visible + ")");
|
||||
void onSystemUserVisibilityChanged(boolean visible) {
|
||||
Log.i(TAG, "onSystemUserVisibilityChanged(" + visible + ")");
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user