Merge "New UserManagerInternal APIs for extra user / display assignment."
This commit is contained in:
@@ -388,8 +388,8 @@ public abstract class UserManagerInternal {
|
||||
* and the user is {@link UserManager#isUserVisible() visible}.
|
||||
*
|
||||
* <p><b>NOTE: </b>this method is meant to be used only by {@code UserController} (when a user
|
||||
* is started). If other clients (like {@code CarService} need to explicitly change the user /
|
||||
* display assignment, we'll need to provide other APIs.
|
||||
* is started); for extra unassignments, callers should call {@link
|
||||
* #assignUserToExtraDisplay(int, int)} instead.
|
||||
*
|
||||
* <p><b>NOTE: </b>this method doesn't validate if the display exists, it's up to the caller to
|
||||
* pass a valid display id.
|
||||
@@ -397,15 +397,43 @@ public abstract class UserManagerInternal {
|
||||
public abstract @UserAssignmentResult int assignUserToDisplayOnStart(@UserIdInt int userId,
|
||||
@UserIdInt int profileGroupId, @UserStartMode int userStartMode, int displayId);
|
||||
|
||||
/**
|
||||
* Assigns an extra display to the given user, so the user is visible on that display.
|
||||
*
|
||||
* <p>This method is meant to be used on automotive builds where a passenger zone has more than
|
||||
* one display (for example, the "main" display and a smaller display used for input).
|
||||
*
|
||||
* <p><b>NOTE: </b>this call will be ignored on devices that do not
|
||||
* {@link UserManager#isVisibleBackgroundUsersSupported() support visible background users}.
|
||||
*
|
||||
* @return whether the operation succeeded, in which case the user would be visible on the
|
||||
* display.
|
||||
*/
|
||||
public abstract boolean assignUserToExtraDisplay(@UserIdInt int userId, int displayId);
|
||||
|
||||
/**
|
||||
* Unassigns a user from its current display when it's stopping.
|
||||
*
|
||||
* <p><b>NOTE: </b>this method is meant to be used only by {@code UserController} (when a user
|
||||
* is stopped). If other clients (like {@code CarService} need to explicitly change the user /
|
||||
* display assignment, we'll need to provide other APIs.
|
||||
* is stopped); for extra unassignments, callers should call
|
||||
* {@link #unassignUserFromExtraDisplay(int, int)} instead.
|
||||
*/
|
||||
public abstract void unassignUserFromDisplayOnStop(@UserIdInt int userId);
|
||||
|
||||
/**
|
||||
* Unassigns the extra display from the given user.
|
||||
*
|
||||
* <p>This method is meant to be used on automotive builds where a passenger zone has more than
|
||||
* one display (for example, the "main" display and a smaller display used for input).
|
||||
*
|
||||
* <p><b>NOTE: </b>this call will be ignored on devices that do not
|
||||
* {@link UserManager#isVisibleBackgroundUsersSupported() support visible background users}.
|
||||
*
|
||||
* @return whether the operation succeeded, i.e., the user was previously
|
||||
* {@link #assignUserToExtraDisplay(int, int) assigned to an extra display}.
|
||||
*/
|
||||
public abstract boolean unassignUserFromExtraDisplay(@UserIdInt int userId, int displayId);
|
||||
|
||||
/**
|
||||
* Returns {@code true} if the user is visible (as defined by
|
||||
* {@link UserManager#isUserVisible()}.
|
||||
|
||||
@@ -7037,6 +7037,16 @@ public class UserManagerService extends IUserManager.Stub {
|
||||
userStartMode, displayId);
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean assignUserToExtraDisplay(int userId, int displayId) {
|
||||
return mUserVisibilityMediator.assignUserToExtraDisplay(userId, displayId);
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean unassignUserFromExtraDisplay(int userId, int displayId) {
|
||||
return mUserVisibilityMediator.unassignUserFromExtraDisplay(userId, displayId);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void unassignUserFromDisplayOnStop(@UserIdInt int userId) {
|
||||
mUserVisibilityMediator.unassignUserFromDisplayOnStop(userId);
|
||||
|
||||
@@ -19,6 +19,7 @@ import static android.content.pm.UserInfo.NO_PROFILE_GROUP_ID;
|
||||
import static android.os.UserHandle.USER_NULL;
|
||||
import static android.os.UserHandle.USER_SYSTEM;
|
||||
import static android.view.Display.DEFAULT_DISPLAY;
|
||||
import static android.view.Display.INVALID_DISPLAY;
|
||||
|
||||
import static com.android.server.pm.UserManagerInternal.USER_ASSIGNMENT_RESULT_FAILURE;
|
||||
import static com.android.server.pm.UserManagerInternal.USER_ASSIGNMENT_RESULT_SUCCESS_INVISIBLE;
|
||||
@@ -113,7 +114,18 @@ public final class UserVisibilityMediator implements Dumpable {
|
||||
*/
|
||||
@Nullable
|
||||
@GuardedBy("mLock")
|
||||
private final SparseIntArray mUsersOnDisplaysMap;
|
||||
private final SparseIntArray mUsersAssignedToDisplayOnStart;
|
||||
|
||||
/**
|
||||
* Map of extra (i.e., not assigned on start, but by explicit calls to
|
||||
* {@link #assignUserToExtraDisplay(int, int)}) displays assigned to user (key is display id,
|
||||
* value is user id).
|
||||
*
|
||||
* <p>Only set when {@code mUsersOnSecondaryDisplaysEnabled} is {@code true}.
|
||||
*/
|
||||
@Nullable
|
||||
@GuardedBy("mLock")
|
||||
private final SparseIntArray mExtraDisplaysAssignedToUsers;
|
||||
|
||||
/**
|
||||
* Mapping from each started user to its profile group.
|
||||
@@ -137,7 +149,13 @@ public final class UserVisibilityMediator implements Dumpable {
|
||||
@VisibleForTesting
|
||||
UserVisibilityMediator(boolean backgroundUsersOnDisplaysEnabled, Handler handler) {
|
||||
mVisibleBackgroundUsersEnabled = backgroundUsersOnDisplaysEnabled;
|
||||
mUsersOnDisplaysMap = mVisibleBackgroundUsersEnabled ? new SparseIntArray() : null;
|
||||
if (mVisibleBackgroundUsersEnabled) {
|
||||
mUsersAssignedToDisplayOnStart = new SparseIntArray();
|
||||
mExtraDisplaysAssignedToUsers = new SparseIntArray();
|
||||
} else {
|
||||
mUsersAssignedToDisplayOnStart = null;
|
||||
mExtraDisplaysAssignedToUsers = null;
|
||||
}
|
||||
mHandler = handler;
|
||||
// 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);
|
||||
@@ -207,7 +225,7 @@ public final class UserVisibilityMediator implements Dumpable {
|
||||
if (DBG) {
|
||||
Slogf.d(TAG, "adding user / display mapping (%d -> %d)", userId, displayId);
|
||||
}
|
||||
mUsersOnDisplaysMap.put(userId, displayId);
|
||||
mUsersAssignedToDisplayOnStart.put(userId, displayId);
|
||||
break;
|
||||
case SECONDARY_DISPLAY_MAPPING_NOT_NEEDED:
|
||||
if (DBG) {
|
||||
@@ -341,9 +359,9 @@ public final class UserVisibilityMediator implements Dumpable {
|
||||
}
|
||||
|
||||
// Check if display is available
|
||||
for (int i = 0; i < mUsersOnDisplaysMap.size(); i++) {
|
||||
int assignedUserId = mUsersOnDisplaysMap.keyAt(i);
|
||||
int assignedDisplayId = mUsersOnDisplaysMap.valueAt(i);
|
||||
for (int i = 0; i < mUsersAssignedToDisplayOnStart.size(); i++) {
|
||||
int assignedUserId = mUsersAssignedToDisplayOnStart.keyAt(i);
|
||||
int assignedDisplayId = mUsersAssignedToDisplayOnStart.valueAt(i);
|
||||
if (DBG) {
|
||||
Slogf.d(TAG, "%d: assignedUserId=%d, assignedDisplayId=%d",
|
||||
i, assignedUserId, assignedDisplayId);
|
||||
@@ -362,6 +380,100 @@ public final class UserVisibilityMediator implements Dumpable {
|
||||
return SECONDARY_DISPLAY_MAPPING_NEEDED;
|
||||
}
|
||||
|
||||
/**
|
||||
* See {@link UserManagerInternal#assignUserToExtraDisplay(int, int)}.
|
||||
*/
|
||||
public boolean assignUserToExtraDisplay(@UserIdInt int userId, int displayId) {
|
||||
if (DBG) {
|
||||
Slogf.d(TAG, "assignUserToExtraDisplay(%d, %d)", userId, displayId);
|
||||
}
|
||||
if (!mVisibleBackgroundUsersEnabled) {
|
||||
Slogf.w(TAG, "assignUserToExtraDisplay(%d, %d): called when not supported", userId,
|
||||
displayId);
|
||||
return false;
|
||||
}
|
||||
if (displayId == INVALID_DISPLAY) {
|
||||
Slogf.w(TAG, "assignUserToExtraDisplay(%d, %d): called with INVALID_DISPLAY", userId,
|
||||
displayId);
|
||||
return false;
|
||||
}
|
||||
if (displayId == DEFAULT_DISPLAY) {
|
||||
Slogf.w(TAG, "assignUserToExtraDisplay(%d, %d): DEFAULT_DISPLAY is automatically "
|
||||
+ "assigned to current user", userId, displayId);
|
||||
return false;
|
||||
}
|
||||
|
||||
synchronized (mLock) {
|
||||
if (!isUserVisible(userId)) {
|
||||
Slogf.w(TAG, "assignUserToExtraDisplay(%d, %d): failed because user is not visible",
|
||||
userId, displayId);
|
||||
return false;
|
||||
}
|
||||
if (isStartedProfile(userId)) {
|
||||
Slogf.w(TAG, "assignUserToExtraDisplay(%d, %d): failed because user is a profile",
|
||||
userId, displayId);
|
||||
return false;
|
||||
}
|
||||
|
||||
if (mExtraDisplaysAssignedToUsers.get(displayId, USER_NULL) == userId) {
|
||||
Slogf.w(TAG, "assignUserToExtraDisplay(%d, %d): failed because user is already "
|
||||
+ "assigned to that display", userId, displayId);
|
||||
return false;
|
||||
}
|
||||
|
||||
int userAssignedToDisplay = getUserAssignedToDisplay(displayId,
|
||||
/* returnCurrentUserByDefault= */ false);
|
||||
if (userAssignedToDisplay != USER_NULL) {
|
||||
Slogf.w(TAG, "assignUserToExtraDisplay(%d, %d): failed because display was assigned"
|
||||
+ " to user %d on start", userId, displayId, userAssignedToDisplay);
|
||||
return false;
|
||||
}
|
||||
userAssignedToDisplay = mExtraDisplaysAssignedToUsers.get(userId, USER_NULL);
|
||||
if (userAssignedToDisplay != USER_NULL) {
|
||||
Slogf.w(TAG, "assignUserToExtraDisplay(%d, %d): failed because user %d was already "
|
||||
+ "assigned that extra display", userId, displayId, userAssignedToDisplay);
|
||||
return false;
|
||||
}
|
||||
if (DBG) {
|
||||
Slogf.d(TAG, "addding %d -> %d to map", displayId, userId);
|
||||
}
|
||||
mExtraDisplaysAssignedToUsers.put(displayId, userId);
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
* See {@link UserManagerInternal#unassignUserFromExtraDisplay(int, int)}.
|
||||
*/
|
||||
public boolean unassignUserFromExtraDisplay(@UserIdInt int userId, int displayId) {
|
||||
if (DBG) {
|
||||
Slogf.d(TAG, "unassignUserFromExtraDisplay(%d, %d)", userId, displayId);
|
||||
}
|
||||
if (!mVisibleBackgroundUsersEnabled) {
|
||||
Slogf.w(TAG, "unassignUserFromExtraDisplay(%d, %d): called when not supported",
|
||||
userId, displayId);
|
||||
return false;
|
||||
}
|
||||
synchronized (mLock) {
|
||||
int assignedUserId = mExtraDisplaysAssignedToUsers.get(displayId, USER_NULL);
|
||||
if (assignedUserId == USER_NULL) {
|
||||
Slogf.w(TAG, "unassignUserFromExtraDisplay(%d, %d): not assigned to any user",
|
||||
userId, displayId);
|
||||
return false;
|
||||
}
|
||||
if (assignedUserId != userId) {
|
||||
Slogf.w(TAG, "unassignUserFromExtraDisplay(%d, %d): was assigned to user %d",
|
||||
userId, displayId, assignedUserId);
|
||||
return false;
|
||||
}
|
||||
if (DBG) {
|
||||
Slogf.d(TAG, "removing %d from map", displayId);
|
||||
}
|
||||
mExtraDisplaysAssignedToUsers.delete(displayId);
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
* See {@link UserManagerInternal#unassignUserFromDisplayOnStop(int)}.
|
||||
*/
|
||||
@@ -373,7 +485,7 @@ public final class UserVisibilityMediator implements Dumpable {
|
||||
synchronized (mLock) {
|
||||
visibleUsersBefore = getVisibleUsers();
|
||||
|
||||
unassignUserFromDisplayOnStopLocked(userId);
|
||||
unassignUserFromAllDisplaysOnStopLocked(userId);
|
||||
|
||||
visibleUsersAfter = getVisibleUsers();
|
||||
}
|
||||
@@ -381,7 +493,7 @@ public final class UserVisibilityMediator implements Dumpable {
|
||||
}
|
||||
|
||||
@GuardedBy("mLock")
|
||||
private void unassignUserFromDisplayOnStopLocked(@UserIdInt int userId) {
|
||||
private void unassignUserFromAllDisplaysOnStopLocked(@UserIdInt int userId) {
|
||||
if (DBG) {
|
||||
Slogf.d(TAG, "Removing %d from mStartedProfileGroupIds (%s)", userId,
|
||||
mStartedProfileGroupIds);
|
||||
@@ -395,10 +507,21 @@ public final class UserVisibilityMediator implements Dumpable {
|
||||
return;
|
||||
}
|
||||
if (DBG) {
|
||||
Slogf.d(TAG, "Removing %d from mUsersOnSecondaryDisplays (%s)", userId,
|
||||
mUsersOnDisplaysMap);
|
||||
Slogf.d(TAG, "Removing user %d from mUsersOnDisplaysMap (%s)", userId,
|
||||
mUsersAssignedToDisplayOnStart);
|
||||
}
|
||||
mUsersAssignedToDisplayOnStart.delete(userId);
|
||||
|
||||
// Remove extra displays as well
|
||||
for (int i = mExtraDisplaysAssignedToUsers.size() - 1; i >= 0; i--) {
|
||||
if (mExtraDisplaysAssignedToUsers.valueAt(i) == userId) {
|
||||
if (DBG) {
|
||||
Slogf.d(TAG, "Removing display %d from mExtraDisplaysAssignedToUsers (%s)",
|
||||
mExtraDisplaysAssignedToUsers.keyAt(i), mExtraDisplaysAssignedToUsers);
|
||||
}
|
||||
mExtraDisplaysAssignedToUsers.removeAt(i);
|
||||
}
|
||||
}
|
||||
mUsersOnDisplaysMap.delete(userId);
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -424,7 +547,7 @@ public final class UserVisibilityMediator implements Dumpable {
|
||||
|
||||
boolean visible;
|
||||
synchronized (mLock) {
|
||||
visible = mUsersOnDisplaysMap.indexOfKey(userId) >= 0;
|
||||
visible = mUsersAssignedToDisplayOnStart.indexOfKey(userId) >= 0;
|
||||
}
|
||||
if (DBG) {
|
||||
Slogf.d(TAG, "isUserVisible(%d): %b from mapping", userId, visible);
|
||||
@@ -448,7 +571,12 @@ public final class UserVisibilityMediator implements Dumpable {
|
||||
}
|
||||
|
||||
synchronized (mLock) {
|
||||
return mUsersOnDisplaysMap.get(userId, Display.INVALID_DISPLAY) == displayId;
|
||||
if (mUsersAssignedToDisplayOnStart.get(userId, Display.INVALID_DISPLAY) == displayId) {
|
||||
// User assigned to display on start
|
||||
return true;
|
||||
}
|
||||
// Check for extra assignment
|
||||
return mExtraDisplaysAssignedToUsers.get(displayId, USER_NULL) == userId;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -465,24 +593,34 @@ public final class UserVisibilityMediator implements Dumpable {
|
||||
}
|
||||
|
||||
synchronized (mLock) {
|
||||
return mUsersOnDisplaysMap.get(userId, Display.INVALID_DISPLAY);
|
||||
return mUsersAssignedToDisplayOnStart.get(userId, Display.INVALID_DISPLAY);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* See {@link UserManagerInternal#getUserAssignedToDisplay(int)}.
|
||||
*/
|
||||
public int getUserAssignedToDisplay(@UserIdInt int displayId) {
|
||||
if (displayId == Display.DEFAULT_DISPLAY || !mVisibleBackgroundUsersEnabled) {
|
||||
public @UserIdInt int getUserAssignedToDisplay(@UserIdInt int displayId) {
|
||||
return getUserAssignedToDisplay(displayId, /* returnCurrentUserByDefault= */ true);
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the user explicitly assigned to a display, or the current user when no user is assigned
|
||||
* to it (and {@code returnCurrentUserByDefault} is {@code true}).
|
||||
*/
|
||||
private @UserIdInt int getUserAssignedToDisplay(@UserIdInt int displayId,
|
||||
boolean returnCurrentUserByDefault) {
|
||||
if (returnCurrentUserByDefault
|
||||
&& (displayId == Display.DEFAULT_DISPLAY || !mVisibleBackgroundUsersEnabled)) {
|
||||
return getCurrentUserId();
|
||||
}
|
||||
|
||||
synchronized (mLock) {
|
||||
for (int i = 0; i < mUsersOnDisplaysMap.size(); i++) {
|
||||
if (mUsersOnDisplaysMap.valueAt(i) != displayId) {
|
||||
for (int i = 0; i < mUsersAssignedToDisplayOnStart.size(); i++) {
|
||||
if (mUsersAssignedToDisplayOnStart.valueAt(i) != displayId) {
|
||||
continue;
|
||||
}
|
||||
int userId = mUsersOnDisplaysMap.keyAt(i);
|
||||
int userId = mUsersAssignedToDisplayOnStart.keyAt(i);
|
||||
if (!isStartedProfile(userId)) {
|
||||
return userId;
|
||||
} else if (DBG) {
|
||||
@@ -491,6 +629,13 @@ public final class UserVisibilityMediator implements Dumpable {
|
||||
}
|
||||
}
|
||||
}
|
||||
if (!returnCurrentUserByDefault) {
|
||||
if (DBG) {
|
||||
Slogf.d(TAG, "getUserAssignedToDisplay(%d): no user assigned to display, returning "
|
||||
+ "USER_NULL instead", displayId);
|
||||
}
|
||||
return USER_NULL;
|
||||
}
|
||||
|
||||
int currentUserId = getCurrentUserId();
|
||||
if (DBG) {
|
||||
@@ -618,9 +763,11 @@ public final class UserVisibilityMediator implements Dumpable {
|
||||
ipw.print("Supports visible background users on displays: ");
|
||||
ipw.println(mVisibleBackgroundUsersEnabled);
|
||||
|
||||
if (mUsersOnDisplaysMap != null) {
|
||||
dumpSparseIntArray(ipw, mUsersOnDisplaysMap, "user / display", "u", "d");
|
||||
}
|
||||
dumpSparseIntArray(ipw, mUsersAssignedToDisplayOnStart, "user / display", "u", "d");
|
||||
|
||||
dumpSparseIntArray(ipw, mExtraDisplaysAssignedToUsers, "extra display / user",
|
||||
"d", "u");
|
||||
|
||||
int numberListeners = mListeners.size();
|
||||
ipw.print("Number of listeners: ");
|
||||
ipw.println(numberListeners);
|
||||
@@ -638,8 +785,14 @@ public final class UserVisibilityMediator implements Dumpable {
|
||||
ipw.decreaseIndent();
|
||||
}
|
||||
|
||||
private static void dumpSparseIntArray(IndentingPrintWriter ipw, SparseIntArray array,
|
||||
private static void dumpSparseIntArray(IndentingPrintWriter ipw, @Nullable SparseIntArray array,
|
||||
String arrayDescription, String keyName, String valueName) {
|
||||
if (array == null) {
|
||||
ipw.print("No ");
|
||||
ipw.print(arrayDescription);
|
||||
ipw.println(" mappings");
|
||||
return;
|
||||
}
|
||||
ipw.print("Number of ");
|
||||
ipw.print(arrayDescription);
|
||||
ipw.print(" mappings: ");
|
||||
|
||||
@@ -49,6 +49,7 @@ public final class UserVisibilityMediatorSUSDTest extends UserVisibilityMediator
|
||||
int result = mMediator.assignUserToDisplayOnStart(USER_ID, USER_ID, FG,
|
||||
DEFAULT_DISPLAY);
|
||||
assertStartUserResult(result, USER_ASSIGNMENT_RESULT_SUCCESS_VISIBLE);
|
||||
expectUserCannotBeUnassignedFromDisplay(USER_ID, DEFAULT_DISPLAY);
|
||||
|
||||
expectUserIsVisible(USER_ID);
|
||||
expectUserIsNotVisibleOnDisplay(USER_ID, INVALID_DISPLAY);
|
||||
@@ -80,6 +81,7 @@ public final class UserVisibilityMediatorSUSDTest extends UserVisibilityMediator
|
||||
int result = mMediator.assignUserToDisplayOnStart(currentUserId, currentUserId, FG,
|
||||
DEFAULT_DISPLAY);
|
||||
assertStartUserResult(result, USER_ASSIGNMENT_RESULT_SUCCESS_VISIBLE);
|
||||
expectUserCannotBeUnassignedFromDisplay(currentUserId, DEFAULT_DISPLAY);
|
||||
|
||||
expectUserIsVisible(currentUserId);
|
||||
expectUserIsNotVisibleOnDisplay(currentUserId, INVALID_DISPLAY);
|
||||
@@ -110,6 +112,7 @@ public final class UserVisibilityMediatorSUSDTest extends UserVisibilityMediator
|
||||
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);
|
||||
|
||||
@@ -165,12 +165,16 @@ abstract class UserVisibilityMediatorTestCase extends ExtendedMockitoTestCase {
|
||||
expectNoDisplayAssignedToUser(USER_ID);
|
||||
expectInitialCurrentUserAssignedToDisplay(DEFAULT_DISPLAY);
|
||||
|
||||
assertInvisibleUserCannotBeAssignedExtraDisplay(USER_ID, SECONDARY_DISPLAY_ID);
|
||||
|
||||
listener.verify();
|
||||
}
|
||||
|
||||
@Test
|
||||
public final void testStartVisibleBgUser_onDefaultDisplay() throws Exception {
|
||||
visibleBgUserCannotBeStartedOnDefaultDisplayTest();
|
||||
|
||||
assertInvisibleUserCannotBeAssignedExtraDisplay(USER_ID, SECONDARY_DISPLAY_ID);
|
||||
}
|
||||
|
||||
protected final void visibleBgUserCannotBeStartedOnDefaultDisplayTest() throws Exception {
|
||||
@@ -180,8 +184,8 @@ abstract class UserVisibilityMediatorTestCase extends ExtendedMockitoTestCase {
|
||||
DEFAULT_DISPLAY);
|
||||
assertStartUserResult(result, USER_ASSIGNMENT_RESULT_FAILURE);
|
||||
|
||||
expectUserIsNotVisibleAtAll(PROFILE_USER_ID);
|
||||
expectNoDisplayAssignedToUser(PROFILE_USER_ID);
|
||||
expectUserIsNotVisibleAtAll(USER_ID);
|
||||
expectNoDisplayAssignedToUser(USER_ID);
|
||||
|
||||
listener.verify();
|
||||
}
|
||||
@@ -194,8 +198,11 @@ abstract class UserVisibilityMediatorTestCase extends ExtendedMockitoTestCase {
|
||||
SECONDARY_DISPLAY_ID);
|
||||
assertStartUserResult(result, USER_ASSIGNMENT_RESULT_FAILURE);
|
||||
|
||||
expectUserIsNotVisibleAtAll(PROFILE_USER_ID);
|
||||
expectNoDisplayAssignedToUser(PROFILE_USER_ID);
|
||||
expectUserIsNotVisibleAtAll(USER_ID);
|
||||
expectNoDisplayAssignedToUser(USER_ID);
|
||||
|
||||
assertInvisibleUserCannotBeAssignedExtraDisplay(USER_ID, SECONDARY_DISPLAY_ID);
|
||||
assertInvisibleUserCannotBeAssignedExtraDisplay(USER_ID, OTHER_SECONDARY_DISPLAY_ID);
|
||||
|
||||
listener.verify();
|
||||
}
|
||||
@@ -217,6 +224,9 @@ abstract class UserVisibilityMediatorTestCase extends ExtendedMockitoTestCase {
|
||||
expectNoDisplayAssignedToUser(USER_SYSTEM);
|
||||
expectUserAssignedToDisplay(SECONDARY_DISPLAY_ID, USER_ID);
|
||||
|
||||
assertUserCannotBeAssignedExtraDisplay(USER_SYSTEM, SECONDARY_DISPLAY_ID);
|
||||
assertUserCannotBeAssignedExtraDisplay(USER_SYSTEM, OTHER_SECONDARY_DISPLAY_ID);
|
||||
|
||||
listener.verify();
|
||||
}
|
||||
|
||||
@@ -256,6 +266,8 @@ abstract class UserVisibilityMediatorTestCase extends ExtendedMockitoTestCase {
|
||||
expectNoDisplayAssignedToUser(PROFILE_USER_ID);
|
||||
expectUserAssignedToDisplay(DEFAULT_DISPLAY, OTHER_USER_ID);
|
||||
|
||||
assertUserCannotBeAssignedExtraDisplay(PROFILE_USER_ID, SECONDARY_DISPLAY_ID);
|
||||
|
||||
listener.verify();
|
||||
}
|
||||
|
||||
@@ -289,6 +301,8 @@ abstract class UserVisibilityMediatorTestCase extends ExtendedMockitoTestCase {
|
||||
expectNoDisplayAssignedToUser(PROFILE_USER_ID);
|
||||
expectInitialCurrentUserAssignedToDisplay(DEFAULT_DISPLAY);
|
||||
|
||||
assertUserCannotBeAssignedExtraDisplay(PROFILE_USER_ID, SECONDARY_DISPLAY_ID);
|
||||
|
||||
listener.verify();
|
||||
}
|
||||
|
||||
@@ -305,6 +319,10 @@ abstract class UserVisibilityMediatorTestCase extends ExtendedMockitoTestCase {
|
||||
expectNoDisplayAssignedToUser(PROFILE_USER_ID);
|
||||
expectInitialCurrentUserAssignedToDisplay(SECONDARY_DISPLAY_ID);
|
||||
|
||||
assertInvisibleUserCannotBeAssignedExtraDisplay(PROFILE_USER_ID, SECONDARY_DISPLAY_ID);
|
||||
assertInvisibleUserCannotBeAssignedExtraDisplay(PROFILE_USER_ID,
|
||||
OTHER_SECONDARY_DISPLAY_ID);
|
||||
|
||||
listener.verify();
|
||||
}
|
||||
|
||||
@@ -320,6 +338,10 @@ abstract class UserVisibilityMediatorTestCase extends ExtendedMockitoTestCase {
|
||||
expectNoDisplayAssignedToUser(PROFILE_USER_ID);
|
||||
expectInitialCurrentUserAssignedToDisplay(SECONDARY_DISPLAY_ID);
|
||||
|
||||
assertInvisibleUserCannotBeAssignedExtraDisplay(PROFILE_USER_ID, SECONDARY_DISPLAY_ID);
|
||||
assertInvisibleUserCannotBeAssignedExtraDisplay(PROFILE_USER_ID,
|
||||
OTHER_SECONDARY_DISPLAY_ID);
|
||||
|
||||
listener.verify();
|
||||
}
|
||||
|
||||
@@ -336,6 +358,9 @@ abstract class UserVisibilityMediatorTestCase extends ExtendedMockitoTestCase {
|
||||
expectNoDisplayAssignedToUser(PROFILE_USER_ID);
|
||||
expectInitialCurrentUserAssignedToDisplay(DEFAULT_DISPLAY);
|
||||
|
||||
assertInvisibleUserCannotBeAssignedExtraDisplay(PROFILE_USER_ID, DEFAULT_DISPLAY);
|
||||
assertInvisibleUserCannotBeAssignedExtraDisplay(PROFILE_USER_ID, SECONDARY_DISPLAY_ID);
|
||||
|
||||
listener.verify();
|
||||
}
|
||||
|
||||
@@ -351,6 +376,10 @@ abstract class UserVisibilityMediatorTestCase extends ExtendedMockitoTestCase {
|
||||
expectNoDisplayAssignedToUser(PROFILE_USER_ID);
|
||||
expectInitialCurrentUserAssignedToDisplay(SECONDARY_DISPLAY_ID);
|
||||
|
||||
assertInvisibleUserCannotBeAssignedExtraDisplay(PROFILE_USER_ID, SECONDARY_DISPLAY_ID);
|
||||
assertInvisibleUserCannotBeAssignedExtraDisplay(PROFILE_USER_ID,
|
||||
OTHER_SECONDARY_DISPLAY_ID);
|
||||
|
||||
listener.verify();
|
||||
}
|
||||
|
||||
@@ -481,6 +510,63 @@ abstract class UserVisibilityMediatorTestCase extends ExtendedMockitoTestCase {
|
||||
.that(actualResult).isEqualTo(expectedResult);
|
||||
}
|
||||
|
||||
protected void assertBgUserBecomesInvisibleOnStop(@UserIdInt int userId) {
|
||||
Log.d(TAG, "Stopping user " + userId);
|
||||
mMediator.unassignUserFromDisplayOnStop(userId);
|
||||
expectUserIsNotVisibleAtAll(userId);
|
||||
}
|
||||
|
||||
/**
|
||||
* Assigns and unassigns the user to / from an extra display, asserting the visibility state in
|
||||
* between.
|
||||
*
|
||||
* <p>It assumes the user was not visible in the display beforehand.
|
||||
*/
|
||||
protected void assertUserCanBeAssignedExtraDisplay(@UserIdInt int userId, int displayId) {
|
||||
assertUserCanBeAssignedExtraDisplay(userId, displayId, /* unassign= */ true);
|
||||
}
|
||||
|
||||
protected void assertUserCanBeAssignedExtraDisplay(@UserIdInt int userId, int displayId,
|
||||
boolean unassign) {
|
||||
|
||||
expectUserIsNotVisibleOnDisplay(userId, displayId);
|
||||
|
||||
Log.d(TAG, "Calling assignUserToExtraDisplay(" + userId + ", " + displayId + ")");
|
||||
assertWithMessage("assignUserToExtraDisplay(%s, %s)", userId, displayId)
|
||||
.that(mMediator.assignUserToExtraDisplay(userId, displayId))
|
||||
.isTrue();
|
||||
expectUserIsVisibleOnDisplay(userId, displayId);
|
||||
|
||||
if (unassign) {
|
||||
Log.d(TAG, "Calling unassignUserFromExtraDisplay(" + userId + ", " + displayId + ")");
|
||||
assertWithMessage("unassignUserFromExtraDisplay(%s, %s)", userId, displayId)
|
||||
.that(mMediator.unassignUserFromExtraDisplay(userId, displayId))
|
||||
.isTrue();
|
||||
expectUserIsNotVisibleOnDisplay(userId, displayId);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Asserts that a user (already visible or not) cannot be assigned to an extra display (and
|
||||
* hence won't be visible on that display).
|
||||
*/
|
||||
protected void assertUserCannotBeAssignedExtraDisplay(@UserIdInt int userId, int displayId) {
|
||||
expectWithMessage("assignUserToExtraDisplay(%s, %s)", userId, displayId)
|
||||
.that(mMediator.assignUserToExtraDisplay(userId, displayId))
|
||||
.isFalse();
|
||||
expectUserIsNotVisibleOnDisplay(userId, displayId);
|
||||
}
|
||||
|
||||
/**
|
||||
* Asserts that an invisible user cannot be assigned to an extra display.
|
||||
*/
|
||||
protected void assertInvisibleUserCannotBeAssignedExtraDisplay(@UserIdInt int userId,
|
||||
int displayId) {
|
||||
assertUserCannotBeAssignedExtraDisplay(userId, displayId);
|
||||
expectNoDisplayAssignedToUser(userId);
|
||||
expectInitialCurrentUserAssignedToDisplay(displayId);
|
||||
}
|
||||
|
||||
protected void expectUserIsVisible(@UserIdInt int userId) {
|
||||
expectWithMessage("isUserVisible(%s)", userId)
|
||||
.that(mMediator.isUserVisible(userId))
|
||||
@@ -534,6 +620,11 @@ abstract class UserVisibilityMediatorTestCase extends ExtendedMockitoTestCase {
|
||||
.that(mMediator.getDisplayAssignedToUser(userId)).isEqualTo(INVALID_DISPLAY);
|
||||
}
|
||||
|
||||
protected void expectUserCannotBeUnassignedFromDisplay(@UserIdInt int userId, int displayId) {
|
||||
expectWithMessage("unassignUserFromExtraDisplay(%s, %s)", userId, displayId)
|
||||
.that(mMediator.unassignUserFromExtraDisplay(userId, displayId)).isFalse();
|
||||
}
|
||||
|
||||
protected void expectUserAssignedToDisplay(int displayId, @UserIdInt int userId) {
|
||||
expectWithMessage("getUserAssignedToDisplay(%s)", displayId)
|
||||
.that(mMediator.getUserAssignedToDisplay(displayId)).isEqualTo(userId);
|
||||
|
||||
@@ -52,6 +52,7 @@ abstract class UserVisibilityMediatorVisibleBackgroundUserTestCase
|
||||
int result = mMediator.assignUserToDisplayOnStart(USER_ID, USER_ID, FG,
|
||||
DEFAULT_DISPLAY);
|
||||
assertStartUserResult(result, USER_ASSIGNMENT_RESULT_SUCCESS_VISIBLE);
|
||||
expectUserCannotBeUnassignedFromDisplay(USER_ID, DEFAULT_DISPLAY);
|
||||
|
||||
expectUserIsVisible(USER_ID);
|
||||
expectUserIsVisibleOnDisplay(USER_ID, DEFAULT_DISPLAY);
|
||||
@@ -64,7 +65,9 @@ abstract class UserVisibilityMediatorVisibleBackgroundUserTestCase
|
||||
expectUserAssignedToDisplay(INVALID_DISPLAY, USER_ID);
|
||||
expectUserAssignedToDisplay(SECONDARY_DISPLAY_ID, USER_ID);
|
||||
|
||||
expectDisplayAssignedToUser(USER_NULL, INVALID_DISPLAY);
|
||||
expectNoDisplayAssignedToUser(USER_NULL);
|
||||
|
||||
assertUserCanBeAssignedExtraDisplay(USER_ID, SECONDARY_DISPLAY_ID);
|
||||
|
||||
listener.verify();
|
||||
}
|
||||
@@ -83,6 +86,7 @@ abstract class UserVisibilityMediatorVisibleBackgroundUserTestCase
|
||||
int result = mMediator.assignUserToDisplayOnStart(currentUserId, currentUserId, FG,
|
||||
DEFAULT_DISPLAY);
|
||||
assertStartUserResult(result, USER_ASSIGNMENT_RESULT_SUCCESS_VISIBLE);
|
||||
expectUserCannotBeUnassignedFromDisplay(currentUserId, DEFAULT_DISPLAY);
|
||||
|
||||
expectUserIsVisible(currentUserId);
|
||||
expectUserIsVisibleOnDisplay(currentUserId, DEFAULT_DISPLAY);
|
||||
@@ -98,6 +102,8 @@ abstract class UserVisibilityMediatorVisibleBackgroundUserTestCase
|
||||
expectUserIsNotVisibleAtAll(previousCurrentUserId);
|
||||
expectNoDisplayAssignedToUser(previousCurrentUserId);
|
||||
|
||||
assertUserCanBeAssignedExtraDisplay(USER_ID, SECONDARY_DISPLAY_ID);
|
||||
|
||||
listener.verify();
|
||||
}
|
||||
|
||||
@@ -113,6 +119,7 @@ abstract class UserVisibilityMediatorVisibleBackgroundUserTestCase
|
||||
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);
|
||||
@@ -123,6 +130,8 @@ abstract class UserVisibilityMediatorVisibleBackgroundUserTestCase
|
||||
expectDisplayAssignedToUser(PROFILE_USER_ID, DEFAULT_DISPLAY);
|
||||
expectUserAssignedToDisplay(DEFAULT_DISPLAY, PARENT_USER_ID);
|
||||
|
||||
assertUserCannotBeAssignedExtraDisplay(PROFILE_USER_ID, SECONDARY_DISPLAY_ID);
|
||||
|
||||
listener.verify();
|
||||
}
|
||||
|
||||
@@ -134,6 +143,9 @@ abstract class UserVisibilityMediatorVisibleBackgroundUserTestCase
|
||||
|
||||
assertStartUserResult(result, USER_ASSIGNMENT_RESULT_FAILURE);
|
||||
|
||||
assertInvisibleUserCannotBeAssignedExtraDisplay(USER_ID, DEFAULT_DISPLAY);
|
||||
assertInvisibleUserCannotBeAssignedExtraDisplay(USER_ID, SECONDARY_DISPLAY_ID);
|
||||
|
||||
listener.verify();
|
||||
}
|
||||
|
||||
@@ -148,6 +160,9 @@ abstract class UserVisibilityMediatorVisibleBackgroundUserTestCase
|
||||
|
||||
expectUserIsNotVisibleAtAll(USER_ID);
|
||||
|
||||
assertInvisibleUserCannotBeAssignedExtraDisplay(USER_ID, DEFAULT_DISPLAY);
|
||||
assertInvisibleUserCannotBeAssignedExtraDisplay(USER_ID, SECONDARY_DISPLAY_ID);
|
||||
|
||||
listener.verify();
|
||||
}
|
||||
|
||||
@@ -159,6 +174,7 @@ abstract class UserVisibilityMediatorVisibleBackgroundUserTestCase
|
||||
int result = mMediator.assignUserToDisplayOnStart(USER_ID, USER_ID, BG_VISIBLE,
|
||||
SECONDARY_DISPLAY_ID);
|
||||
assertStartUserResult(result, USER_ASSIGNMENT_RESULT_SUCCESS_VISIBLE);
|
||||
expectUserCannotBeUnassignedFromDisplay(USER_ID, SECONDARY_DISPLAY_ID);
|
||||
|
||||
expectUserIsVisible(USER_ID);
|
||||
expectUserIsVisibleOnDisplay(USER_ID, SECONDARY_DISPLAY_ID);
|
||||
@@ -169,7 +185,16 @@ abstract class UserVisibilityMediatorVisibleBackgroundUserTestCase
|
||||
expectDisplayAssignedToUser(USER_ID, SECONDARY_DISPLAY_ID);
|
||||
expectUserAssignedToDisplay(SECONDARY_DISPLAY_ID, USER_ID);
|
||||
|
||||
listener.verify();
|
||||
assertUserCanBeAssignedExtraDisplay(USER_ID, OTHER_SECONDARY_DISPLAY_ID);
|
||||
|
||||
// Assign again, without unassigning (to make sure it becomes invisible on stop)
|
||||
AsyncUserVisibilityListener listener2 = addListenerForEvents(onInvisible(USER_ID));
|
||||
assertUserCanBeAssignedExtraDisplay(USER_ID, OTHER_SECONDARY_DISPLAY_ID,
|
||||
/* unassign= */ false);
|
||||
|
||||
assertBgUserBecomesInvisibleOnStop(USER_ID);
|
||||
|
||||
listener2.verify();
|
||||
}
|
||||
|
||||
@Test
|
||||
@@ -203,6 +228,8 @@ abstract class UserVisibilityMediatorVisibleBackgroundUserTestCase
|
||||
expectNoDisplayAssignedToUser(USER_ID);
|
||||
expectUserAssignedToDisplay(SECONDARY_DISPLAY_ID, OTHER_USER_ID);
|
||||
|
||||
assertUserCannotBeAssignedExtraDisplay(USER_ID, SECONDARY_DISPLAY_ID);
|
||||
|
||||
listener.verify();
|
||||
}
|
||||
|
||||
@@ -226,7 +253,18 @@ abstract class UserVisibilityMediatorVisibleBackgroundUserTestCase
|
||||
expectDisplayAssignedToUser(USER_ID, OTHER_SECONDARY_DISPLAY_ID);
|
||||
expectUserAssignedToDisplay(OTHER_SECONDARY_DISPLAY_ID, USER_ID);
|
||||
|
||||
assertUserCanBeAssignedExtraDisplay(USER_ID, SECONDARY_DISPLAY_ID);
|
||||
|
||||
listener.verify();
|
||||
|
||||
// Assign again, without unassigning (to make sure it becomes invisible on stop)
|
||||
AsyncUserVisibilityListener listener2 = addListenerForEvents(onInvisible(USER_ID));
|
||||
assertUserCanBeAssignedExtraDisplay(USER_ID, SECONDARY_DISPLAY_ID,
|
||||
/* unassign= */ false);
|
||||
|
||||
assertBgUserBecomesInvisibleOnStop(USER_ID);
|
||||
|
||||
listener2.verify();
|
||||
}
|
||||
|
||||
@Test
|
||||
@@ -244,12 +282,14 @@ abstract class UserVisibilityMediatorVisibleBackgroundUserTestCase
|
||||
expectNoDisplayAssignedToUser(PROFILE_USER_ID);
|
||||
expectUserAssignedToDisplay(OTHER_SECONDARY_DISPLAY_ID, PARENT_USER_ID);
|
||||
|
||||
assertInvisibleUserCannotBeAssignedExtraDisplay(PROFILE_USER_ID, SECONDARY_DISPLAY_ID);
|
||||
|
||||
listener.verify();
|
||||
}
|
||||
|
||||
// Conditions below are asserted on other tests, but they're explicitly checked in the 2
|
||||
// tests below (which call this method) as well
|
||||
private void currentUserVisibilityWhenNoDisplayIsAssignedTest(@UserIdInt int currentUserId) {
|
||||
// Conditions below are asserted on other tests, but they're explicitly checked in the 2
|
||||
// tests below as well
|
||||
expectUserIsVisible(currentUserId);
|
||||
expectUserIsVisibleOnDisplay(currentUserId, DEFAULT_DISPLAY);
|
||||
expectUserIsNotVisibleOnDisplay(currentUserId, SECONDARY_DISPLAY_ID);
|
||||
@@ -277,4 +317,13 @@ abstract class UserVisibilityMediatorVisibleBackgroundUserTestCase
|
||||
expectUserIsNotVisibleAtAll(INITIAL_CURRENT_USER_ID);
|
||||
expectDisplayAssignedToUser(INITIAL_CURRENT_USER_ID, INVALID_DISPLAY);
|
||||
}
|
||||
|
||||
@Test
|
||||
public final void testAssignUserToExtraDisplay_invalidDisplays() throws Exception {
|
||||
expectWithMessage("assignUserToExtraDisplay(%s, %s)", USER_ID, INVALID_DISPLAY)
|
||||
.that(mMediator.assignUserToExtraDisplay(USER_ID, INVALID_DISPLAY)).isFalse();
|
||||
// DEFAULT_DISPLAY is always assigned to the current user
|
||||
expectWithMessage("assignUserToExtraDisplay(%s, %s)", USER_ID, DEFAULT_DISPLAY)
|
||||
.that(mMediator.assignUserToExtraDisplay(USER_ID, DEFAULT_DISPLAY)).isFalse();
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user