Add userSwitching state to UserRepository
This is required to stop face auth in case the user is currently switching Bug: 262838215 Test: atest UserRepositoryTest Change-Id: I55d3a8832bf9ccae28a0d7349b173780a24265d0
This commit is contained in:
@@ -17,8 +17,11 @@
|
||||
|
||||
package com.android.systemui.user.data.repository
|
||||
|
||||
import android.app.IActivityManager
|
||||
import android.app.UserSwitchObserver
|
||||
import android.content.Context
|
||||
import android.content.pm.UserInfo
|
||||
import android.os.IRemoteCallback
|
||||
import android.os.UserHandle
|
||||
import android.os.UserManager
|
||||
import android.provider.Settings
|
||||
@@ -30,6 +33,8 @@ import com.android.systemui.dagger.SysUISingleton
|
||||
import com.android.systemui.dagger.qualifiers.Application
|
||||
import com.android.systemui.dagger.qualifiers.Background
|
||||
import com.android.systemui.dagger.qualifiers.Main
|
||||
import com.android.systemui.flags.FeatureFlags
|
||||
import com.android.systemui.flags.Flags.FACE_AUTH_REFACTOR
|
||||
import com.android.systemui.settings.UserTracker
|
||||
import com.android.systemui.user.data.model.UserSwitcherSettingsModel
|
||||
import com.android.systemui.util.settings.GlobalSettings
|
||||
@@ -68,6 +73,9 @@ interface UserRepository {
|
||||
/** [UserInfo] of the currently-selected user. */
|
||||
val selectedUserInfo: Flow<UserInfo>
|
||||
|
||||
/** Whether user switching is currently in progress. */
|
||||
val userSwitchingInProgress: Flow<Boolean>
|
||||
|
||||
/** User ID of the last non-guest selected user. */
|
||||
val lastSelectedNonGuestUserId: Int
|
||||
|
||||
@@ -108,6 +116,8 @@ constructor(
|
||||
@Background private val backgroundDispatcher: CoroutineDispatcher,
|
||||
private val globalSettings: GlobalSettings,
|
||||
private val tracker: UserTracker,
|
||||
private val activityManager: IActivityManager,
|
||||
featureFlags: FeatureFlags,
|
||||
) : UserRepository {
|
||||
|
||||
private val _userSwitcherSettings = MutableStateFlow(runBlocking { getSettings() })
|
||||
@@ -129,6 +139,10 @@ constructor(
|
||||
private var _isGuestUserResetting: Boolean = false
|
||||
override var isGuestUserResetting: Boolean = _isGuestUserResetting
|
||||
|
||||
private val _isUserSwitchingInProgress = MutableStateFlow(false)
|
||||
override val userSwitchingInProgress: Flow<Boolean>
|
||||
get() = _isUserSwitchingInProgress
|
||||
|
||||
override val isGuestUserCreationScheduled = AtomicBoolean()
|
||||
|
||||
override val isStatusBarUserChipEnabled: Boolean =
|
||||
@@ -141,6 +155,9 @@ constructor(
|
||||
init {
|
||||
observeSelectedUser()
|
||||
observeUserSettings()
|
||||
if (featureFlags.isEnabled(FACE_AUTH_REFACTOR)) {
|
||||
observeUserSwitching()
|
||||
}
|
||||
}
|
||||
|
||||
override fun refreshUsers() {
|
||||
@@ -166,6 +183,28 @@ constructor(
|
||||
return _userSwitcherSettings.value.isSimpleUserSwitcher
|
||||
}
|
||||
|
||||
private fun observeUserSwitching() {
|
||||
conflatedCallbackFlow {
|
||||
val callback =
|
||||
object : UserSwitchObserver() {
|
||||
override fun onUserSwitching(newUserId: Int, reply: IRemoteCallback) {
|
||||
trySendWithFailureLogging(true, TAG, "userSwitching started")
|
||||
}
|
||||
|
||||
override fun onUserSwitchComplete(newUserId: Int) {
|
||||
trySendWithFailureLogging(false, TAG, "userSwitching completed")
|
||||
}
|
||||
}
|
||||
activityManager.registerUserSwitchObserver(callback, TAG)
|
||||
trySendWithFailureLogging(false, TAG, "initial value defaulting to false")
|
||||
awaitClose { activityManager.unregisterUserSwitchObserver(callback) }
|
||||
}
|
||||
.onEach { _isUserSwitchingInProgress.value = it }
|
||||
// TODO (b/262838215), Make this stateIn and initialize directly in field declaration
|
||||
// once the flag is launched
|
||||
.launchIn(applicationScope)
|
||||
}
|
||||
|
||||
private fun observeSelectedUser() {
|
||||
conflatedCallbackFlow {
|
||||
fun send() {
|
||||
|
||||
@@ -17,12 +17,17 @@
|
||||
|
||||
package com.android.systemui.user.data.repository
|
||||
|
||||
import android.app.IActivityManager
|
||||
import android.app.UserSwitchObserver
|
||||
import android.content.pm.UserInfo
|
||||
import android.os.IRemoteCallback
|
||||
import android.os.UserHandle
|
||||
import android.os.UserManager
|
||||
import android.provider.Settings
|
||||
import androidx.test.filters.SmallTest
|
||||
import com.android.systemui.SysuiTestCase
|
||||
import com.android.systemui.flags.FakeFeatureFlags
|
||||
import com.android.systemui.flags.Flags.FACE_AUTH_REFACTOR
|
||||
import com.android.systemui.settings.FakeUserTracker
|
||||
import com.android.systemui.user.data.model.UserSwitcherSettingsModel
|
||||
import com.android.systemui.util.settings.FakeSettings
|
||||
@@ -39,7 +44,14 @@ import org.junit.Before
|
||||
import org.junit.Test
|
||||
import org.junit.runner.RunWith
|
||||
import org.junit.runners.JUnit4
|
||||
import org.mockito.ArgumentCaptor
|
||||
import org.mockito.Captor
|
||||
import org.mockito.Mock
|
||||
import org.mockito.Mockito.any
|
||||
import org.mockito.Mockito.anyString
|
||||
import org.mockito.Mockito.mock
|
||||
import org.mockito.Mockito.times
|
||||
import org.mockito.Mockito.verify
|
||||
import org.mockito.Mockito.`when` as whenever
|
||||
import org.mockito.MockitoAnnotations
|
||||
|
||||
@@ -48,6 +60,8 @@ import org.mockito.MockitoAnnotations
|
||||
class UserRepositoryImplTest : SysuiTestCase() {
|
||||
|
||||
@Mock private lateinit var manager: UserManager
|
||||
@Mock private lateinit var activityManager: IActivityManager
|
||||
@Captor private lateinit var userSwitchObserver: ArgumentCaptor<UserSwitchObserver>
|
||||
|
||||
private lateinit var underTest: UserRepositoryImpl
|
||||
|
||||
@@ -214,6 +228,34 @@ class UserRepositoryImplTest : SysuiTestCase() {
|
||||
assertThat(selectedUserInfo?.id).isEqualTo(1)
|
||||
}
|
||||
|
||||
@Test
|
||||
fun userSwitchingInProgress_registersOnlyOneUserSwitchObserver() = runSelfCancelingTest {
|
||||
underTest = create(this)
|
||||
|
||||
underTest.userSwitchingInProgress.launchIn(this)
|
||||
underTest.userSwitchingInProgress.launchIn(this)
|
||||
underTest.userSwitchingInProgress.launchIn(this)
|
||||
|
||||
verify(activityManager, times(1)).registerUserSwitchObserver(any(), anyString())
|
||||
}
|
||||
|
||||
@Test
|
||||
fun userSwitchingInProgress_propagatesStateFromActivityManager() = runSelfCancelingTest {
|
||||
underTest = create(this)
|
||||
verify(activityManager)
|
||||
.registerUserSwitchObserver(userSwitchObserver.capture(), anyString())
|
||||
|
||||
userSwitchObserver.value.onUserSwitching(0, mock(IRemoteCallback::class.java))
|
||||
|
||||
var mostRecentSwitchingValue = false
|
||||
underTest.userSwitchingInProgress.onEach { mostRecentSwitchingValue = it }.launchIn(this)
|
||||
|
||||
assertThat(mostRecentSwitchingValue).isTrue()
|
||||
|
||||
userSwitchObserver.value.onUserSwitchComplete(0)
|
||||
assertThat(mostRecentSwitchingValue).isFalse()
|
||||
}
|
||||
|
||||
private fun createUserInfo(
|
||||
id: Int,
|
||||
isGuest: Boolean,
|
||||
@@ -280,6 +322,8 @@ class UserRepositoryImplTest : SysuiTestCase() {
|
||||
}
|
||||
|
||||
private fun create(scope: CoroutineScope = TestCoroutineScope()): UserRepositoryImpl {
|
||||
val featureFlags = FakeFeatureFlags()
|
||||
featureFlags.set(FACE_AUTH_REFACTOR, true)
|
||||
return UserRepositoryImpl(
|
||||
appContext = context,
|
||||
manager = manager,
|
||||
@@ -288,6 +332,8 @@ class UserRepositoryImplTest : SysuiTestCase() {
|
||||
backgroundDispatcher = IMMEDIATE,
|
||||
globalSettings = globalSettings,
|
||||
tracker = tracker,
|
||||
activityManager = activityManager,
|
||||
featureFlags = featureFlags,
|
||||
)
|
||||
}
|
||||
|
||||
|
||||
@@ -39,6 +39,10 @@ class FakeUserRepository : UserRepository {
|
||||
private val _selectedUserInfo = MutableStateFlow<UserInfo?>(null)
|
||||
override val selectedUserInfo: Flow<UserInfo> = _selectedUserInfo.filterNotNull()
|
||||
|
||||
private val _userSwitchingInProgress = MutableStateFlow(false)
|
||||
override val userSwitchingInProgress: Flow<Boolean>
|
||||
get() = _userSwitchingInProgress
|
||||
|
||||
override var lastSelectedNonGuestUserId: Int = UserHandle.USER_SYSTEM
|
||||
|
||||
private var _isGuestUserAutoCreated: Boolean = false
|
||||
|
||||
Reference in New Issue
Block a user