Loading services/core/java/com/android/server/pm/UserManagerService.java +1 −14 Original line number Diff line number Diff line Loading @@ -1789,20 +1789,7 @@ public class UserManagerService extends IUserManager.Stub { } final long ident = Binder.clearCallingIdentity(); try { // TODO(b/2399825580): refactor into UserDisplayAssigner IntArray visibleUsers; synchronized (mUsersLock) { int usersSize = mUsers.size(); visibleUsers = new IntArray(); for (int i = 0; i < usersSize; i++) { UserInfo ui = mUsers.valueAt(i).info; if (!ui.partial && !ui.preCreated && !mRemovingUserIds.get(ui.id) && mUserVisibilityMediator.isUserVisible(ui.id)) { visibleUsers.add(ui.id); } } } return visibleUsers.toArray(); return mUserVisibilityMediator.getVisibleUsers().toArray(); } finally { Binder.restoreCallingIdentity(ident); } Loading services/core/java/com/android/server/pm/UserVisibilityMediator.java +33 −4 Original line number Diff line number Diff line Loading @@ -32,6 +32,7 @@ import android.os.UserHandle; import android.os.UserManager; import android.util.Dumpable; import android.util.IndentingPrintWriter; import android.util.IntArray; import android.util.SparseIntArray; import android.view.Display; Loading Loading @@ -117,6 +118,9 @@ public final class UserVisibilityMediator implements Dumpable { UserVisibilityMediator(boolean usersOnSecondaryDisplaysEnabled) { mUsersOnSecondaryDisplaysEnabled = usersOnSecondaryDisplaysEnabled; mUsersOnSecondaryDisplays = mUsersOnSecondaryDisplaysEnabled ? new SparseIntArray() : null; // 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); } /** Loading Loading @@ -458,6 +462,25 @@ public final class UserVisibilityMediator implements Dumpable { return currentUserId; } /** * Gets the ids of the visible users. */ public IntArray getVisibleUsers() { // TODO(b/258054362): this method's performance is O(n2), as it interacts through all users // here, then again on isUserVisible(). We could "fix" it to be O(n), but given that the // 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 < mStartedProfileGroupIds.size(); i++) { int userId = mStartedProfileGroupIds.keyAt(i); if (isUserVisible(userId)) { visibleUsers.add(userId); } } } return visibleUsers; } private void dump(IndentingPrintWriter ipw) { ipw.println("UserVisibilityMediator"); ipw.increaseIndent(); Loading @@ -466,21 +489,27 @@ public final class UserVisibilityMediator implements Dumpable { ipw.print("Current user id: "); ipw.println(mCurrentUserId); dumpIntArray(ipw, mStartedProfileGroupIds, "started user / profile group", "u", "pg"); ipw.print("Visible users: "); // TODO: merge 2 lines below if/when IntArray implements toString()... IntArray visibleUsers = getVisibleUsers(); ipw.println(java.util.Arrays.toString(visibleUsers.toArray())); dumpSparseIntArray(ipw, mStartedProfileGroupIds, "started user / profile group", "u", "pg"); ipw.print("Supports background users on secondary displays: "); ipw.println(mUsersOnSecondaryDisplaysEnabled); if (mUsersOnSecondaryDisplays != null) { dumpIntArray(ipw, mUsersOnSecondaryDisplays, "background user / secondary display", "u", "d"); dumpSparseIntArray(ipw, mUsersOnSecondaryDisplays, "background user / secondary display", "u", "d"); } } ipw.decreaseIndent(); } private static void dumpIntArray(IndentingPrintWriter ipw, SparseIntArray array, private static void dumpSparseIntArray(IndentingPrintWriter ipw, SparseIntArray array, String arrayDescription, String keyName, String valueName) { ipw.print("Number of "); ipw.print(arrayDescription); Loading services/tests/mockingservicestests/src/com/android/server/pm/UserVisibilityMediatorMUMDTest.java +3 −0 Original line number Diff line number Diff line Loading @@ -21,6 +21,7 @@ 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.UserVisibilityMediator.INITIAL_CURRENT_USER_ID; import org.junit.Test; Loading Loading @@ -63,6 +64,7 @@ public final class UserVisibilityMediatorMUMDTest extends UserVisibilityMediator expectUserIsVisibleOnDisplay(USER_ID, SECONDARY_DISPLAY_ID); expectUserIsNotVisibleOnDisplay(USER_ID, INVALID_DISPLAY); expectUserIsNotVisibleOnDisplay(USER_ID, DEFAULT_DISPLAY); expectVisibleUsers(INITIAL_CURRENT_USER_ID, USER_ID); expectDisplayAssignedToUser(USER_ID, SECONDARY_DISPLAY_ID); expectUserAssignedToDisplay(SECONDARY_DISPLAY_ID, USER_ID); Loading Loading @@ -110,6 +112,7 @@ public final class UserVisibilityMediatorMUMDTest extends UserVisibilityMediator expectUserIsNotVisibleOnDisplay(USER_ID, SECONDARY_DISPLAY_ID); expectUserIsNotVisibleOnDisplay(USER_ID, INVALID_DISPLAY); expectUserIsNotVisibleOnDisplay(USER_ID, DEFAULT_DISPLAY); expectVisibleUsers(INITIAL_CURRENT_USER_ID, USER_ID); expectDisplayAssignedToUser(USER_ID, OTHER_SECONDARY_DISPLAY_ID); expectUserAssignedToDisplay(OTHER_SECONDARY_DISPLAY_ID, USER_ID); Loading services/tests/mockingservicestests/src/com/android/server/pm/UserVisibilityMediatorTestCase.java +13 −0 Original line number Diff line number Diff line Loading @@ -34,6 +34,7 @@ import static com.google.common.truth.Truth.assertWithMessage; import static org.junit.Assert.assertThrows; import android.annotation.UserIdInt; import android.util.IntArray; import android.util.Log; import com.android.internal.util.Preconditions; Loading @@ -42,6 +43,8 @@ import com.android.server.ExtendedMockitoTestCase; import org.junit.Before; import org.junit.Test; import java.util.Arrays; /** * Base class for {@link UserVisibilityMediator} tests. * Loading Loading @@ -133,6 +136,7 @@ abstract class UserVisibilityMediatorTestCase extends ExtendedMockitoTestCase { // 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); Loading @@ -156,6 +160,7 @@ abstract class UserVisibilityMediatorTestCase extends ExtendedMockitoTestCase { expectUserIsNotVisibleOnDisplay(currentUserId, INVALID_DISPLAY); expectUserIsVisibleOnDisplay(currentUserId, DEFAULT_DISPLAY); expectUserIsVisibleOnDisplay(currentUserId, SECONDARY_DISPLAY_ID); expectVisibleUsers(currentUserId); expectDisplayAssignedToUser(currentUserId, DEFAULT_DISPLAY); expectUserAssignedToDisplay(DEFAULT_DISPLAY, currentUserId); Loading Loading @@ -216,6 +221,7 @@ abstract class UserVisibilityMediatorTestCase extends ExtendedMockitoTestCase { 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); Loading Loading @@ -404,6 +410,13 @@ abstract class UserVisibilityMediatorTestCase extends ExtendedMockitoTestCase { .isTrue(); } protected void expectVisibleUsers(@UserIdInt Integer... userIds) { IntArray visibleUsers = mMediator.getVisibleUsers(); expectWithMessage("getVisibleUsers()").that(visibleUsers).isNotNull(); expectWithMessage("getVisibleUsers()").that(visibleUsers.toArray()).asList() .containsExactlyElementsIn(Arrays.asList(userIds)); } protected void expectUserIsVisibleOnDisplay(@UserIdInt int userId, int displayId) { expectWithMessage("mediator.isUserVisible(%s, %s)", userId, displayId) .that(mMediator.isUserVisible(userId, displayId)) Loading Loading
services/core/java/com/android/server/pm/UserManagerService.java +1 −14 Original line number Diff line number Diff line Loading @@ -1789,20 +1789,7 @@ public class UserManagerService extends IUserManager.Stub { } final long ident = Binder.clearCallingIdentity(); try { // TODO(b/2399825580): refactor into UserDisplayAssigner IntArray visibleUsers; synchronized (mUsersLock) { int usersSize = mUsers.size(); visibleUsers = new IntArray(); for (int i = 0; i < usersSize; i++) { UserInfo ui = mUsers.valueAt(i).info; if (!ui.partial && !ui.preCreated && !mRemovingUserIds.get(ui.id) && mUserVisibilityMediator.isUserVisible(ui.id)) { visibleUsers.add(ui.id); } } } return visibleUsers.toArray(); return mUserVisibilityMediator.getVisibleUsers().toArray(); } finally { Binder.restoreCallingIdentity(ident); } Loading
services/core/java/com/android/server/pm/UserVisibilityMediator.java +33 −4 Original line number Diff line number Diff line Loading @@ -32,6 +32,7 @@ import android.os.UserHandle; import android.os.UserManager; import android.util.Dumpable; import android.util.IndentingPrintWriter; import android.util.IntArray; import android.util.SparseIntArray; import android.view.Display; Loading Loading @@ -117,6 +118,9 @@ public final class UserVisibilityMediator implements Dumpable { UserVisibilityMediator(boolean usersOnSecondaryDisplaysEnabled) { mUsersOnSecondaryDisplaysEnabled = usersOnSecondaryDisplaysEnabled; mUsersOnSecondaryDisplays = mUsersOnSecondaryDisplaysEnabled ? new SparseIntArray() : null; // 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); } /** Loading Loading @@ -458,6 +462,25 @@ public final class UserVisibilityMediator implements Dumpable { return currentUserId; } /** * Gets the ids of the visible users. */ public IntArray getVisibleUsers() { // TODO(b/258054362): this method's performance is O(n2), as it interacts through all users // here, then again on isUserVisible(). We could "fix" it to be O(n), but given that the // 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 < mStartedProfileGroupIds.size(); i++) { int userId = mStartedProfileGroupIds.keyAt(i); if (isUserVisible(userId)) { visibleUsers.add(userId); } } } return visibleUsers; } private void dump(IndentingPrintWriter ipw) { ipw.println("UserVisibilityMediator"); ipw.increaseIndent(); Loading @@ -466,21 +489,27 @@ public final class UserVisibilityMediator implements Dumpable { ipw.print("Current user id: "); ipw.println(mCurrentUserId); dumpIntArray(ipw, mStartedProfileGroupIds, "started user / profile group", "u", "pg"); ipw.print("Visible users: "); // TODO: merge 2 lines below if/when IntArray implements toString()... IntArray visibleUsers = getVisibleUsers(); ipw.println(java.util.Arrays.toString(visibleUsers.toArray())); dumpSparseIntArray(ipw, mStartedProfileGroupIds, "started user / profile group", "u", "pg"); ipw.print("Supports background users on secondary displays: "); ipw.println(mUsersOnSecondaryDisplaysEnabled); if (mUsersOnSecondaryDisplays != null) { dumpIntArray(ipw, mUsersOnSecondaryDisplays, "background user / secondary display", "u", "d"); dumpSparseIntArray(ipw, mUsersOnSecondaryDisplays, "background user / secondary display", "u", "d"); } } ipw.decreaseIndent(); } private static void dumpIntArray(IndentingPrintWriter ipw, SparseIntArray array, private static void dumpSparseIntArray(IndentingPrintWriter ipw, SparseIntArray array, String arrayDescription, String keyName, String valueName) { ipw.print("Number of "); ipw.print(arrayDescription); Loading
services/tests/mockingservicestests/src/com/android/server/pm/UserVisibilityMediatorMUMDTest.java +3 −0 Original line number Diff line number Diff line Loading @@ -21,6 +21,7 @@ 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.UserVisibilityMediator.INITIAL_CURRENT_USER_ID; import org.junit.Test; Loading Loading @@ -63,6 +64,7 @@ public final class UserVisibilityMediatorMUMDTest extends UserVisibilityMediator expectUserIsVisibleOnDisplay(USER_ID, SECONDARY_DISPLAY_ID); expectUserIsNotVisibleOnDisplay(USER_ID, INVALID_DISPLAY); expectUserIsNotVisibleOnDisplay(USER_ID, DEFAULT_DISPLAY); expectVisibleUsers(INITIAL_CURRENT_USER_ID, USER_ID); expectDisplayAssignedToUser(USER_ID, SECONDARY_DISPLAY_ID); expectUserAssignedToDisplay(SECONDARY_DISPLAY_ID, USER_ID); Loading Loading @@ -110,6 +112,7 @@ public final class UserVisibilityMediatorMUMDTest extends UserVisibilityMediator expectUserIsNotVisibleOnDisplay(USER_ID, SECONDARY_DISPLAY_ID); expectUserIsNotVisibleOnDisplay(USER_ID, INVALID_DISPLAY); expectUserIsNotVisibleOnDisplay(USER_ID, DEFAULT_DISPLAY); expectVisibleUsers(INITIAL_CURRENT_USER_ID, USER_ID); expectDisplayAssignedToUser(USER_ID, OTHER_SECONDARY_DISPLAY_ID); expectUserAssignedToDisplay(OTHER_SECONDARY_DISPLAY_ID, USER_ID); Loading
services/tests/mockingservicestests/src/com/android/server/pm/UserVisibilityMediatorTestCase.java +13 −0 Original line number Diff line number Diff line Loading @@ -34,6 +34,7 @@ import static com.google.common.truth.Truth.assertWithMessage; import static org.junit.Assert.assertThrows; import android.annotation.UserIdInt; import android.util.IntArray; import android.util.Log; import com.android.internal.util.Preconditions; Loading @@ -42,6 +43,8 @@ import com.android.server.ExtendedMockitoTestCase; import org.junit.Before; import org.junit.Test; import java.util.Arrays; /** * Base class for {@link UserVisibilityMediator} tests. * Loading Loading @@ -133,6 +136,7 @@ abstract class UserVisibilityMediatorTestCase extends ExtendedMockitoTestCase { // 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); Loading @@ -156,6 +160,7 @@ abstract class UserVisibilityMediatorTestCase extends ExtendedMockitoTestCase { expectUserIsNotVisibleOnDisplay(currentUserId, INVALID_DISPLAY); expectUserIsVisibleOnDisplay(currentUserId, DEFAULT_DISPLAY); expectUserIsVisibleOnDisplay(currentUserId, SECONDARY_DISPLAY_ID); expectVisibleUsers(currentUserId); expectDisplayAssignedToUser(currentUserId, DEFAULT_DISPLAY); expectUserAssignedToDisplay(DEFAULT_DISPLAY, currentUserId); Loading Loading @@ -216,6 +221,7 @@ abstract class UserVisibilityMediatorTestCase extends ExtendedMockitoTestCase { 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); Loading Loading @@ -404,6 +410,13 @@ abstract class UserVisibilityMediatorTestCase extends ExtendedMockitoTestCase { .isTrue(); } protected void expectVisibleUsers(@UserIdInt Integer... userIds) { IntArray visibleUsers = mMediator.getVisibleUsers(); expectWithMessage("getVisibleUsers()").that(visibleUsers).isNotNull(); expectWithMessage("getVisibleUsers()").that(visibleUsers.toArray()).asList() .containsExactlyElementsIn(Arrays.asList(userIds)); } protected void expectUserIsVisibleOnDisplay(@UserIdInt int userId, int displayId) { expectWithMessage("mediator.isUserVisible(%s, %s)", userId, displayId) .that(mMediator.isUserVisible(userId, displayId)) Loading