diff --git a/services/core/java/com/android/server/pm/UserVisibilityMediator.java b/services/core/java/com/android/server/pm/UserVisibilityMediator.java index 9c4187b35e93c..2650b2394cc5e 100644 --- a/services/core/java/com/android/server/pm/UserVisibilityMediator.java +++ b/services/core/java/com/android/server/pm/UserVisibilityMediator.java @@ -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) { diff --git a/services/tests/mockingservicestests/src/com/android/server/pm/AsyncUserVisibilityListener.java b/services/tests/mockingservicestests/src/com/android/server/pm/AsyncUserVisibilityListener.java index afcedd6f41bf8..a97491daa96e3 100644 --- a/services/tests/mockingservicestests/src/com/android/server/pm/AsyncUserVisibilityListener.java +++ b/services/tests/mockingservicestests/src/com/android/server/pm/AsyncUserVisibilityListener.java @@ -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; diff --git a/services/tests/mockingservicestests/src/com/android/server/pm/UserVisibilityMediatorMUMDTest.java b/services/tests/mockingservicestests/src/com/android/server/pm/UserVisibilityMediatorMUMDTest.java index c5a85721cc8ac..6d8910eb8cdd0 100644 --- a/services/tests/mockingservicestests/src/com/android/server/pm/UserVisibilityMediatorMUMDTest.java +++ b/services/tests/mockingservicestests/src/com/android/server/pm/UserVisibilityMediatorMUMDTest.java @@ -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 diff --git a/services/tests/mockingservicestests/src/com/android/server/pm/UserVisibilityMediatorSUSDTest.java b/services/tests/mockingservicestests/src/com/android/server/pm/UserVisibilityMediatorSUSDTest.java index fc0287f5d6381..1065392be8ce2 100644 --- a/services/tests/mockingservicestests/src/com/android/server/pm/UserVisibilityMediatorSUSDTest.java +++ b/services/tests/mockingservicestests/src/com/android/server/pm/UserVisibilityMediatorSUSDTest.java @@ -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(); 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 6ceb38adf8752..c2038311e740e 100644 --- a/services/tests/mockingservicestests/src/com/android/server/pm/UserVisibilityMediatorTestCase.java +++ b/services/tests/mockingservicestests/src/com/android/server/pm/UserVisibilityMediatorTestCase.java @@ -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))