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

Commit 418581d8 authored by Fabián Kozynski's avatar Fabián Kozynski
Browse files

Check logoutUser handle to determine if we can log out

Test: atest UserRepositoryImplTest
Fixes: 401000285
Flag: EXEMPT bugfix
Change-Id: I58ac0ab51708f094b6c87e55f710cdb1eb4cd453
parent 26302b2e
Loading
Loading
Loading
Loading
+151 −4
Original line number Diff line number Diff line
@@ -17,8 +17,10 @@

package com.android.systemui.user.data.repository

import android.app.admin.DevicePolicyManager
import android.app.admin.devicePolicyManager
import android.content.Intent
import android.content.applicationContext
import android.content.pm.UserInfo
import android.internal.statusbar.fakeStatusBarService
import android.os.UserHandle
@@ -77,10 +79,7 @@ class UserRepositoryImplTest : SysuiTestCase() {
    fun setUp() {
        MockitoAnnotations.initMocks(this)
        tracker = FakeUserTracker()
        context.orCreateTestableResources.addOverride(
            R.bool.config_userSwitchingMustGoThroughLoginScreen,
            false,
        )
        setUserSwitchingMustGoThroughLoginScreen(false)
    }

    @Test
@@ -308,6 +307,117 @@ class UserRepositoryImplTest : SysuiTestCase() {
            job.cancel()
        }

    @Test
    fun isSecondaryUserLogoutEnabled_secondaryLogoutDisabled_alwaysFalse() =
        testScope.runTest {
            underTest = create(testScope.backgroundScope)
            mockLogoutUser(LogoutUserResult.NON_SYSTEM_CURRENT)
            setSecondaryUserLogoutEnabled(false)
            setUpUsers(count = 2, selectedIndex = 0)
            tracker.onProfileChanged()

            val secondaryUserLogoutEnabled by
                collectLastValue(underTest.isSecondaryUserLogoutEnabled)

            assertThat(secondaryUserLogoutEnabled).isFalse()

            setUpUsers(count = 2, selectedIndex = 1)
            tracker.onProfileChanged()
            assertThat(secondaryUserLogoutEnabled).isFalse()
        }

    @Test
    fun isSecondaryUserLogoutEnabled_secondaryLogoutEnabled_NullLogoutUser_alwaysFalse() =
        testScope.runTest {
            underTest = create(testScope.backgroundScope)
            mockLogoutUser(LogoutUserResult.NONE)
            setSecondaryUserLogoutEnabled(true)
            setUpUsers(count = 2, selectedIndex = 0)
            tracker.onProfileChanged()

            val secondaryUserLogoutEnabled by
                collectLastValue(underTest.isSecondaryUserLogoutEnabled)

            assertThat(secondaryUserLogoutEnabled).isFalse()

            setUpUsers(count = 2, selectedIndex = 1)
            tracker.onProfileChanged()
            assertThat(secondaryUserLogoutEnabled).isFalse()
        }

    @Test
    fun isSecondaryUserLogoutEnabled_secondaryLogoutEnabled_NonSystemLogoutUser_trueWhenNonSystem() =
        testScope.runTest {
            underTest = create(testScope.backgroundScope)
            mockLogoutUser(LogoutUserResult.NON_SYSTEM_CURRENT)
            setSecondaryUserLogoutEnabled(true)
            setUpUsers(count = 2, selectedIndex = 0)
            tracker.onProfileChanged()

            val secondaryUserLogoutEnabled by
                collectLastValue(underTest.isSecondaryUserLogoutEnabled)

            assertThat(secondaryUserLogoutEnabled).isFalse()

            setUpUsers(count = 2, selectedIndex = 1)
            tracker.onProfileChanged()
            assertThat(secondaryUserLogoutEnabled).isTrue()
        }

    @Test
    fun isLogoutToSystemUserEnabled_logoutThroughLoginScreenDisabled_alwaysFalse() =
        testScope.runTest {
            underTest = create(testScope.backgroundScope)
            mockLogoutUser(LogoutUserResult.NON_SYSTEM_CURRENT)
            setUserSwitchingMustGoThroughLoginScreen(false)
            setUpUsers(count = 2, selectedIndex = 0)
            tracker.onProfileChanged()

            val logoutToSystemUserEnabled by collectLastValue(underTest.isLogoutToSystemUserEnabled)

            assertThat(logoutToSystemUserEnabled).isFalse()

            setUpUsers(count = 2, selectedIndex = 1)
            tracker.onProfileChanged()
            assertThat(logoutToSystemUserEnabled).isFalse()
        }

    @Test
    fun isLogoutToSystemUserEnabled_logoutThroughLoginScreenEnabled_NullLogoutUser_alwaysFalse() =
        testScope.runTest {
            underTest = create(testScope.backgroundScope)
            mockLogoutUser(LogoutUserResult.NONE)
            setUserSwitchingMustGoThroughLoginScreen(true)
            setUpUsers(count = 2, selectedIndex = 0)
            tracker.onProfileChanged()

            val logoutToSystemUserEnabled by collectLastValue(underTest.isLogoutToSystemUserEnabled)

            assertThat(logoutToSystemUserEnabled).isFalse()

            setUpUsers(count = 2, selectedIndex = 1)
            tracker.onProfileChanged()
            assertThat(logoutToSystemUserEnabled).isFalse()
        }

    @Test
    fun isLogoutToSystemUserEnabled_logoutThroughLoginScreenEnabled_NonSystemLogoutUser_trueWhenNonSystem() =
        testScope.runTest {
            underTest = create(testScope.backgroundScope)
            mockLogoutUser(LogoutUserResult.NON_SYSTEM_CURRENT)
            setUserSwitchingMustGoThroughLoginScreen(true)
            setUpUsers(count = 2, selectedIndex = 0)
            tracker.onProfileChanged()

            val logoutToSystemUserEnabled by collectLastValue(underTest.isLogoutToSystemUserEnabled)

            assertThat(logoutToSystemUserEnabled).isFalse()

            setUpUsers(count = 2, selectedIndex = 1)
            tracker.onProfileChanged()
            assertThat(logoutToSystemUserEnabled).isTrue()
        }

    private fun createUserInfo(id: Int, isGuest: Boolean): UserInfo {
        val flags = 0
        return UserInfo(
@@ -354,6 +464,38 @@ class UserRepositoryImplTest : SysuiTestCase() {
        assertThat(model.isUserSwitcherEnabled).isEqualTo(expectedUserSwitcherEnabled)
    }

    private fun setSecondaryUserLogoutEnabled(enabled: Boolean) {
        whenever(devicePolicyManager.isLogoutEnabled).thenReturn(enabled)
        broadcastDispatcher.sendIntentToMatchingReceiversOnly(
            kosmos.applicationContext,
            Intent(DevicePolicyManager.ACTION_DEVICE_POLICY_MANAGER_STATE_CHANGED),
        )
    }

    private fun setUserSwitchingMustGoThroughLoginScreen(enabled: Boolean) {
        context.orCreateTestableResources.addOverride(
            R.bool.config_userSwitchingMustGoThroughLoginScreen,
            enabled,
        )
    }

    private fun mockLogoutUser(result: LogoutUserResult) {
        when (result) {
            LogoutUserResult.NONE -> {
                whenever(devicePolicyManager.logoutUser).thenReturn(null)
            }
            LogoutUserResult.NON_SYSTEM_CURRENT -> {
                whenever(devicePolicyManager.logoutUser).thenAnswer {
                    if (tracker.userHandle != UserHandle.SYSTEM) {
                        tracker.userHandle
                    } else {
                        null
                    }
                }
            }
        }
    }

    private fun create(scope: CoroutineScope): UserRepositoryImpl {
        return UserRepositoryImpl(
            appContext = context,
@@ -373,4 +515,9 @@ class UserRepositoryImplTest : SysuiTestCase() {
    companion object {
        @JvmStatic private val IMMEDIATE = Dispatchers.Main.immediate
    }

    private enum class LogoutUserResult {
        NONE,
        NON_SYSTEM_CURRENT,
    }
}
+7 −8
Original line number Diff line number Diff line
@@ -414,16 +414,15 @@ constructor(
        }
    }

    private suspend fun SelectedUserModel.isEligibleForLogout(): Boolean {
        return withContext(backgroundDispatcher) {
            selectionStatus == SelectionStatus.SELECTION_COMPLETE &&
                devicePolicyManager.logoutUser != null
        }
    }

    companion object {
        private const val TAG = "UserRepository"
        @VisibleForTesting const val SETTING_SIMPLE_USER_SWITCHER = "lockscreenSimpleUserSwitcher"
    }
}

fun SelectedUserModel.isEligibleForLogout(): Boolean {
    // TODO(b/206032495): should call mDevicePolicyManager.getLogoutUserId() instead of
    // hardcode it to USER_SYSTEM so it properly supports headless system user mode
    // (and then call mDevicePolicyManager.clearLogoutUser() after switched)
    return selectionStatus == SelectionStatus.SELECTION_COMPLETE &&
        userInfo.id != android.os.UserHandle.USER_SYSTEM
}