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

Commit 7c060b29 authored by Peter Kalauskas's avatar Peter Kalauskas
Browse files

Add tests for guest user metrics

Test: statsd_testdrive -terse 90
Test: atest SystemUITests:com.android.systemui.qs.tiles.UserDetailViewAdapterTest
Test: atest SystemUITests:com.android.systemui.statusbar.policy.UserSwitcherControllerTest

Bug: 169783558
Bug: 194441567
Change-Id: I009fc0eba32e34cb62f2cc15f9337bce9b81c89d
Merged-In: I009fc0eba32e34cb62f2cc15f9337bce9b81c89d
parent d1ccddb7
Loading
Loading
Loading
Loading
+31 −24
Original line number Diff line number Diff line
@@ -16,25 +16,24 @@

package com.android.systemui;

import android.app.ActivityManager;
import android.app.Dialog;
import android.app.AlertDialog;
import android.content.BroadcastReceiver;
import android.content.ContentResolver;
import android.content.Context;
import android.content.DialogInterface;
import android.content.Intent;
import android.content.IntentFilter;
import android.content.pm.UserInfo;
import android.os.RemoteException;
import android.os.UserHandle;
import android.provider.Settings;
import android.util.Log;

import com.android.internal.annotations.VisibleForTesting;
import com.android.internal.logging.UiEventLogger;
import com.android.systemui.broadcast.BroadcastDispatcher;
import com.android.systemui.qs.QSUserSwitcherEvent;
import com.android.systemui.settings.UserTracker;
import com.android.systemui.statusbar.phone.SystemUIDialog;
import com.android.systemui.statusbar.policy.UserSwitcherController;
import com.android.systemui.util.settings.SecureSettings;

/**
 * Manages notification when a guest session is resumed.
@@ -43,16 +42,23 @@ public class GuestResumeSessionReceiver extends BroadcastReceiver {

    private static final String TAG = "GuestResumeSessionReceiver";

    private static final String SETTING_GUEST_HAS_LOGGED_IN = "systemui.guest_has_logged_in";
    @VisibleForTesting
    public static final String SETTING_GUEST_HAS_LOGGED_IN = "systemui.guest_has_logged_in";

    private Dialog mNewSessionDialog;
    @VisibleForTesting
    public AlertDialog mNewSessionDialog;
    private final UserTracker mUserTracker;
    private final UserSwitcherController mUserSwitcherController;
    private final UiEventLogger mUiEventLogger;
    private final SecureSettings mSecureSettings;

    public GuestResumeSessionReceiver(UserSwitcherController userSwitcherController,
            UiEventLogger uiEventLogger) {
            UserTracker userTracker, UiEventLogger uiEventLogger,
            SecureSettings secureSettings) {
        mUserSwitcherController = userSwitcherController;
        mUserTracker = userTracker;
        mUiEventLogger = uiEventLogger;
        mSecureSettings = secureSettings;
    }

    /**
@@ -78,26 +84,19 @@ public class GuestResumeSessionReceiver extends BroadcastReceiver {
                return;
            }

            UserInfo currentUser;
            try {
                currentUser = ActivityManager.getService().getCurrentUser();
            } catch (RemoteException e) {
                return;
            }
            UserInfo currentUser = mUserTracker.getUserInfo();
            if (!currentUser.isGuest()) {
                return;
            }

            ContentResolver cr = context.getContentResolver();
            int notFirstLogin = Settings.System.getIntForUser(
                    cr, SETTING_GUEST_HAS_LOGGED_IN, 0, userId);
            int notFirstLogin = mSecureSettings.getIntForUser(
                    SETTING_GUEST_HAS_LOGGED_IN, 0, userId);
            if (notFirstLogin != 0) {
                mNewSessionDialog = new ResetSessionDialog(context, mUserSwitcherController,
                        mUiEventLogger, userId);
                mNewSessionDialog.show();
            } else {
                Settings.System.putIntForUser(
                        cr, SETTING_GUEST_HAS_LOGGED_IN, 1, userId);
                mSecureSettings.putIntForUser(SETTING_GUEST_HAS_LOGGED_IN, 1, userId);
            }
        }
    }
@@ -109,18 +108,26 @@ public class GuestResumeSessionReceiver extends BroadcastReceiver {
        }
    }

    private static class ResetSessionDialog extends SystemUIDialog implements
    /**
     * Dialog shown when user when asking for confirmation before deleting guest user.
     */
    @VisibleForTesting
    public static class ResetSessionDialog extends SystemUIDialog implements
            DialogInterface.OnClickListener {

        private static final int BUTTON_WIPE = BUTTON_NEGATIVE;
        private static final int BUTTON_DONTWIPE = BUTTON_POSITIVE;
        @VisibleForTesting
        public static final int BUTTON_WIPE = BUTTON_NEGATIVE;
        @VisibleForTesting
        public static final int BUTTON_DONTWIPE = BUTTON_POSITIVE;

        private final UserSwitcherController mUserSwitcherController;
        private final UiEventLogger mUiEventLogger;
        private final int mUserId;

        ResetSessionDialog(Context context, UserSwitcherController userSwitcherController,
                UiEventLogger uiEventLogger, int userId) {
        ResetSessionDialog(Context context,
                UserSwitcherController userSwitcherController,
                UiEventLogger uiEventLogger,
                int userId) {
            super(context);

            setTitle(context.getString(R.string.guest_wipe_session_title));
+41 −31
Original line number Diff line number Diff line
@@ -23,6 +23,7 @@ import static com.android.systemui.DejankUtils.whitelistIpcs;

import android.annotation.UserIdInt;
import android.app.ActivityManager;
import android.app.AlertDialog;
import android.app.Dialog;
import android.app.IActivityTaskManager;
import android.content.BroadcastReceiver;
@@ -71,9 +72,11 @@ import com.android.systemui.plugins.FalsingManager;
import com.android.systemui.plugins.qs.DetailAdapter;
import com.android.systemui.qs.QSUserSwitcherEvent;
import com.android.systemui.qs.tiles.UserDetailView;
import com.android.systemui.settings.UserTracker;
import com.android.systemui.statusbar.phone.SystemUIDialog;
import com.android.systemui.telephony.TelephonyListenerManager;
import com.android.systemui.user.CreateUserActivity;
import com.android.systemui.util.settings.SecureSettings;

import java.io.FileDescriptor;
import java.io.PrintWriter;
@@ -104,9 +107,12 @@ public class UserSwitcherController implements Dumpable {
    private static final String PERMISSION_SELF = "com.android.systemui.permission.SELF";

    protected final Context mContext;
    protected final UserTracker mUserTracker;
    protected final UserManager mUserManager;
    private final ContentObserver mSettingsObserver;
    private final ArrayList<WeakReference<BaseUserAdapter>> mAdapters = new ArrayList<>();
    private final GuestResumeSessionReceiver mGuestResumeSessionReceiver;
    @VisibleForTesting
    final GuestResumeSessionReceiver mGuestResumeSessionReceiver;
    private final KeyguardStateController mKeyguardStateController;
    protected final Handler mHandler;
    private final ActivityStarter mActivityStarter;
@@ -115,15 +121,18 @@ public class UserSwitcherController implements Dumpable {
    private final IActivityTaskManager mActivityTaskManager;

    private ArrayList<UserRecord> mUsers = new ArrayList<>();
    private Dialog mExitGuestDialog;
    private Dialog mAddUserDialog;
    @VisibleForTesting
    AlertDialog mExitGuestDialog;
    @VisibleForTesting
    Dialog mAddUserDialog;
    private int mLastNonGuestUser = UserHandle.USER_SYSTEM;
    private boolean mResumeUserOnGuestLogout = true;
    private boolean mSimpleUserSwitcher;
    // When false, there won't be any visual affordance to add a new user from the keyguard even if
    // the user is unlocked
    private boolean mAddUsersFromLockScreen;
    private boolean mPauseRefreshUsers;
    @VisibleForTesting
    boolean mPauseRefreshUsers;
    private int mSecondaryUser = UserHandle.USER_NULL;
    private Intent mSecondaryUserServiceIntent;
    private SparseBooleanArray mForcePictureLoadForUserId = new SparseBooleanArray(2);
@@ -137,6 +146,8 @@ public class UserSwitcherController implements Dumpable {

    @Inject
    public UserSwitcherController(Context context,
            UserManager userManager,
            UserTracker userTracker,
            KeyguardStateController keyguardStateController,
            @Main Handler handler,
            ActivityStarter activityStarter,
@@ -146,14 +157,17 @@ public class UserSwitcherController implements Dumpable {
            TelephonyListenerManager telephonyListenerManager,
            IActivityTaskManager activityTaskManager,
            UserDetailAdapter userDetailAdapter,
            SecureSettings secureSettings,
            @UiBackground Executor uiBgExecutor) {
        mContext = context;
        mUserTracker = userTracker;
        mBroadcastDispatcher = broadcastDispatcher;
        mTelephonyListenerManager = telephonyListenerManager;
        mActivityTaskManager = activityTaskManager;
        mUiEventLogger = uiEventLogger;
        mFalsingManager = falsingManager;
        mGuestResumeSessionReceiver = new GuestResumeSessionReceiver(this, mUiEventLogger);
        mGuestResumeSessionReceiver = new GuestResumeSessionReceiver(
                this, mUserTracker, mUiEventLogger, secureSettings);
        mUserDetailAdapter = userDetailAdapter;
        mUiBgExecutor = uiBgExecutor;
        if (!UserManager.isGuestUserEphemeral()) {
@@ -166,7 +180,7 @@ public class UserSwitcherController implements Dumpable {
        mKeyguardStateController = keyguardStateController;
        mHandler = handler;
        mActivityStarter = activityStarter;
        mUserManager = UserManager.get(context);
        mUserManager = userManager;
        IntentFilter filter = new IntentFilter();
        filter.addAction(Intent.ACTION_USER_ADDED);
        filter.addAction(Intent.ACTION_USER_REMOVED);
@@ -185,6 +199,15 @@ public class UserSwitcherController implements Dumpable {
        mContext.registerReceiverAsUser(mReceiver, UserHandle.SYSTEM, filter,
                PERMISSION_SELF, null /* scheduler */);

        mSettingsObserver = new ContentObserver(mHandler) {
            @Override
            public void onChange(boolean selfChange) {
                mSimpleUserSwitcher = shouldUseSimpleUserSwitcher();
                mAddUsersFromLockScreen = Settings.Global.getInt(mContext.getContentResolver(),
                        Settings.Global.ADD_USERS_WHEN_LOCKED, 0) != 0;
                refreshUsers(UserHandle.USER_NULL);
            };
        };
        mContext.getContentResolver().registerContentObserver(
                Settings.Global.getUriFor(SIMPLE_USER_SWITCHER_GLOBAL_SETTING), true,
                mSettingsObserver);
@@ -246,11 +269,11 @@ public class UserSwitcherController implements Dumpable {
                    return null;
                }
                ArrayList<UserRecord> records = new ArrayList<>(infos.size());
                int currentId = ActivityManager.getCurrentUser();
                int currentId = mUserTracker.getUserId();
                // Check user switchability of the foreground user since SystemUI is running in
                // User 0
                boolean canSwitchUsers = mUserManager.getUserSwitchability(
                        UserHandle.of(ActivityManager.getCurrentUser())) == SWITCHABILITY_STATUS_OK;
                        UserHandle.of(mUserTracker.getUserId())) == SWITCHABILITY_STATUS_OK;
                UserInfo currentUserInfo = null;
                UserRecord guestRecord = null;

@@ -391,7 +414,7 @@ public class UserSwitcherController implements Dumpable {
    }

    public void logoutCurrentUser() {
        int currentUser = ActivityManager.getCurrentUser();
        int currentUser = mUserTracker.getUserId();
        if (currentUser != UserHandle.USER_SYSTEM) {
            pauseRefreshUsers();
            ActivityManager.logoutCurrentUser();
@@ -403,7 +426,7 @@ public class UserSwitcherController implements Dumpable {
            Log.w(TAG, "User " + userId + " could not removed.");
            return;
        }
        if (ActivityManager.getCurrentUser() == userId) {
        if (mUserTracker.getUserId() == userId) {
            switchToUserId(UserHandle.USER_SYSTEM);
        }
        if (mUserManager.removeUser(userId)) {
@@ -411,7 +434,8 @@ public class UserSwitcherController implements Dumpable {
        }
    }

    private void onUserListItemClicked(UserRecord record) {
    @VisibleForTesting
    void onUserListItemClicked(UserRecord record) {
        int id;
        if (record.isGuest && record.info == null) {
            // No guest user. Create one.
@@ -429,7 +453,7 @@ public class UserSwitcherController implements Dumpable {
            id = record.info.id;
        }

        int currUserId = ActivityManager.getCurrentUser();
        int currUserId = mUserTracker.getUserId();
        if (currUserId == id) {
            if (record.isGuest) {
                showExitGuestDialog(id);
@@ -587,15 +611,6 @@ public class UserSwitcherController implements Dumpable {
        }
    };

    private final ContentObserver mSettingsObserver = new ContentObserver(new Handler()) {
        public void onChange(boolean selfChange) {
            mSimpleUserSwitcher = shouldUseSimpleUserSwitcher();
            mAddUsersFromLockScreen = Settings.Global.getInt(mContext.getContentResolver(),
                    Settings.Global.ADD_USERS_WHEN_LOCKED, 0) != 0;
            refreshUsers(UserHandle.USER_NULL);
        };
    };

    @Override
    public void dump(FileDescriptor fd, PrintWriter pw, String[] args) {
        pw.println("UserSwitcherController state:");
@@ -654,13 +669,7 @@ public class UserSwitcherController implements Dumpable {
     * UserHandle.USER_NULL}, then switch immediately to the newly created guest user.
     */
    public void removeGuestUser(@UserIdInt int guestUserId, @UserIdInt int targetUserId) {
        UserInfo currentUser;
        try {
            currentUser = ActivityManager.getService().getCurrentUser();
        } catch (RemoteException e) {
            Log.e(TAG, "Couldn't remove guest because ActivityManager is dead");
            return;
        }
        UserInfo currentUser = mUserTracker.getUserInfo();
        if (currentUser.id != guestUserId) {
            Log.w(TAG, "User requesting to start a new session (" + guestUserId + ")"
                    + " is not current user (" + currentUser.id + ")");
@@ -874,9 +883,9 @@ public class UserSwitcherController implements Dumpable {

    private void checkIfAddUserDisallowedByAdminOnly(UserRecord record) {
        EnforcedAdmin admin = RestrictedLockUtilsInternal.checkIfRestrictionEnforced(mContext,
                UserManager.DISALLOW_ADD_USER, ActivityManager.getCurrentUser());
                UserManager.DISALLOW_ADD_USER, mUserTracker.getUserId());
        if (admin != null && !RestrictedLockUtilsInternal.hasBaseUserRestriction(mContext,
                UserManager.DISALLOW_ADD_USER, ActivityManager.getCurrentUser())) {
                UserManager.DISALLOW_ADD_USER, mUserTracker.getUserId())) {
            record.isDisabledByAdmin = true;
            record.enforcedAdmin = admin;
        } else {
@@ -1088,7 +1097,8 @@ public class UserSwitcherController implements Dumpable {
        }
    }

    private final class AddUserDialog extends SystemUIDialog implements
    @VisibleForTesting
    final class AddUserDialog extends SystemUIDialog implements
            DialogInterface.OnClickListener {

        public AddUserDialog(Context context) {
+248 −0
Original line number Diff line number Diff line
/*
 * Copyright (C) 2021 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.systemui.statusbar.policy

import android.app.IActivityTaskManager
import android.content.DialogInterface
import android.content.Intent
import android.content.pm.UserInfo
import android.graphics.Bitmap
import android.os.Handler
import android.os.UserHandle
import android.os.UserManager
import android.testing.AndroidTestingRunner
import android.testing.TestableLooper
import androidx.test.filters.SmallTest
import com.android.internal.logging.testing.UiEventLoggerFake
import com.android.internal.util.UserIcons
import com.android.systemui.GuestResumeSessionReceiver
import com.android.systemui.R
import com.android.systemui.SysuiTestCase
import com.android.systemui.broadcast.BroadcastDispatcher
import com.android.systemui.plugins.ActivityStarter
import com.android.systemui.plugins.FalsingManager
import com.android.systemui.qs.QSUserSwitcherEvent
import com.android.systemui.settings.UserTracker
import com.android.systemui.telephony.TelephonyListenerManager
import com.android.systemui.util.concurrency.FakeExecutor
import com.android.systemui.util.settings.SecureSettings
import com.android.systemui.util.time.FakeSystemClock
import org.junit.Assert.assertEquals
import org.junit.Assert.assertNotNull
import org.junit.Before
import org.junit.Test
import org.junit.runner.RunWith
import org.mockito.ArgumentMatchers.anyInt
import org.mockito.ArgumentMatchers.eq
import org.mockito.Mock
import org.mockito.Mockito.any
import org.mockito.Mockito.anyString
import org.mockito.Mockito.`when`
import org.mockito.MockitoAnnotations

@RunWith(AndroidTestingRunner::class)
@TestableLooper.RunWithLooper(setAsMainLooper = true)
@SmallTest
class UserSwitcherControllerTest : SysuiTestCase() {
    @Mock private lateinit var keyguardStateController: KeyguardStateController
    @Mock private lateinit var handler: Handler
    @Mock private lateinit var userTracker: UserTracker
    @Mock private lateinit var userManager: UserManager
    @Mock private lateinit var activityStarter: ActivityStarter
    @Mock private lateinit var broadcastDispatcher: BroadcastDispatcher
    @Mock private lateinit var activityTaskManager: IActivityTaskManager
    @Mock private lateinit var userDetailAdapter: UserSwitcherController.UserDetailAdapter
    @Mock private lateinit var telephonyListenerManager: TelephonyListenerManager
    @Mock private lateinit var secureSettings: SecureSettings
    @Mock private lateinit var falsingManager: FalsingManager
    private lateinit var testableLooper: TestableLooper
    private lateinit var uiBgExecutor: FakeExecutor
    private lateinit var uiEventLogger: UiEventLoggerFake
    private lateinit var userSwitcherController: UserSwitcherController
    private lateinit var picture: Bitmap
    private val ownerId = UserHandle.USER_SYSTEM
    private val ownerInfo = UserInfo(ownerId, "Owner", null,
            UserInfo.FLAG_ADMIN or UserInfo.FLAG_FULL or UserInfo.FLAG_INITIALIZED or
                    UserInfo.FLAG_PRIMARY or UserInfo.FLAG_SYSTEM,
            UserManager.USER_TYPE_FULL_SYSTEM)
    private val guestId = 1234
    private val guestInfo = UserInfo(guestId, "Guest", null,
            UserInfo.FLAG_FULL or UserInfo.FLAG_GUEST, UserManager.USER_TYPE_FULL_GUEST)

    @Before
    fun setUp() {
        MockitoAnnotations.initMocks(this)
        testableLooper = TestableLooper.get(this)
        uiBgExecutor = FakeExecutor(FakeSystemClock())
        uiEventLogger = UiEventLoggerFake()

        context.orCreateTestableResources.addOverride(
                com.android.internal.R.bool.config_guestUserAutoCreated, false)

        `when`(userManager.canAddMoreUsers()).thenReturn(true)

        userSwitcherController = UserSwitcherController(context,
                userManager,
                userTracker,
                keyguardStateController,
                handler,
                activityStarter,
                broadcastDispatcher,
                uiEventLogger,
                falsingManager,
                telephonyListenerManager,
                activityTaskManager,
                userDetailAdapter,
                secureSettings,
                uiBgExecutor)
        userSwitcherController.mPauseRefreshUsers = true

        picture = UserIcons.convertToBitmap(context.getDrawable(R.drawable.ic_avatar_user))
    }

    @Test
    fun testAddGuest_okButtonPressed_isLogged() {
        val emptyGuestUserRecord = UserSwitcherController.UserRecord(
                null,
                null,
                true /* guest */,
                false /* current */,
                false /* isAddUser */,
                false /* isRestricted */,
                true /* isSwitchToEnabled */)
        `when`(userTracker.userId).thenReturn(ownerId)
        `when`(userTracker.userInfo).thenReturn(ownerInfo)

        `when`(userManager.createGuest(any(), anyString())).thenReturn(guestInfo)

        userSwitcherController.onUserListItemClicked(emptyGuestUserRecord)
        assertEquals(1, uiEventLogger.numLogs())
        assertEquals(QSUserSwitcherEvent.QS_USER_GUEST_ADD.id, uiEventLogger.eventId(0))
    }

    @Test
    fun testRemoveGuest_removeButtonPressed_isLogged() {
        val currentGuestUserRecord = UserSwitcherController.UserRecord(
                guestInfo,
                picture,
                true /* guest */,
                true /* current */,
                false /* isAddUser */,
                false /* isRestricted */,
                true /* isSwitchToEnabled */)
        `when`(userTracker.userId).thenReturn(guestInfo.id)
        `when`(userTracker.userInfo).thenReturn(guestInfo)

        userSwitcherController.onUserListItemClicked(currentGuestUserRecord)
        assertNotNull(userSwitcherController.mExitGuestDialog)
        userSwitcherController.mExitGuestDialog
                .getButton(DialogInterface.BUTTON_POSITIVE).performClick()
        testableLooper.processAllMessages()
        assertEquals(1, uiEventLogger.numLogs())
        assertEquals(QSUserSwitcherEvent.QS_USER_GUEST_REMOVE.id, uiEventLogger.eventId(0))
    }

    @Test
    fun testRemoveGuest_cancelButtonPressed_isNotLogged() {
        val currentGuestUserRecord = UserSwitcherController.UserRecord(
                guestInfo,
                picture,
                true /* guest */,
                true /* current */,
                false /* isAddUser */,
                false /* isRestricted */,
                true /* isSwitchToEnabled */)
        `when`(userTracker.userId).thenReturn(guestId)
        `when`(userTracker.userInfo).thenReturn(guestInfo)

        userSwitcherController.onUserListItemClicked(currentGuestUserRecord)
        assertNotNull(userSwitcherController.mExitGuestDialog)
        userSwitcherController.mExitGuestDialog
                .getButton(DialogInterface.BUTTON_NEGATIVE).performClick()
        testableLooper.processAllMessages()
        assertEquals(0, uiEventLogger.numLogs())
    }

    @Test
    fun testWipeGuest_startOverButtonPressed_isLogged() {
        val currentGuestUserRecord = UserSwitcherController.UserRecord(
                guestInfo,
                picture,
                true /* guest */,
                false /* current */,
                false /* isAddUser */,
                false /* isRestricted */,
                true /* isSwitchToEnabled */)
        `when`(userTracker.userId).thenReturn(guestId)
        `when`(userTracker.userInfo).thenReturn(guestInfo)

        // Simulate that guest user has already logged in
        `when`(secureSettings.getIntForUser(
                eq(GuestResumeSessionReceiver.SETTING_GUEST_HAS_LOGGED_IN), anyInt(), anyInt()))
                .thenReturn(1)

        userSwitcherController.onUserListItemClicked(currentGuestUserRecord)

        // Simulate a user switch event
        val intent = Intent(Intent.ACTION_USER_SWITCHED).putExtra(Intent.EXTRA_USER_HANDLE, guestId)

        assertNotNull(userSwitcherController.mGuestResumeSessionReceiver)
        userSwitcherController.mGuestResumeSessionReceiver.onReceive(context, intent)

        assertNotNull(userSwitcherController.mGuestResumeSessionReceiver.mNewSessionDialog)
        userSwitcherController.mGuestResumeSessionReceiver.mNewSessionDialog
                .getButton(GuestResumeSessionReceiver.ResetSessionDialog.BUTTON_WIPE).performClick()
        testableLooper.processAllMessages()
        assertEquals(1, uiEventLogger.numLogs())
        assertEquals(QSUserSwitcherEvent.QS_USER_GUEST_WIPE.id, uiEventLogger.eventId(0))
    }

    @Test
    fun testWipeGuest_continueButtonPressed_isLogged() {
        val currentGuestUserRecord = UserSwitcherController.UserRecord(
                guestInfo,
                picture,
                true /* guest */,
                false /* current */,
                false /* isAddUser */,
                false /* isRestricted */,
                true /* isSwitchToEnabled */)
        `when`(userTracker.userId).thenReturn(guestId)
        `when`(userTracker.userInfo).thenReturn(guestInfo)

        // Simulate that guest user has already logged in
        `when`(secureSettings.getIntForUser(
                eq(GuestResumeSessionReceiver.SETTING_GUEST_HAS_LOGGED_IN), anyInt(), anyInt()))
                .thenReturn(1)

        userSwitcherController.onUserListItemClicked(currentGuestUserRecord)

        // Simulate a user switch event
        val intent = Intent(Intent.ACTION_USER_SWITCHED).putExtra(Intent.EXTRA_USER_HANDLE, guestId)

        assertNotNull(userSwitcherController.mGuestResumeSessionReceiver)
        userSwitcherController.mGuestResumeSessionReceiver.onReceive(context, intent)

        assertNotNull(userSwitcherController.mGuestResumeSessionReceiver.mNewSessionDialog)
        userSwitcherController.mGuestResumeSessionReceiver.mNewSessionDialog
                .getButton(GuestResumeSessionReceiver.ResetSessionDialog.BUTTON_DONTWIPE)
                .performClick()
        testableLooper.processAllMessages()
        assertEquals(1, uiEventLogger.numLogs())
        assertEquals(QSUserSwitcherEvent.QS_USER_GUEST_CONTINUE.id, uiEventLogger.eventId(0))
    }
}