Merge "Changed behavior of isUserVisible() for current user on MUMD devices."

This commit is contained in:
TreeHugger Robot
2022-11-28 19:46:58 +00:00
committed by Android (Google) Code Review
5 changed files with 192 additions and 124 deletions

View File

@@ -413,41 +413,12 @@ public final class UserVisibilityMediator implements Dumpable {
if (displayId == Display.INVALID_DISPLAY) {
return false;
}
if (!mUsersOnSecondaryDisplaysEnabled) {
return isCurrentUserOrRunningProfileOfCurrentUser(userId);
}
// TODO(b/256242848): temporary workaround to let WM use this API without breaking current
// behavior - return true for current user / profile for any display (other than those
// explicitly assigned to another users), otherwise they wouldn't be able to launch
// activities on other non-passenger displays, like cluster).
// In the long-term, it should rely just on mUsersOnSecondaryDisplays, which
// would be updated by CarService to allow additional mappings.
if (isCurrentUserOrRunningProfileOfCurrentUser(userId)) {
synchronized (mLock) {
boolean assignedToUser = false;
boolean assignedToAnotherUser = false;
for (int i = 0; i < mUsersOnSecondaryDisplays.size(); i++) {
if (mUsersOnSecondaryDisplays.valueAt(i) == displayId) {
if (mUsersOnSecondaryDisplays.keyAt(i) == userId) {
assignedToUser = true;
break;
} else {
assignedToAnotherUser = true;
// Cannot break because it could be assigned to a profile of the user
// (and we better not assume that the iteration will check for the
// parent user before its profiles)
}
}
}
if (DBG) {
Slogf.d(TAG, "isUserVisibleOnDisplay(%d, %d): assignedToUser=%b, "
+ "assignedToAnotherUser=%b, mUsersOnSecondaryDisplays=%s",
userId, displayId, assignedToUser, assignedToAnotherUser,
mUsersOnSecondaryDisplays);
}
return assignedToUser || !assignedToAnotherUser;
}
if (!mUsersOnSecondaryDisplaysEnabled || displayId == Display.DEFAULT_DISPLAY) {
// TODO(b/245939659): will need to move the displayId == Display.DEFAULT_DISPLAY outside
// once it supports background users on DEFAULT_DISPLAY (for example, passengers in a
// no-driver configuration)
return isCurrentUserOrRunningProfileOfCurrentUser(userId);
}
synchronized (mLock) {

View File

@@ -40,7 +40,6 @@ public final class AsyncUserVisibilityListener implements UserVisibilityListener
private static final String TAG = AsyncUserVisibilityListener.class.getSimpleName();
private static final long WAIT_TIMEOUT_MS = 2_000;
private static final long WAIT_NO_EVENTS_TIMEOUT_MS = 100;
private static int sNextId;

View File

@@ -15,12 +15,14 @@
*/
package com.android.server.pm;
import static android.os.UserHandle.USER_NULL;
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;
import static com.android.server.pm.UserManagerInternal.USER_ASSIGNMENT_RESULT_SUCCESS_VISIBLE;
import static com.android.server.pm.UserVisibilityChangedEvent.onInvisible;
import static com.android.server.pm.UserVisibilityChangedEvent.onVisible;
import static com.android.server.pm.UserVisibilityMediator.INITIAL_CURRENT_USER_ID;
@@ -39,6 +41,88 @@ public final class UserVisibilityMediatorMUMDTest extends UserVisibilityMediator
super(/* usersOnSecondaryDisplaysEnabled= */ true);
}
@Test
public void testStartFgUser_onDefaultDisplay() throws Exception {
AsyncUserVisibilityListener listener = addListenerForEvents(
onInvisible(INITIAL_CURRENT_USER_ID),
onVisible(USER_ID));
int result = mMediator.assignUserToDisplayOnStart(USER_ID, USER_ID, FG,
DEFAULT_DISPLAY);
assertStartUserResult(result, USER_ASSIGNMENT_RESULT_SUCCESS_VISIBLE);
expectUserIsVisible(USER_ID);
expectUserIsVisibleOnDisplay(USER_ID, DEFAULT_DISPLAY);
expectUserIsNotVisibleOnDisplay(USER_ID, INVALID_DISPLAY);
expectUserIsNotVisibleOnDisplay(USER_ID, SECONDARY_DISPLAY_ID);
expectVisibleUsers(USER_ID);
expectDisplayAssignedToUser(USER_ID, DEFAULT_DISPLAY);
expectUserAssignedToDisplay(DEFAULT_DISPLAY, USER_ID);
expectUserAssignedToDisplay(INVALID_DISPLAY, USER_ID);
expectUserAssignedToDisplay(SECONDARY_DISPLAY_ID, USER_ID);
expectDisplayAssignedToUser(USER_NULL, INVALID_DISPLAY);
listener.verify();
}
@Test
public void testSwitchFgUser_onDefaultDisplay() throws Exception {
int previousCurrentUserId = OTHER_USER_ID;
int currentUserId = USER_ID;
AsyncUserVisibilityListener listener = addListenerForEvents(
onInvisible(INITIAL_CURRENT_USER_ID),
onVisible(previousCurrentUserId),
onInvisible(previousCurrentUserId),
onVisible(currentUserId));
startForegroundUser(previousCurrentUserId);
int result = mMediator.assignUserToDisplayOnStart(currentUserId, currentUserId, FG,
DEFAULT_DISPLAY);
assertStartUserResult(result, USER_ASSIGNMENT_RESULT_SUCCESS_VISIBLE);
expectUserIsVisible(currentUserId);
expectUserIsVisibleOnDisplay(currentUserId, DEFAULT_DISPLAY);
expectUserIsNotVisibleOnDisplay(currentUserId, INVALID_DISPLAY);
expectUserIsNotVisibleOnDisplay(currentUserId, SECONDARY_DISPLAY_ID);
expectVisibleUsers(currentUserId);
expectDisplayAssignedToUser(currentUserId, DEFAULT_DISPLAY);
expectUserAssignedToDisplay(DEFAULT_DISPLAY, currentUserId);
expectUserAssignedToDisplay(INVALID_DISPLAY, currentUserId);
expectUserAssignedToDisplay(SECONDARY_DISPLAY_ID, currentUserId);
expectUserIsNotVisibleAtAll(previousCurrentUserId);
expectNoDisplayAssignedToUser(previousCurrentUserId);
listener.verify();
}
@Test
public void testStartBgProfile_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,
DEFAULT_DISPLAY);
assertStartUserResult(result, USER_ASSIGNMENT_RESULT_SUCCESS_VISIBLE);
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);
listener.verify();
}
@Test
public void testStartFgUser_onInvalidDisplay() throws Exception {
AsyncUserVisibilityListener listener = addListenerForNoEvents();
@@ -89,15 +173,15 @@ public final class UserVisibilityMediatorMUMDTest extends UserVisibilityMediator
startDefaultProfile();
// Make sure they were visible before
expectUserIsVisibleOnDisplay(PARENT_USER_ID, SECONDARY_DISPLAY_ID);
expectUserIsVisibleOnDisplay(PROFILE_USER_ID, SECONDARY_DISPLAY_ID);
expectUserIsNotVisibleOnDisplay("before", PARENT_USER_ID, SECONDARY_DISPLAY_ID);
expectUserIsNotVisibleOnDisplay("before", PROFILE_USER_ID, SECONDARY_DISPLAY_ID);
int result = mMediator.assignUserToDisplayOnStart(USER_ID, USER_ID, BG,
SECONDARY_DISPLAY_ID);
assertStartUserResult(result, USER_ASSIGNMENT_RESULT_SUCCESS_VISIBLE);
expectUserIsNotVisibleOnDisplay(PARENT_USER_ID, SECONDARY_DISPLAY_ID);
expectUserIsNotVisibleOnDisplay(PROFILE_USER_ID, SECONDARY_DISPLAY_ID);
expectUserIsNotVisibleOnDisplay("after", PARENT_USER_ID, SECONDARY_DISPLAY_ID);
expectUserIsNotVisibleOnDisplay("after", PROFILE_USER_ID, SECONDARY_DISPLAY_ID);
}
@Test

View File

@@ -15,7 +15,15 @@
*/
package com.android.server.pm;
import static android.os.UserHandle.USER_NULL;
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_VISIBLE;
import static com.android.server.pm.UserVisibilityChangedEvent.onInvisible;
import static com.android.server.pm.UserVisibilityChangedEvent.onVisible;
import static com.android.server.pm.UserVisibilityMediator.INITIAL_CURRENT_USER_ID;
import org.junit.Test;
@@ -32,6 +40,88 @@ public final class UserVisibilityMediatorSUSDTest extends UserVisibilityMediator
super(/* usersOnSecondaryDisplaysEnabled= */ false);
}
@Test
public void testStartFgUser_onDefaultDisplay() throws Exception {
AsyncUserVisibilityListener listener = addListenerForEvents(
onInvisible(INITIAL_CURRENT_USER_ID),
onVisible(USER_ID));
int result = mMediator.assignUserToDisplayOnStart(USER_ID, USER_ID, FG,
DEFAULT_DISPLAY);
assertStartUserResult(result, USER_ASSIGNMENT_RESULT_SUCCESS_VISIBLE);
expectUserIsVisible(USER_ID);
expectUserIsNotVisibleOnDisplay(USER_ID, INVALID_DISPLAY);
expectUserIsVisibleOnDisplay(USER_ID, DEFAULT_DISPLAY);
expectUserIsVisibleOnDisplay(USER_ID, SECONDARY_DISPLAY_ID);
expectVisibleUsers(USER_ID);
expectDisplayAssignedToUser(USER_ID, DEFAULT_DISPLAY);
expectUserAssignedToDisplay(DEFAULT_DISPLAY, USER_ID);
expectUserAssignedToDisplay(INVALID_DISPLAY, USER_ID);
expectUserAssignedToDisplay(SECONDARY_DISPLAY_ID, USER_ID);
expectDisplayAssignedToUser(USER_NULL, INVALID_DISPLAY);
listener.verify();
}
@Test
public void testSwitchFgUser_onDefaultDisplay() throws Exception {
int previousCurrentUserId = OTHER_USER_ID;
int currentUserId = USER_ID;
AsyncUserVisibilityListener listener = addListenerForEvents(
onInvisible(INITIAL_CURRENT_USER_ID),
onVisible(previousCurrentUserId),
onInvisible(previousCurrentUserId),
onVisible(currentUserId));
startForegroundUser(previousCurrentUserId);
int result = mMediator.assignUserToDisplayOnStart(currentUserId, currentUserId, FG,
DEFAULT_DISPLAY);
assertStartUserResult(result, USER_ASSIGNMENT_RESULT_SUCCESS_VISIBLE);
expectUserIsVisible(currentUserId);
expectUserIsNotVisibleOnDisplay(currentUserId, INVALID_DISPLAY);
expectUserIsVisibleOnDisplay(currentUserId, DEFAULT_DISPLAY);
expectUserIsVisibleOnDisplay(currentUserId, SECONDARY_DISPLAY_ID);
expectVisibleUsers(currentUserId);
expectDisplayAssignedToUser(currentUserId, DEFAULT_DISPLAY);
expectUserAssignedToDisplay(DEFAULT_DISPLAY, currentUserId);
expectUserAssignedToDisplay(INVALID_DISPLAY, currentUserId);
expectUserAssignedToDisplay(SECONDARY_DISPLAY_ID, currentUserId);
expectUserIsNotVisibleAtAll(previousCurrentUserId);
expectNoDisplayAssignedToUser(previousCurrentUserId);
listener.verify();
}
@Test
public void testStartBgProfile_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,
DEFAULT_DISPLAY);
assertStartUserResult(result, USER_ASSIGNMENT_RESULT_SUCCESS_VISIBLE);
expectUserIsVisible(PROFILE_USER_ID);
expectUserIsNotVisibleOnDisplay(PROFILE_USER_ID, INVALID_DISPLAY);
expectUserIsVisibleOnDisplay(PROFILE_USER_ID, DEFAULT_DISPLAY);
expectUserIsVisibleOnDisplay(PROFILE_USER_ID, SECONDARY_DISPLAY_ID);
expectVisibleUsers(PARENT_USER_ID, PROFILE_USER_ID);
expectDisplayAssignedToUser(PROFILE_USER_ID, DEFAULT_DISPLAY);
expectUserAssignedToDisplay(DEFAULT_DISPLAY, PARENT_USER_ID);
listener.verify();
}
@Test
public void testStartBgUser_onSecondaryDisplay() throws Exception {
AsyncUserVisibilityListener listener = addListenerForNoEvents();

View File

@@ -37,6 +37,7 @@ import static org.junit.Assert.assertThrows;
import android.annotation.UserIdInt;
import android.os.Handler;
import android.text.TextUtils;
import android.util.IntArray;
import android.util.Log;
@@ -134,66 +135,6 @@ abstract class UserVisibilityMediatorTestCase extends ExtendedMockitoTestCase {
.assignUserToDisplayOnStart(USER_CURRENT_OR_SELF, USER_ID, FG, DEFAULT_DISPLAY));
}
@Test
public final void testStartFgUser_onDefaultDisplay() throws Exception {
AsyncUserVisibilityListener listener = addListenerForEvents(
onInvisible(INITIAL_CURRENT_USER_ID),
onVisible(USER_ID));
int result = mMediator.assignUserToDisplayOnStart(USER_ID, USER_ID, FG,
DEFAULT_DISPLAY);
assertStartUserResult(result, USER_ASSIGNMENT_RESULT_SUCCESS_VISIBLE);
expectUserIsVisible(USER_ID);
expectUserIsNotVisibleOnDisplay(USER_ID, INVALID_DISPLAY);
expectUserIsVisibleOnDisplay(USER_ID, DEFAULT_DISPLAY);
// TODO(b/244644281): once isUserVisible() is fixed (see note there), this assertion will
// fail on MUMD, so we'll need to refactor / split this test (and possibly others)
expectUserIsVisibleOnDisplay(USER_ID, SECONDARY_DISPLAY_ID);
expectVisibleUsers(USER_ID);
expectDisplayAssignedToUser(USER_ID, DEFAULT_DISPLAY);
expectUserAssignedToDisplay(DEFAULT_DISPLAY, USER_ID);
expectUserAssignedToDisplay(INVALID_DISPLAY, USER_ID);
expectUserAssignedToDisplay(SECONDARY_DISPLAY_ID, USER_ID);
expectDisplayAssignedToUser(USER_NULL, INVALID_DISPLAY);
listener.verify();
}
@Test
public final void testSwitchFgUser_onDefaultDisplay() throws Exception {
int previousCurrentUserId = OTHER_USER_ID;
int currentUserId = USER_ID;
AsyncUserVisibilityListener listener = addListenerForEvents(
onInvisible(INITIAL_CURRENT_USER_ID),
onVisible(previousCurrentUserId),
onInvisible(previousCurrentUserId),
onVisible(currentUserId));
startForegroundUser(previousCurrentUserId);
int result = mMediator.assignUserToDisplayOnStart(currentUserId, currentUserId, FG,
DEFAULT_DISPLAY);
assertStartUserResult(result, USER_ASSIGNMENT_RESULT_SUCCESS_VISIBLE);
expectUserIsVisible(currentUserId);
expectUserIsNotVisibleOnDisplay(currentUserId, INVALID_DISPLAY);
expectUserIsVisibleOnDisplay(currentUserId, DEFAULT_DISPLAY);
expectUserIsVisibleOnDisplay(currentUserId, SECONDARY_DISPLAY_ID);
expectVisibleUsers(currentUserId);
expectDisplayAssignedToUser(currentUserId, DEFAULT_DISPLAY);
expectUserAssignedToDisplay(DEFAULT_DISPLAY, currentUserId);
expectUserAssignedToDisplay(INVALID_DISPLAY, currentUserId);
expectUserAssignedToDisplay(SECONDARY_DISPLAY_ID, currentUserId);
expectUserIsNotVisibleAtAll(previousCurrentUserId);
expectNoDisplayAssignedToUser(previousCurrentUserId);
listener.verify();
}
@Test
public final void testStartFgUser_onSecondaryDisplay() throws Exception {
AsyncUserVisibilityListener listener = addListenerForNoEvents();
@@ -244,31 +185,6 @@ abstract class UserVisibilityMediatorTestCase extends ExtendedMockitoTestCase {
listener.verify();
}
@Test
public final void testStartBgProfile_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,
DEFAULT_DISPLAY);
assertStartUserResult(result, USER_ASSIGNMENT_RESULT_SUCCESS_VISIBLE);
expectUserIsVisible(PROFILE_USER_ID);
expectUserIsNotVisibleOnDisplay(PROFILE_USER_ID, INVALID_DISPLAY);
expectUserIsVisibleOnDisplay(PROFILE_USER_ID, DEFAULT_DISPLAY);
expectUserIsVisibleOnDisplay(PROFILE_USER_ID, SECONDARY_DISPLAY_ID);
expectVisibleUsers(PARENT_USER_ID, PROFILE_USER_ID);
expectDisplayAssignedToUser(PROFILE_USER_ID, DEFAULT_DISPLAY);
expectUserAssignedToDisplay(DEFAULT_DISPLAY, PARENT_USER_ID);
listener.verify();
}
@Test
public final void testStopVisibleProfile() throws Exception {
AsyncUserVisibilityListener listener = addListenerForEvents(
@@ -530,6 +446,14 @@ abstract class UserVisibilityMediatorTestCase extends ExtendedMockitoTestCase {
.isFalse();
}
protected void expectUserIsNotVisibleOnDisplay(String when, @UserIdInt int userId,
int displayId) {
String suffix = TextUtils.isEmpty(when) ? "" : " on " + when;
expectWithMessage("mediator.isUserVisible(%s, %s)%s", userId, displayId, suffix)
.that(mMediator.isUserVisible(userId, displayId))
.isFalse();
}
protected void expectUserIsNotVisibleAtAll(@UserIdInt int userId) {
expectWithMessage("mediator.isUserVisible(%s)", userId)
.that(mMediator.isUserVisible(userId))