diff --git a/services/core/java/com/android/server/pm/UserManagerInternal.java b/services/core/java/com/android/server/pm/UserManagerInternal.java index a9edce15a724d..3cbaebe4101e6 100644 --- a/services/core/java/com/android/server/pm/UserManagerInternal.java +++ b/services/core/java/com/android/server/pm/UserManagerInternal.java @@ -64,11 +64,12 @@ public abstract class UserManagerInternal { }) public @interface UserAssignmentResult {} - private static final String PREFIX_USER_START_MODE = "USER_START_MODE_"; + // TODO(b/248408342): Move keep annotation to the method referencing these fields reflectively. + @Keep public static final int USER_START_MODE_FOREGROUND = 1; + @Keep public static final int USER_START_MODE_BACKGROUND = 2; + @Keep public static final int USER_START_MODE_BACKGROUND_VISIBLE = 3; - /** - * Type used to indicate how a user started. - */ + private static final String PREFIX_USER_START_MODE = "USER_START_MODE_"; @IntDef(flag = false, prefix = {PREFIX_USER_START_MODE}, value = { USER_START_MODE_FOREGROUND, USER_START_MODE_BACKGROUND, @@ -76,32 +77,6 @@ public abstract class UserManagerInternal { }) public @interface UserStartMode {} - // TODO(b/248408342): Move keep annotations below to the method referencing these fields - // reflectively. - - /** (Full) user started on foreground (a.k.a. "current user"). */ - @Keep public static final int USER_START_MODE_FOREGROUND = 1; - - /** - * User (full or profile) started on background and is - * {@link UserManager#isUserVisible() invisible}. - * - *

This is the "traditional" way of starting a background user, and can be used to start - * profiles as well, although starting an invisible profile is not common from the System UI - * (it could be done through APIs or adb, though). - */ - @Keep public static final int USER_START_MODE_BACKGROUND = 2; - - /** - * User (full or profile) started on background and is - * {@link UserManager#isUserVisible() visible}. - * - *

This is the "traditional" way of starting a profile (i.e., when the profile of the current - * user is the current foreground user), but it can also be used to start a full user associated - * with a display (which is the case on automotives with passenger displays). - */ - @Keep public static final int USER_START_MODE_BACKGROUND_VISIBLE = 3; - public interface UserRestrictionsListener { /** * Called when a user restriction changes. diff --git a/services/core/java/com/android/server/pm/UserVisibilityMediator.java b/services/core/java/com/android/server/pm/UserVisibilityMediator.java index fe8a5008930a9..d5cc7caffa902 100644 --- a/services/core/java/com/android/server/pm/UserVisibilityMediator.java +++ b/services/core/java/com/android/server/pm/UserVisibilityMediator.java @@ -42,7 +42,6 @@ import android.util.Dumpable; import android.util.EventLog; import android.util.IndentingPrintWriter; import android.util.IntArray; -import android.util.Log; import android.util.SparseIntArray; import android.view.Display; @@ -56,8 +55,6 @@ import com.android.server.pm.UserManagerInternal.UserVisibilityListener; import com.android.server.utils.Slogf; import java.io.PrintWriter; -import java.util.ArrayList; -import java.util.List; import java.util.concurrent.CopyOnWriteArrayList; /** @@ -80,11 +77,11 @@ import java.util.concurrent.CopyOnWriteArrayList; */ public final class UserVisibilityMediator implements Dumpable { - private static final String TAG = UserVisibilityMediator.class.getSimpleName(); - - private static final boolean DBG = Log.isLoggable(TAG, Log.DEBUG); + 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(); + private static final String PREFIX_SECONDARY_DISPLAY_MAPPING = "SECONDARY_DISPLAY_MAPPING_"; public static final int SECONDARY_DISPLAY_MAPPING_NEEDED = 1; public static final int SECONDARY_DISPLAY_MAPPING_NOT_NEEDED = 2; @@ -101,7 +98,7 @@ public final class UserVisibilityMediator implements Dumpable { }) public @interface SecondaryDisplayMappingStatus {} - // TODO(b/266158156): might need to change this if boot logic is refactored for HSUM devices + // TODO(b/242195409): might need to change this if boot logic is refactored for HSUM devices @VisibleForTesting static final int INITIAL_CURRENT_USER_ID = USER_SYSTEM; @@ -135,23 +132,10 @@ public final class UserVisibilityMediator implements Dumpable { private final SparseIntArray mExtraDisplaysAssignedToUsers; /** - * Mapping of each user that started visible (key) to its profile group id (value). - * - *

It's used to determine not just if the user is visible, but also - * {@link #isProfile(int, int) if it's a profile}. + * Mapping from each started user to its profile group. */ @GuardedBy("mLock") - private final SparseIntArray mStartedVisibleProfileGroupIds = new SparseIntArray(); - - /** - * List of profiles that have explicitly started invisible. - * - *

Only used for debugging purposes (and set when {@link #DBG} is {@code true}), hence we - * don't care about autoboxing. - */ - @GuardedBy("mLock") - @Nullable - private final List mStartedInvisibleProfileUserIds; + private final SparseIntArray mStartedProfileGroupIds = new SparseIntArray(); /** * Handler user to call listeners @@ -180,14 +164,9 @@ public final class UserVisibilityMediator implements Dumpable { mUsersAssignedToDisplayOnStart = null; mExtraDisplaysAssignedToUsers = null; } - mStartedInvisibleProfileUserIds = DBG ? new ArrayList<>(4) : null; mHandler = handler; - // TODO(b/266158156): might need to change this if boot logic is refactored for HSUM devices - mStartedVisibleProfileGroupIds.put(INITIAL_CURRENT_USER_ID, INITIAL_CURRENT_USER_ID); - - if (DBG) { - Slogf.i(TAG, "UserVisibilityMediator created with DBG on"); - } + // TODO(b/242195409): might need to change this if boot logic is refactored for HSUM devices + mStartedProfileGroupIds.put(INITIAL_CURRENT_USER_ID, INITIAL_CURRENT_USER_ID); } /** @@ -198,8 +177,6 @@ public final class UserVisibilityMediator implements Dumpable { int displayId) { Preconditions.checkArgument(!isSpecialUserId(userId), "user id cannot be generic: %d", userId); - validateUserStartMode(userStartMode); - // This method needs to perform 4 actions: // // 1. Check if the user can be started given the provided arguments @@ -247,29 +224,14 @@ public final class UserVisibilityMediator implements Dumpable { visibleUsersBefore = getVisibleUsers(); - // Set current user / started users state - switch (userStartMode) { - case USER_START_MODE_FOREGROUND: - mCurrentUserId = userId; - // Fallthrough - case USER_START_MODE_BACKGROUND_VISIBLE: - if (DBG) { - Slogf.d(TAG, "adding visible user / profile group id mapping (%d -> %d)", - userId, profileGroupId); - } - mStartedVisibleProfileGroupIds.put(userId, profileGroupId); - break; - case USER_START_MODE_BACKGROUND: - if (mStartedInvisibleProfileUserIds != null - && isProfile(userId, profileGroupId)) { - Slogf.d(TAG, "adding user %d to list of invisible profiles", userId); - mStartedInvisibleProfileUserIds.add(userId); - } - break; - default: - Slogf.wtf(TAG, "invalid userStartMode passed to assignUserToDisplayOnStart: " - + "%d", userStartMode); + // Set current user / profiles state + if (userStartMode == USER_START_MODE_FOREGROUND) { + mCurrentUserId = userId; } + if (DBG) { + Slogf.d(TAG, "adding user / profile mapping (%d -> %d)", userId, profileGroupId); + } + mStartedProfileGroupIds.put(userId, profileGroupId); // Set user / display state switch (mappingResult) { @@ -335,46 +297,39 @@ public final class UserVisibilityMediator implements Dumpable { boolean foreground = userStartMode == USER_START_MODE_FOREGROUND; if (displayId != DEFAULT_DISPLAY) { if (foreground) { - Slogf.w(TAG, "getUserVisibilityOnStartLocked(%d, %d, %s, %d) failed: cannot start " + Slogf.w(TAG, "getUserVisibilityOnStartLocked(%d, %d, %b, %d) failed: cannot start " + "foreground user on secondary display", userId, profileGroupId, - userStartModeToString(userStartMode), displayId); + foreground, displayId); return USER_ASSIGNMENT_RESULT_FAILURE; } if (!mVisibleBackgroundUsersEnabled) { - Slogf.w(TAG, "getUserVisibilityOnStartLocked(%d, %d, %s, %d) failed: called on " + Slogf.w(TAG, "getUserVisibilityOnStartLocked(%d, %d, %b, %d) failed: called on " + "device that doesn't support multiple users on multiple displays", - userId, profileGroupId, userStartModeToString(userStartMode), displayId); + userId, profileGroupId, foreground, displayId); return USER_ASSIGNMENT_RESULT_FAILURE; } } if (isProfile(userId, profileGroupId)) { if (displayId != DEFAULT_DISPLAY) { - Slogf.w(TAG, "canStartUserLocked(%d, %d, %s, %d) failed: cannot start profile user " - + "on secondary display", userId, profileGroupId, - userStartModeToString(userStartMode), displayId); + Slogf.w(TAG, "canStartUserLocked(%d, %d, %b, %d) failed: cannot start profile user " + + "on secondary display", userId, profileGroupId, foreground, + displayId); return USER_ASSIGNMENT_RESULT_FAILURE; } - switch (userStartMode) { - case USER_START_MODE_FOREGROUND: - Slogf.w(TAG, "startUser(%d, %d, %s, %d) failed: cannot start profile user in " - + "foreground", userId, profileGroupId, - userStartModeToString(userStartMode), displayId); - return USER_ASSIGNMENT_RESULT_FAILURE; - case USER_START_MODE_BACKGROUND_VISIBLE: - boolean isParentVisibleOnDisplay = isUserVisible(profileGroupId, displayId); - if (!isParentVisibleOnDisplay) { - Slogf.w(TAG, "getUserVisibilityOnStartLocked(%d, %d, %s, %d) failed: cannot" - + " start profile user visible when its parent is not visible in " - + "that display", userId, profileGroupId, - userStartModeToString(userStartMode), displayId); - return USER_ASSIGNMENT_RESULT_FAILURE; - } - return USER_ASSIGNMENT_RESULT_SUCCESS_VISIBLE; - case USER_START_MODE_BACKGROUND: - return USER_ASSIGNMENT_RESULT_SUCCESS_INVISIBLE; + if (foreground) { + Slogf.w(TAG, "startUser(%d, %d, %b, %d) failed: cannot start profile user in " + + "foreground", userId, profileGroupId, foreground, displayId); + return USER_ASSIGNMENT_RESULT_FAILURE; + } else { + boolean isParentVisibleOnDisplay = isUserVisible(profileGroupId, displayId); + if (DBG) { + Slogf.d(TAG, "parent visible on display: %b", isParentVisibleOnDisplay); + } + return isParentVisibleOnDisplay + ? USER_ASSIGNMENT_RESULT_SUCCESS_VISIBLE + : USER_ASSIGNMENT_RESULT_SUCCESS_INVISIBLE; } - } return foreground || displayId != DEFAULT_DISPLAY @@ -392,9 +347,8 @@ public final class UserVisibilityMediator implements Dumpable { if (mVisibleBackgroundUserOnDefaultDisplayAllowed && userStartMode == USER_START_MODE_BACKGROUND_VISIBLE) { int userStartedOnDefaultDisplay = getUserStartedOnDisplay(DEFAULT_DISPLAY); - if (userStartedOnDefaultDisplay != USER_NULL - && userStartedOnDefaultDisplay != profileGroupId) { - Slogf.w(TAG, "canAssignUserToDisplayLocked(): cannot start user %d visible on" + if (userStartedOnDefaultDisplay != USER_NULL) { + Slogf.w(TAG, "getUserVisibilityOnStartLocked(): cannot start user %d visible on" + " default display because user %d already did so", userId, userStartedOnDefaultDisplay); return SECONDARY_DISPLAY_MAPPING_FAILED; @@ -500,7 +454,7 @@ public final class UserVisibilityMediator implements Dumpable { userId, displayId); return false; } - if (isStartedVisibleProfileLocked(userId)) { + if (isStartedProfile(userId)) { Slogf.w(TAG, "assignUserToExtraDisplay(%d, %d): failed because user is a profile", userId, displayId); return false; @@ -588,14 +542,10 @@ public final class UserVisibilityMediator implements Dumpable { @GuardedBy("mLock") private void unassignUserFromAllDisplaysOnStopLocked(@UserIdInt int userId) { if (DBG) { - Slogf.d(TAG, "Removing %d from mStartedVisibleProfileGroupIds (%s)", userId, - mStartedVisibleProfileGroupIds); - } - mStartedVisibleProfileGroupIds.delete(userId); - if (mStartedInvisibleProfileUserIds != null) { - Slogf.d(TAG, "Removing %d from list of invisible profiles", userId); - mStartedInvisibleProfileUserIds.remove(Integer.valueOf(userId)); + Slogf.d(TAG, "Removing %d from mStartedProfileGroupIds (%s)", userId, + mStartedProfileGroupIds); } + mStartedProfileGroupIds.delete(userId); if (!mVisibleBackgroundUsersEnabled) { // Don't need to update mUsersAssignedToDisplayOnStart because methods (such as @@ -625,8 +575,7 @@ public final class UserVisibilityMediator implements Dumpable { * See {@link UserManagerInternal#isUserVisible(int)}. */ public boolean isUserVisible(@UserIdInt int userId) { - // For optimization (as most devices don't support visible background users), check for - // current foreground user and their profiles first + // First check current foreground user and their profiles (on main display) if (isCurrentUserOrRunningProfileOfCurrentUser(userId)) { if (VERBOSE) { Slogf.v(TAG, "isUserVisible(%d): true to current user or profile", userId); @@ -635,31 +584,19 @@ public final class UserVisibilityMediator implements Dumpable { } if (!mVisibleBackgroundUsersEnabled) { - if (VERBOSE) { - Slogf.v(TAG, "isUserVisible(%d): false for non-current user (or its profiles) when" + if (DBG) { + Slogf.d(TAG, "isUserVisible(%d): false for non-current user (or its profiles) when" + " device doesn't support visible background users", userId); } return false; } - + boolean visible; synchronized (mLock) { - int profileGroupId; - synchronized (mLock) { - profileGroupId = mStartedVisibleProfileGroupIds.get(userId, NO_PROFILE_GROUP_ID); - } - if (isProfile(userId, profileGroupId)) { - return isUserAssignedToDisplayOnStartLocked(profileGroupId); - } - return isUserAssignedToDisplayOnStartLocked(userId); + visible = mUsersAssignedToDisplayOnStart.indexOfKey(userId) >= 0; } - } - - @GuardedBy("mLock") - private boolean isUserAssignedToDisplayOnStartLocked(@UserIdInt int userId) { - boolean visible = mUsersAssignedToDisplayOnStart.indexOfKey(userId) >= 0; - if (VERBOSE) { - Slogf.v(TAG, "isUserAssignedToDisplayOnStartLocked(%d): %b", userId, visible); + if (DBG) { + Slogf.d(TAG, "isUserVisible(%d): %b from mapping", userId, visible); } return visible; } @@ -672,8 +609,7 @@ public final class UserVisibilityMediator implements Dumpable { return false; } - // For optimization (as most devices don't support visible background users), check for - // current user and profile first. Current user is always visible on: + // Current user is always visible on: // - Default display // - Secondary displays when device doesn't support visible bg users // - Or when explicitly added (which is checked below) @@ -695,26 +631,14 @@ public final class UserVisibilityMediator implements Dumpable { } synchronized (mLock) { - int profileGroupId; - synchronized (mLock) { - profileGroupId = mStartedVisibleProfileGroupIds.get(userId, NO_PROFILE_GROUP_ID); + if (mUsersAssignedToDisplayOnStart.get(userId, Display.INVALID_DISPLAY) == displayId) { + // User assigned to display on start + return true; } - if (isProfile(userId, profileGroupId)) { - return isFullUserVisibleOnBackgroundLocked(profileGroupId, displayId); - } - return isFullUserVisibleOnBackgroundLocked(userId, displayId); - } - } - // NOTE: it doesn't check if the userId is a full user, it's up to the caller to check that - @GuardedBy("mLock") - private boolean isFullUserVisibleOnBackgroundLocked(@UserIdInt int userId, int displayId) { - if (mUsersAssignedToDisplayOnStart.get(userId, Display.INVALID_DISPLAY) == displayId) { - // User assigned to display on start - return true; + // Check for extra display assignment + return mExtraDisplaysAssignedToUsers.get(displayId, USER_NULL) == userId; } - // Check for extra display assignment - return mExtraDisplaysAssignedToUsers.get(displayId, USER_NULL) == userId; } /** @@ -782,7 +706,7 @@ public final class UserVisibilityMediator implements Dumpable { continue; } int userId = mUsersAssignedToDisplayOnStart.keyAt(i); - if (!isStartedVisibleProfileLocked(userId)) { + if (!isStartedProfile(userId)) { return userId; } else if (DBG) { Slogf.d(TAG, "getUserAssignedToDisplay(%d): skipping user %d because it's " @@ -815,8 +739,8 @@ public final class UserVisibilityMediator implements Dumpable { // number of users is too small, the gain is probably not worth the increase on complexity. IntArray visibleUsers = new IntArray(); synchronized (mLock) { - for (int i = 0; i < mStartedVisibleProfileGroupIds.size(); i++) { - int userId = mStartedVisibleProfileGroupIds.keyAt(i); + for (int i = 0; i < mStartedProfileGroupIds.size(); i++) { + int userId = mStartedProfileGroupIds.keyAt(i); if (isUserVisible(userId)) { visibleUsers.add(userId); } @@ -849,7 +773,7 @@ public final class UserVisibilityMediator implements Dumpable { } } - // TODO(b/266158156): remove this method if not needed anymore + // TODO(b/242195409): remove this method if not needed anymore /** * Nofify all listeners that the system user visibility changed. */ @@ -911,9 +835,6 @@ public final class UserVisibilityMediator implements Dumpable { ipw.println("UserVisibilityMediator"); ipw.increaseIndent(); - ipw.print("DBG: "); - ipw.println(DBG); - synchronized (mLock) { ipw.print("Current user id: "); ipw.println(mCurrentUserId); @@ -921,12 +842,8 @@ public final class UserVisibilityMediator implements Dumpable { ipw.print("Visible users: "); ipw.println(getVisibleUsers()); - dumpSparseIntArray(ipw, mStartedVisibleProfileGroupIds, - "started visible user / profile group", "u", "pg"); - if (mStartedInvisibleProfileUserIds != null) { - ipw.print("Profiles started invisible: "); - ipw.println(mStartedInvisibleProfileUserIds); - } + dumpSparseIntArray(ipw, mStartedProfileGroupIds, "started user / profile group", + "u", "pg"); ipw.print("Supports visible background users on displays: "); ipw.println(mVisibleBackgroundUsersEnabled); @@ -1034,25 +951,22 @@ public final class UserVisibilityMediator implements Dumpable { if (mCurrentUserId == userId) { return true; } - return mStartedVisibleProfileGroupIds.get(userId, NO_PROFILE_GROUP_ID) - == mCurrentUserId; + return mStartedProfileGroupIds.get(userId, NO_PROFILE_GROUP_ID) == mCurrentUserId; } } - @GuardedBy("mLock") - private boolean isStartedVisibleProfileLocked(@UserIdInt int userId) { - int profileGroupId = mStartedVisibleProfileGroupIds.get(userId, NO_PROFILE_GROUP_ID); + private boolean isStartedProfile(@UserIdInt int userId) { + int profileGroupId; + synchronized (mLock) { + profileGroupId = mStartedProfileGroupIds.get(userId, NO_PROFILE_GROUP_ID); + } return isProfile(userId, profileGroupId); } - private void validateUserStartMode(@UserStartMode int userStartMode) { - switch (userStartMode) { - case USER_START_MODE_FOREGROUND: - case USER_START_MODE_BACKGROUND: - case USER_START_MODE_BACKGROUND_VISIBLE: - return; + private @UserIdInt int getStartedProfileGroupId(@UserIdInt int userId) { + synchronized (mLock) { + return mStartedProfileGroupIds.get(userId, NO_PROFILE_GROUP_ID); } - throw new IllegalArgumentException("Invalid user start mode: " + userStartMode); } private static String secondaryDisplayMappingStatusToString( diff --git a/services/tests/mockingservicestests/src/com/android/server/pm/UserVisibilityMediatorMUPANDTest.java b/services/tests/mockingservicestests/src/com/android/server/pm/UserVisibilityMediatorMUPANDTest.java index 8979585d9235c..38cf6341e798b 100644 --- a/services/tests/mockingservicestests/src/com/android/server/pm/UserVisibilityMediatorMUPANDTest.java +++ b/services/tests/mockingservicestests/src/com/android/server/pm/UserVisibilityMediatorMUPANDTest.java @@ -75,8 +75,8 @@ public final class UserVisibilityMediatorMUPANDTest assertUserCanBeAssignedExtraDisplay(USER_ID, OTHER_SECONDARY_DISPLAY_ID); // Make sure another user cannot be started on default display - int result2 = mMediator.assignUserToDisplayOnStart(otherUserId, otherUserId, BG_VISIBLE, - DEFAULT_DISPLAY); + int result2 = mMediator.assignUserToDisplayOnStart(otherUserId, visibleBgUserId, + BG_VISIBLE, DEFAULT_DISPLAY); assertStartUserResult(result2, USER_ASSIGNMENT_RESULT_FAILURE, "when user (%d) is starting on default display after it was started by user %d", otherUserId, visibleBgUserId); @@ -119,8 +119,8 @@ public final class UserVisibilityMediatorMUPANDTest assertUserCanBeAssignedExtraDisplay(USER_ID, OTHER_SECONDARY_DISPLAY_ID); // Make sure another user cannot be started on default display - int result2 = mMediator.assignUserToDisplayOnStart(otherUserId, otherUserId, BG_VISIBLE, - DEFAULT_DISPLAY); + int result2 = mMediator.assignUserToDisplayOnStart(otherUserId, visibleBgUserId, + BG_VISIBLE, DEFAULT_DISPLAY); assertStartUserResult(result2, USER_ASSIGNMENT_RESULT_FAILURE, "when user (%d) is starting on default display after it was started by user %d", otherUserId, visibleBgUserId); @@ -128,6 +128,7 @@ public final class UserVisibilityMediatorMUPANDTest listener.verify(); } + /* TODO: re-add @Test public void @@ -226,4 +227,5 @@ public final class UserVisibilityMediatorMUPANDTest listener.verify(); } + */ } diff --git a/services/tests/mockingservicestests/src/com/android/server/pm/UserVisibilityMediatorTestCase.java b/services/tests/mockingservicestests/src/com/android/server/pm/UserVisibilityMediatorTestCase.java index 566084adfae33..5176d684ace68 100644 --- a/services/tests/mockingservicestests/src/com/android/server/pm/UserVisibilityMediatorTestCase.java +++ b/services/tests/mockingservicestests/src/com/android/server/pm/UserVisibilityMediatorTestCase.java @@ -44,6 +44,7 @@ import android.text.TextUtils; import android.util.IntArray; import android.util.Log; +import com.android.internal.util.Preconditions; import com.android.server.ExtendedMockitoTestCase; import org.junit.Before; @@ -147,12 +148,6 @@ abstract class UserVisibilityMediatorTestCase extends ExtendedMockitoTestCase { .assignUserToDisplayOnStart(USER_CURRENT_OR_SELF, USER_ID, FG, DEFAULT_DISPLAY)); } - @Test - public final void testAssignUserToDisplayOnStart_invalidUserStartMode() { - assertThrows(IllegalArgumentException.class, () -> mMediator - .assignUserToDisplayOnStart(USER_ID, USER_ID, 666, DEFAULT_DISPLAY)); - } - @Test public final void testStartFgUser_onSecondaryDisplay() throws Exception { AsyncUserVisibilityListener listener = addListenerForNoEvents(); @@ -288,7 +283,7 @@ abstract class UserVisibilityMediatorTestCase extends ExtendedMockitoTestCase { int result = mMediator.assignUserToDisplayOnStart(PROFILE_USER_ID, PARENT_USER_ID, BG_VISIBLE, DEFAULT_DISPLAY); - assertStartUserResult(result, USER_ASSIGNMENT_RESULT_FAILURE); + assertStartUserResult(result, USER_ASSIGNMENT_RESULT_SUCCESS_INVISIBLE); expectUserIsNotVisibleAtAll(PROFILE_USER_ID); expectNoDisplayAssignedToUser(PROFILE_USER_ID); @@ -304,14 +299,14 @@ abstract class UserVisibilityMediatorTestCase extends ExtendedMockitoTestCase { int result = mMediator.assignUserToDisplayOnStart(PROFILE_USER_ID, PARENT_USER_ID, BG_VISIBLE, DEFAULT_DISPLAY); - assertStartUserResult(result, USER_ASSIGNMENT_RESULT_FAILURE); + assertStartUserResult(result, USER_ASSIGNMENT_RESULT_SUCCESS_INVISIBLE); expectUserIsNotVisibleAtAll(PROFILE_USER_ID); expectNoDisplayAssignedToUser(PROFILE_USER_ID); expectInitialCurrentUserAssignedToDisplay(DEFAULT_DISPLAY); - assertInvisibleUserCannotBeAssignedExtraDisplay(PROFILE_USER_ID, SECONDARY_DISPLAY_ID); + assertUserCannotBeAssignedExtraDisplay(PROFILE_USER_ID, SECONDARY_DISPLAY_ID); listener.verify(); } @@ -336,41 +331,6 @@ abstract class UserVisibilityMediatorTestCase extends ExtendedMockitoTestCase { listener.verify(); } - @Test - public final void testStartBgProfile_onDefaultDisplay_whenParentIsNotStarted() - throws Exception { - AsyncUserVisibilityListener listener = addListenerForNoEvents(); - - int result = mMediator.assignUserToDisplayOnStart(PROFILE_USER_ID, PARENT_USER_ID, BG, - DEFAULT_DISPLAY); - assertStartUserResult(result, USER_ASSIGNMENT_RESULT_SUCCESS_INVISIBLE); - - expectUserIsNotVisibleAtAll(PROFILE_USER_ID); - expectNoDisplayAssignedToUser(PROFILE_USER_ID); - - listener.verify(); - } - - @Test - public final void testStartBgProfile_onDefaultDisplay_whenParentIsStartedOnBg() - throws Exception { - AsyncUserVisibilityListener listener = addListenerForNoEvents(); - startBackgroundUser(PARENT_USER_ID); - - int result = mMediator.assignUserToDisplayOnStart(PROFILE_USER_ID, PARENT_USER_ID, BG, - DEFAULT_DISPLAY); - assertStartUserResult(result, USER_ASSIGNMENT_RESULT_SUCCESS_INVISIBLE); - - expectUserIsNotVisibleAtAll(PROFILE_USER_ID); - - expectNoDisplayAssignedToUser(PROFILE_USER_ID); - expectInitialCurrentUserAssignedToDisplay(DEFAULT_DISPLAY); - - assertUserCannotBeAssignedExtraDisplay(PROFILE_USER_ID, SECONDARY_DISPLAY_ID); - - listener.verify(); - } - @Test public final void testStartBgProfile_onSecondaryDisplay() throws Exception { AsyncUserVisibilityListener listener = addListenerForNoEvents(); @@ -525,6 +485,8 @@ abstract class UserVisibilityMediatorTestCase extends ExtendedMockitoTestCase { * se. */ protected final void startUserInSecondaryDisplay(@UserIdInt int userId, int displayId) { + Preconditions.checkArgument(displayId != INVALID_DISPLAY && displayId != DEFAULT_DISPLAY, + "must pass a secondary display, not %d", displayId); Log.d(TAG, "startUserInSecondaryDisplay(" + userId + ", " + displayId + ")"); int result = mMediator.assignUserToDisplayOnStart(userId, userId, BG_VISIBLE, displayId); if (result != USER_ASSIGNMENT_RESULT_SUCCESS_VISIBLE) { diff --git a/services/tests/mockingservicestests/src/com/android/server/pm/UserVisibilityMediatorVisibleBackgroundUserTestCase.java b/services/tests/mockingservicestests/src/com/android/server/pm/UserVisibilityMediatorVisibleBackgroundUserTestCase.java index f0840633e054a..49c6a8854c49a 100644 --- a/services/tests/mockingservicestests/src/com/android/server/pm/UserVisibilityMediatorVisibleBackgroundUserTestCase.java +++ b/services/tests/mockingservicestests/src/com/android/server/pm/UserVisibilityMediatorVisibleBackgroundUserTestCase.java @@ -107,6 +107,34 @@ abstract class UserVisibilityMediatorVisibleBackgroundUserTestCase listener.verify(); } + @Test + public final void testStartVisibleBgProfile_onDefaultDisplay_whenParentIsCurrentUser() + throws Exception { + AsyncUserVisibilityListener listener = addListenerForEvents( + onInvisible(INITIAL_CURRENT_USER_ID), + onVisible(PARENT_USER_ID), + onVisible(PROFILE_USER_ID)); + startForegroundUser(PARENT_USER_ID); + + int result = mMediator.assignUserToDisplayOnStart(PROFILE_USER_ID, PARENT_USER_ID, + BG_VISIBLE, DEFAULT_DISPLAY); + assertStartUserResult(result, USER_ASSIGNMENT_RESULT_SUCCESS_VISIBLE); + expectUserCannotBeUnassignedFromDisplay(PROFILE_USER_ID, DEFAULT_DISPLAY); + + expectUserIsVisible(PROFILE_USER_ID); + expectUserIsNotVisibleOnDisplay(PROFILE_USER_ID, INVALID_DISPLAY); + expectUserIsNotVisibleOnDisplay(PROFILE_USER_ID, SECONDARY_DISPLAY_ID); + expectUserIsVisibleOnDisplay(PROFILE_USER_ID, DEFAULT_DISPLAY); + expectVisibleUsers(PARENT_USER_ID, PROFILE_USER_ID); + + expectDisplayAssignedToUser(PROFILE_USER_ID, DEFAULT_DISPLAY); + expectUserAssignedToDisplay(DEFAULT_DISPLAY, PARENT_USER_ID); + + assertUserCannotBeAssignedExtraDisplay(PROFILE_USER_ID, SECONDARY_DISPLAY_ID); + + listener.verify(); + } + @Test public final void testStartFgUser_onInvalidDisplay() throws Exception { AsyncUserVisibilityListener listener = addListenerForNoEvents(); @@ -239,84 +267,15 @@ abstract class UserVisibilityMediatorVisibleBackgroundUserTestCase listener2.verify(); } - @Test - public final void testStartVisibleBgProfile_onDefaultDisplay_whenParentIsCurrentUser() - throws Exception { - AsyncUserVisibilityListener listener = addListenerForEvents( - onInvisible(INITIAL_CURRENT_USER_ID), - onVisible(PARENT_USER_ID), - onVisible(PROFILE_USER_ID)); - startForegroundUser(PARENT_USER_ID); - - int result = mMediator.assignUserToDisplayOnStart(PROFILE_USER_ID, PARENT_USER_ID, - BG_VISIBLE, DEFAULT_DISPLAY); - assertStartUserResult(result, USER_ASSIGNMENT_RESULT_SUCCESS_VISIBLE); - expectUserCannotBeUnassignedFromDisplay(PROFILE_USER_ID, DEFAULT_DISPLAY); - - expectUserIsVisible(PROFILE_USER_ID); - expectUserIsNotVisibleOnDisplay(PROFILE_USER_ID, INVALID_DISPLAY); - expectUserIsNotVisibleOnDisplay(PROFILE_USER_ID, SECONDARY_DISPLAY_ID); - expectUserIsVisibleOnDisplay(PROFILE_USER_ID, DEFAULT_DISPLAY); - expectVisibleUsers(PARENT_USER_ID, PROFILE_USER_ID); - - expectDisplayAssignedToUser(PROFILE_USER_ID, DEFAULT_DISPLAY); - expectUserAssignedToDisplay(DEFAULT_DISPLAY, PARENT_USER_ID); - - assertUserCannotBeAssignedExtraDisplay(PROFILE_USER_ID, SECONDARY_DISPLAY_ID); - - listener.verify(); - } - @Test public final void - testStartVisibleBgProfile_onDefaultDisplay_whenParentIsStartedVisibleOnAnotherDisplay() - throws Exception { + testStartVisibleBgProfile_onDefaultDisplay_whenParentVisibleOnSecondaryDisplay() + throws Exception { AsyncUserVisibilityListener listener = addListenerForEvents(onVisible(PARENT_USER_ID)); startUserInSecondaryDisplay(PARENT_USER_ID, OTHER_SECONDARY_DISPLAY_ID); int result = mMediator.assignUserToDisplayOnStart(PROFILE_USER_ID, PARENT_USER_ID, BG_VISIBLE, DEFAULT_DISPLAY); - assertStartUserResult(result, USER_ASSIGNMENT_RESULT_FAILURE); - - expectUserIsNotVisibleAtAll(PROFILE_USER_ID); - expectNoDisplayAssignedToUser(PROFILE_USER_ID); - expectUserAssignedToDisplay(OTHER_SECONDARY_DISPLAY_ID, PARENT_USER_ID); - - assertInvisibleUserCannotBeAssignedExtraDisplay(PROFILE_USER_ID, SECONDARY_DISPLAY_ID); - - listener.verify(); - } - - // Not supported - profiles can only be started on default display - @Test - public final void - testStartVisibleBgProfile_onSecondaryDisplay_whenParentIsStartedVisibleOnThatDisplay() - throws Exception { - AsyncUserVisibilityListener listener = addListenerForEvents(onVisible(PARENT_USER_ID)); - startUserInSecondaryDisplay(PARENT_USER_ID, OTHER_SECONDARY_DISPLAY_ID); - - int result = mMediator.assignUserToDisplayOnStart(PROFILE_USER_ID, PARENT_USER_ID, - BG_VISIBLE, DEFAULT_DISPLAY); - assertStartUserResult(result, USER_ASSIGNMENT_RESULT_FAILURE); - - expectUserIsNotVisibleAtAll(PROFILE_USER_ID); - expectNoDisplayAssignedToUser(PROFILE_USER_ID); - expectUserAssignedToDisplay(OTHER_SECONDARY_DISPLAY_ID, PARENT_USER_ID); - - assertInvisibleUserCannotBeAssignedExtraDisplay(PROFILE_USER_ID, SECONDARY_DISPLAY_ID); - - listener.verify(); - } - - @Test - public final void - testStartProfile_onDefaultDisplay_whenParentIsStartedVisibleOnSecondaryDisplay() - throws Exception { - AsyncUserVisibilityListener listener = addListenerForEvents(onVisible(PARENT_USER_ID)); - startUserInSecondaryDisplay(PARENT_USER_ID, OTHER_SECONDARY_DISPLAY_ID); - - int result = mMediator.assignUserToDisplayOnStart(PROFILE_USER_ID, PARENT_USER_ID, BG, - DEFAULT_DISPLAY); assertStartUserResult(result, USER_ASSIGNMENT_RESULT_SUCCESS_INVISIBLE); expectUserIsNotVisibleAtAll(PROFILE_USER_ID);