Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 01e27df2 authored by Felipe Leme's avatar Felipe Leme Committed by Android (Google) Code Review
Browse files

Merge "UserVisibilityMediator: allow visible bg users on default display."

parents 8206e5ee 2c4a5939
Loading
Loading
Loading
Loading
+126 −42
Original line number Diff line number Diff line
@@ -36,6 +36,7 @@ import android.annotation.UserIdInt;
import android.os.Handler;
import android.os.UserHandle;
import android.os.UserManager;
import android.util.DebugUtils;
import android.util.Dumpable;
import android.util.EventLog;
import android.util.IndentingPrintWriter;
@@ -80,6 +81,7 @@ public final class UserVisibilityMediator implements Dumpable {

    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;
    public static final int SECONDARY_DISPLAY_MAPPING_FAILED = -1;
@@ -88,7 +90,7 @@ public final class UserVisibilityMediator implements Dumpable {
     * Whether a user / display assignment requires adding an entry to the
     * {@code mUsersOnSecondaryDisplays} map.
     */
    @IntDef(flag = false, prefix = {"SECONDARY_DISPLAY_MAPPING_"}, value = {
    @IntDef(flag = false, prefix = {PREFIX_SECONDARY_DISPLAY_MAPPING}, value = {
            SECONDARY_DISPLAY_MAPPING_NEEDED,
            SECONDARY_DISPLAY_MAPPING_NOT_NEEDED,
            SECONDARY_DISPLAY_MAPPING_FAILED
@@ -102,6 +104,7 @@ public final class UserVisibilityMediator implements Dumpable {
    private final Object mLock = new Object();

    private final boolean mVisibleBackgroundUsersEnabled;
    private final boolean mVisibleBackgroundUserOnDefaultDisplayAllowed;

    @UserIdInt
    @GuardedBy("mLock")
@@ -110,7 +113,7 @@ public final class UserVisibilityMediator implements Dumpable {
    /**
     * Map of background users started visible on displays (key is user id, value is display id).
     *
     * <p>Only set when {@code mUsersOnSecondaryDisplaysEnabled} is {@code true}.
     * <p>Only set when {@code mVisibleBackgroundUsersEnabled} is {@code true}.
     */
    @Nullable
    @GuardedBy("mLock")
@@ -121,7 +124,7 @@ public final class UserVisibilityMediator implements Dumpable {
     * {@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}.
     * <p>Only set when {@code mVisibleBackgroundUsersEnabled} is {@code true}.
     */
    @Nullable
    @GuardedBy("mLock")
@@ -143,12 +146,17 @@ public final class UserVisibilityMediator implements Dumpable {
            new CopyOnWriteArrayList<>();

    UserVisibilityMediator(Handler handler) {
        this(UserManager.isVisibleBackgroundUsersEnabled(), handler);
        this(UserManager.isVisibleBackgroundUsersEnabled(),
                // TODO(b/261538232): get visibleBackgroundUserOnDefaultDisplayAllowed from UM
                /* visibleBackgroundUserOnDefaultDisplayAllowed= */ false, handler);
    }

    @VisibleForTesting
    UserVisibilityMediator(boolean backgroundUsersOnDisplaysEnabled, Handler handler) {
    UserVisibilityMediator(boolean backgroundUsersOnDisplaysEnabled,
            boolean visibleBackgroundUserOnDefaultDisplayAllowed, Handler handler) {
        mVisibleBackgroundUsersEnabled = backgroundUsersOnDisplaysEnabled;
        mVisibleBackgroundUserOnDefaultDisplayAllowed =
                visibleBackgroundUserOnDefaultDisplayAllowed;
        if (mVisibleBackgroundUsersEnabled) {
            mUsersAssignedToDisplayOnStart = new SparseIntArray();
            mExtraDisplaysAssignedToUsers = new SparseIntArray();
@@ -203,7 +211,12 @@ public final class UserVisibilityMediator implements Dumpable {
                return result;
            }

            int mappingResult = canAssignUserToDisplayLocked(userId, profileGroupId, displayId);
            int mappingResult = canAssignUserToDisplayLocked(userId, profileGroupId, userStartMode,
                    displayId);
            if (DBG) {
                Slogf.d(TAG, "mapping result: %s",
                        secondaryDisplayMappingStatusToString(mappingResult));
            }
            if (mappingResult == SECONDARY_DISPLAY_MAPPING_FAILED) {
                return USER_ASSIGNMENT_RESULT_FAILURE;
            }
@@ -263,14 +276,16 @@ public final class UserVisibilityMediator implements Dumpable {
                    + "(it should be BACKGROUND_USER_VISIBLE", userId, displayId);
            return USER_ASSIGNMENT_RESULT_FAILURE;
        }
        if (userStartMode == USER_START_MODE_BACKGROUND_VISIBLE
                && displayId == DEFAULT_DISPLAY && !isProfile(userId, profileGroupId)) {

        boolean visibleBackground = userStartMode == USER_START_MODE_BACKGROUND_VISIBLE;
        if (displayId == DEFAULT_DISPLAY && visibleBackground
                && !mVisibleBackgroundUserOnDefaultDisplayAllowed
                && !isProfile(userId, profileGroupId)) {
            Slogf.wtf(TAG, "cannot start full user (%d) visible on default display", userId);
            return USER_ASSIGNMENT_RESULT_FAILURE;
        }

        boolean foreground = userStartMode == USER_START_MODE_FOREGROUND;

        if (displayId != DEFAULT_DISPLAY) {
            if (foreground) {
                Slogf.w(TAG, "getUserVisibilityOnStartLocked(%d, %d, %b, %d) failed: cannot start "
@@ -309,6 +324,7 @@ public final class UserVisibilityMediator implements Dumpable {
        }

        return foreground || displayId != DEFAULT_DISPLAY
                || (visibleBackground && mVisibleBackgroundUserOnDefaultDisplayAllowed)
                        ? USER_ASSIGNMENT_RESULT_SUCCESS_VISIBLE
                        : USER_ASSIGNMENT_RESULT_SUCCESS_INVISIBLE;
    }
@@ -316,20 +332,40 @@ public final class UserVisibilityMediator implements Dumpable {
    @GuardedBy("mLock")
    @SecondaryDisplayMappingStatus
    private int canAssignUserToDisplayLocked(@UserIdInt int userId,
            @UserIdInt int profileGroupId, int displayId) {
        if (displayId == DEFAULT_DISPLAY
                && (!mVisibleBackgroundUsersEnabled || !isProfile(userId, profileGroupId))) {
            @UserIdInt int profileGroupId, @UserStartMode int userStartMode, int displayId) {
        if (displayId == DEFAULT_DISPLAY) {
            boolean mappingNeeded = false;
            if (mVisibleBackgroundUserOnDefaultDisplayAllowed
                    && userStartMode == USER_START_MODE_BACKGROUND_VISIBLE) {
                int userStartedOnDefaultDisplay = getUserStartedOnDisplay(DEFAULT_DISPLAY);
                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;
                }
                mappingNeeded = true;
            }
            if (!mappingNeeded && mVisibleBackgroundUsersEnabled
                    && isProfile(userId, profileGroupId)) {
                mappingNeeded = true;
            }

            if (!mappingNeeded) {
                // Don't need to do anything because methods (such as isUserVisible()) already
                // know that the current user (and its profiles) is assigned to the default display.
                // But on MUMD devices, profiles are only supported in the default display, so it
                // cannot return yet as it needs to check if the parent is also assigned to the
            // DEFAULT_DISPLAY (this is done indirectly below when it checks that the profile parent
            // is the current user, as the current user is always assigned to the DEFAULT_DISPLAY).
                // DEFAULT_DISPLAY (this is done indirectly below when it checks that the profile
                // parent is the current user, as the current user is always assigned to the
                // DEFAULT_DISPLAY).
                if (DBG) {
                Slogf.d(TAG, "ignoring mapping for default display");
                    Slogf.d(TAG, "ignoring mapping for default display for user %d starting as %s",
                            userId, userStartModeToString(userStartMode));
                }
                return SECONDARY_DISPLAY_MAPPING_NOT_NEEDED;
            }
        }

        if (userId == UserHandle.USER_SYSTEM) {
            Slogf.w(TAG, "Cannot assign system user to secondary display (%d)", displayId);
@@ -421,13 +457,14 @@ public final class UserVisibilityMediator implements Dumpable {
                return false;
            }

            int userAssignedToDisplay = getUserAssignedToDisplay(displayId,
                    /* returnCurrentUserByDefault= */ false);
            // First check if the user started on display
            int userAssignedToDisplay = getUserStartedOnDisplay(displayId);
            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;
            }
            // Then if was assigned extra
            userAssignedToDisplay = mExtraDisplaysAssignedToUsers.get(userId, USER_NULL);
            if (userAssignedToDisplay != USER_NULL) {
                Slogf.w(TAG, "assignUserToExtraDisplay(%d, %d): failed because user %d was already "
@@ -435,7 +472,8 @@ public final class UserVisibilityMediator implements Dumpable {
                return false;
            }
            if (DBG) {
                Slogf.d(TAG, "addding %d -> %d to map", displayId, userId);
                Slogf.d(TAG, "addding %d -> %d to mExtraDisplaysAssignedToUsers", displayId,
                        userId);
            }
            mExtraDisplaysAssignedToUsers.put(displayId, userId);
        }
@@ -501,7 +539,7 @@ public final class UserVisibilityMediator implements Dumpable {
        mStartedProfileGroupIds.delete(userId);

        if (!mVisibleBackgroundUsersEnabled) {
            // Don't need to do update mUsersOnSecondaryDisplays because methods (such as
            // Don't need to update mUsersAssignedToDisplayOnStart because methods (such as
            // isUserVisible()) already know that the current user (and their profiles) is
            // assigned to the default display.
            return;
@@ -536,11 +574,10 @@ public final class UserVisibilityMediator implements Dumpable {
            return true;
        }

        // Device doesn't support multiple users on multiple displays, so only users checked above
        // can be visible
        if (!mVisibleBackgroundUsersEnabled) {
            if (DBG) {
                Slogf.d(TAG, "isUserVisible(%d): false for non-current user on MUMD", userId);
                Slogf.d(TAG, "isUserVisible(%d): false for non-current user (or its profiles) when"
                        + " device doesn't support visible background users", userId);
            }
            return false;
        }
@@ -559,15 +596,29 @@ public final class UserVisibilityMediator implements Dumpable {
     * See {@link UserManagerInternal#isUserVisible(int, int)}.
     */
    public boolean isUserVisible(@UserIdInt int userId, int displayId) {
        if (displayId == Display.INVALID_DISPLAY) {
        if (displayId == INVALID_DISPLAY) {
            return false;
        }

        if (!mVisibleBackgroundUsersEnabled || 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);
        // 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)
        if (isCurrentUserOrRunningProfileOfCurrentUser(userId)
                && (displayId == DEFAULT_DISPLAY || !mVisibleBackgroundUsersEnabled)) {
            if (VERBOSE) {
                Slogf.v(TAG, "isUserVisible(%d, %d): returning true for current user/profile",
                        userId, displayId);
            }
            return true;
        }

        if (!mVisibleBackgroundUsersEnabled) {
            if (DBG) {
                Slogf.d(TAG, "isUserVisible(%d, %d): returning false as device does not support"
                        + " visible background users", userId, displayId);
            }
            return false;
        }

        synchronized (mLock) {
@@ -575,7 +626,8 @@ public final class UserVisibilityMediator implements Dumpable {
                // User assigned to display on start
                return true;
            }
            // Check for extra assignment

            // Check for extra display assignment
            return mExtraDisplaysAssignedToUsers.get(displayId, USER_NULL) == userId;
        }
    }
@@ -585,15 +637,31 @@ public final class UserVisibilityMediator implements Dumpable {
     */
    public int getDisplayAssignedToUser(@UserIdInt int userId) {
        if (isCurrentUserOrRunningProfileOfCurrentUser(userId)) {
            return Display.DEFAULT_DISPLAY;
            if (mVisibleBackgroundUserOnDefaultDisplayAllowed) {
                // When device supports visible bg users on default display, the default display is
                // assigned to the current user, unless a user is started visible on it
                int userStartedOnDefaultDisplay;
                synchronized (mLock) {
                    userStartedOnDefaultDisplay = getUserStartedOnDisplay(DEFAULT_DISPLAY);
                }
                if (userStartedOnDefaultDisplay != USER_NULL) {
                    if (DBG) {
                        Slogf.d(TAG, "getDisplayAssignedToUser(%d): returning INVALID_DISPLAY for "
                                + "current user user %d was started on DEFAULT_DISPLAY",
                                userId, userStartedOnDefaultDisplay);
                    }
                    return INVALID_DISPLAY;
                }
            }
            return DEFAULT_DISPLAY;
        }

        if (!mVisibleBackgroundUsersEnabled) {
            return Display.INVALID_DISPLAY;
            return INVALID_DISPLAY;
        }

        synchronized (mLock) {
            return mUsersAssignedToDisplayOnStart.get(userId, Display.INVALID_DISPLAY);
            return mUsersAssignedToDisplayOnStart.get(userId, INVALID_DISPLAY);
        }
    }

@@ -604,6 +672,13 @@ public final class UserVisibilityMediator implements Dumpable {
        return getUserAssignedToDisplay(displayId, /* returnCurrentUserByDefault= */ true);
    }

    /**
     * Gets the user explicitly assigned to a display.
     */
    private @UserIdInt int getUserStartedOnDisplay(@UserIdInt int displayId) {
        return getUserAssignedToDisplay(displayId, /* returnCurrentUserByDefault= */ false);
    }

    /**
     * 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}).
@@ -611,7 +686,8 @@ public final class UserVisibilityMediator implements Dumpable {
    private @UserIdInt int getUserAssignedToDisplay(@UserIdInt int displayId,
            boolean returnCurrentUserByDefault) {
        if (returnCurrentUserByDefault
                && (displayId == Display.DEFAULT_DISPLAY || !mVisibleBackgroundUsersEnabled)) {
                && ((displayId == DEFAULT_DISPLAY && !mVisibleBackgroundUserOnDefaultDisplayAllowed
                || !mVisibleBackgroundUsersEnabled))) {
            return getCurrentUserId();
        }

@@ -763,8 +839,10 @@ public final class UserVisibilityMediator implements Dumpable {
            ipw.print("Supports visible background users on displays: ");
            ipw.println(mVisibleBackgroundUsersEnabled);

            dumpSparseIntArray(ipw, mUsersAssignedToDisplayOnStart, "user / display", "u", "d");
            ipw.print("Allows visible background users on default display: ");
            ipw.println(mVisibleBackgroundUserOnDefaultDisplayAllowed);

            dumpSparseIntArray(ipw, mUsersAssignedToDisplayOnStart, "user / display", "u", "d");
            dumpSparseIntArray(ipw, mExtraDisplaysAssignedToUsers, "extra display / user",
                    "d", "u");

@@ -872,4 +950,10 @@ public final class UserVisibilityMediator implements Dumpable {
            return mStartedProfileGroupIds.get(userId, NO_PROFILE_GROUP_ID);
        }
    }

    private static String secondaryDisplayMappingStatusToString(
            @SecondaryDisplayMappingStatus int status) {
        return DebugUtils.constantToString(UserVisibilityMediator.class,
                PREFIX_SECONDARY_DISPLAY_MAPPING, status);
    }
}
+9 −2
Original line number Diff line number Diff line
@@ -62,14 +62,21 @@ public final class DumpableDumperRule implements TestRule {
        };
    }

    private void dumpOnFailure(String testName) throws IOException {
    /**
     * Logs all dumpables.
     */
    public void dump(String reason) {
        if (mDumpables.isEmpty()) {
            return;
        }
        Log.w(TAG, "Dumping " + mDumpables.size() + " dumpables on failure of " + testName);
        Log.w(TAG, "Dumping " + mDumpables.size() + " dumpable(s). Reason: " + reason);
        mDumpables.forEach(d -> logDumpable(d));
    }

    private void dumpOnFailure(String testName) throws IOException {
        dump("failure of " + testName);
    }

    private void logDumpable(Dumpable dumpable) {
        try {
            try (StringWriter sw = new StringWriter(); PrintWriter pw = new PrintWriter(sw)) {
+16 −1
Original line number Diff line number Diff line
@@ -15,6 +15,8 @@
 */
package com.android.server.pm;

import org.junit.Test;

/**
 * Tests for {@link UserVisibilityMediator} tests for devices that support concurrent Multiple
 * Users on Multiple Displays (A.K.A {@code MUMD}).
@@ -26,6 +28,19 @@ public final class UserVisibilityMediatorMUMDTest
        extends UserVisibilityMediatorVisibleBackgroundUserTestCase {

    public UserVisibilityMediatorMUMDTest() throws Exception {
        super(/* usersOnSecondaryDisplaysEnabled= */ true);
        super(/* backgroundUsersOnDisplaysEnabled= */ true,
                /* backgroundUserOnDefaultDisplayAllowed= */ false);
    }

    @Test
    public void testStartVisibleBgUser_onDefaultDisplay() throws Exception {
        int userId = visibleBgUserCannotBeStartedOnDefaultDisplayTest();

        assertInvisibleUserCannotBeAssignedExtraDisplay(userId, SECONDARY_DISPLAY_ID);
    }

    @Test
    public void testStartBgUser_onDefaultDisplay_visible() throws Exception {
        visibleBgUserCannotBeStartedOnDefaultDisplayTest();
    }
}
+129 −0
Original line number Diff line number Diff line
/*
 * Copyright (C) 2022 The Android Open Source Project
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *      http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

package com.android.server.pm;

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;

/**
 * Tests for {@link UserVisibilityMediator} tests for devices that support not only concurrent
 * Multiple Users on Multiple Displays, but also let background users to be visible in the default
 * display (A.K.A {@code MUPAND} - MUltiple Passengers, No Driver).
 *
 * <p> Run as {@code
* atest FrameworksMockingServicesTests:com.android.server.pm.UserVisibilityMediatorMUPANDTest}
 */
public final class UserVisibilityMediatorMUPANDTest
        extends UserVisibilityMediatorVisibleBackgroundUserTestCase {

    public UserVisibilityMediatorMUPANDTest() throws Exception {
        super(/* backgroundUsersOnDisplaysEnabled= */ true,
                /* backgroundUserOnDefaultDisplayAllowed= */ true);
    }

    @Test
    public void testStartVisibleBgUser_onDefaultDisplay_initialCurrentUserId()
            throws Exception {
        int currentUserId = INITIAL_CURRENT_USER_ID;
        int visibleBgUserId = USER_ID;
        int otherUserId = OTHER_USER_ID;

        AsyncUserVisibilityListener listener = addListenerForEvents(onVisible(visibleBgUserId));

        int result = mMediator.assignUserToDisplayOnStart(visibleBgUserId, visibleBgUserId,
                BG_VISIBLE, DEFAULT_DISPLAY);
        assertStartUserResult(result, USER_ASSIGNMENT_RESULT_SUCCESS_VISIBLE);
        expectVisibleUsers(currentUserId, visibleBgUserId);

        // Assert bg user visibility
        expectUserIsVisible(visibleBgUserId);
        expectUserIsVisibleOnDisplay(visibleBgUserId, DEFAULT_DISPLAY);
        expectUserIsNotVisibleOnDisplay(visibleBgUserId, INVALID_DISPLAY);
        expectDisplayAssignedToUser(visibleBgUserId, DEFAULT_DISPLAY);
        expectUserAssignedToDisplay(DEFAULT_DISPLAY, visibleBgUserId);

        // Assert current user visibility
        expectUserIsVisible(currentUserId);
        expectUserIsVisibleOnDisplay(currentUserId, DEFAULT_DISPLAY);
        expectUserIsNotVisibleOnDisplay(currentUserId, INVALID_DISPLAY);
        expectDisplayAssignedToUser(currentUserId, INVALID_DISPLAY);

        assertUserCanBeAssignedExtraDisplay(USER_ID, OTHER_SECONDARY_DISPLAY_ID);

        // Make sure another user cannot be started on 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);
        expectVisibleUsers(currentUserId, visibleBgUserId);

        listener.verify();
    }

    @Test
    public void testStartVisibleBgUser_onDefaultDisplay_nonInitialCurrentUserId()
            throws Exception {
        int currentUserId = OTHER_USER_ID;
        int visibleBgUserId = USER_ID;
        int otherUserId = YET_ANOTHER_USER_ID;

        AsyncUserVisibilityListener listener = addListenerForEvents(
                onInvisible(INITIAL_CURRENT_USER_ID),
                onVisible(currentUserId),
                onVisible(visibleBgUserId));
        startForegroundUser(currentUserId);

        int result = mMediator.assignUserToDisplayOnStart(visibleBgUserId, visibleBgUserId,
                BG_VISIBLE, DEFAULT_DISPLAY);
        assertStartUserResult(result, USER_ASSIGNMENT_RESULT_SUCCESS_VISIBLE);
        expectVisibleUsers(currentUserId, visibleBgUserId);

        // Assert bg user visibility
        expectUserIsVisible(visibleBgUserId);
        expectUserIsVisibleOnDisplay(visibleBgUserId, DEFAULT_DISPLAY);
        expectUserIsNotVisibleOnDisplay(visibleBgUserId, INVALID_DISPLAY);
        expectDisplayAssignedToUser(visibleBgUserId, DEFAULT_DISPLAY);
        expectUserAssignedToDisplay(DEFAULT_DISPLAY, visibleBgUserId);

        // Assert current user visibility
        expectUserIsVisible(currentUserId);
        expectUserIsVisibleOnDisplay(currentUserId, DEFAULT_DISPLAY);
        expectUserIsNotVisibleOnDisplay(currentUserId, INVALID_DISPLAY);
        expectDisplayAssignedToUser(currentUserId, INVALID_DISPLAY);

        assertUserCanBeAssignedExtraDisplay(USER_ID, OTHER_SECONDARY_DISPLAY_ID);

        // Make sure another user cannot be started on 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);
        expectVisibleUsers(currentUserId, visibleBgUserId);

        listener.verify();
    }
}
+14 −1
Original line number Diff line number Diff line
@@ -37,7 +37,15 @@ import org.junit.Test;
public final class UserVisibilityMediatorSUSDTest extends UserVisibilityMediatorTestCase {

    public UserVisibilityMediatorSUSDTest() {
        super(/* usersOnSecondaryDisplaysEnabled= */ false);
        super(/* backgroundUsersOnDisplaysEnabled= */ false,
                /* backgroundUserOnDefaultDisplayAllowed= */ false);
    }

    @Test
    public void testStartVisibleBgUser_onDefaultDisplay() throws Exception {
        int userId = visibleBgUserCannotBeStartedOnDefaultDisplayTest();

        assertInvisibleUserCannotBeAssignedExtraDisplay(userId, SECONDARY_DISPLAY_ID);
    }

    @Test
@@ -100,6 +108,11 @@ public final class UserVisibilityMediatorSUSDTest extends UserVisibilityMediator
        listener.verify();
    }

    @Test
    public void testStartBgUser_onDefaultDisplay_visible() throws Exception {
        visibleBgUserCannotBeStartedOnDefaultDisplayTest();
    }

    @Test
    public void testStartVisibleBgProfile_onDefaultDisplay_whenParentIsCurrentUser()
            throws Exception {
Loading