Merge "UserSwitcherController impl uses UserInteractor" into tm-qpr-dev am: 37f4b300c6
Original change: https://googleplex-android-review.googlesource.com/c/platform/frameworks/base/+/20090976 Change-Id: I1a3d139feb426db437533f92c1278218d0eace02 Signed-off-by: Automerger Merge Worker <android-build-automerger-merge-worker@system.gserviceaccount.com>
This commit is contained in:
@@ -17,12 +17,21 @@
|
|||||||
|
|
||||||
package com.android.systemui.statusbar.policy
|
package com.android.systemui.statusbar.policy
|
||||||
|
|
||||||
|
import android.content.Context
|
||||||
import android.content.Intent
|
import android.content.Intent
|
||||||
import android.view.View
|
import android.view.View
|
||||||
|
import com.android.systemui.dagger.SysUISingleton
|
||||||
|
import com.android.systemui.dagger.qualifiers.Application
|
||||||
import com.android.systemui.flags.FeatureFlags
|
import com.android.systemui.flags.FeatureFlags
|
||||||
import com.android.systemui.flags.Flags
|
import com.android.systemui.flags.Flags
|
||||||
|
import com.android.systemui.keyguard.domain.interactor.KeyguardInteractor
|
||||||
|
import com.android.systemui.plugins.ActivityStarter
|
||||||
import com.android.systemui.qs.user.UserSwitchDialogController
|
import com.android.systemui.qs.user.UserSwitchDialogController
|
||||||
import com.android.systemui.user.data.source.UserRecord
|
import com.android.systemui.user.data.source.UserRecord
|
||||||
|
import com.android.systemui.user.domain.interactor.GuestUserInteractor
|
||||||
|
import com.android.systemui.user.domain.interactor.UserInteractor
|
||||||
|
import com.android.systemui.user.legacyhelper.data.LegacyUserDataHelper
|
||||||
|
import com.android.systemui.user.legacyhelper.ui.LegacyUserUiHelper
|
||||||
import dagger.Lazy
|
import dagger.Lazy
|
||||||
import java.io.PrintWriter
|
import java.io.PrintWriter
|
||||||
import java.lang.ref.WeakReference
|
import java.lang.ref.WeakReference
|
||||||
@@ -30,11 +39,17 @@ import javax.inject.Inject
|
|||||||
import kotlinx.coroutines.flow.Flow
|
import kotlinx.coroutines.flow.Flow
|
||||||
|
|
||||||
/** Implementation of [UserSwitcherController]. */
|
/** Implementation of [UserSwitcherController]. */
|
||||||
|
@SysUISingleton
|
||||||
class UserSwitcherControllerImpl
|
class UserSwitcherControllerImpl
|
||||||
@Inject
|
@Inject
|
||||||
constructor(
|
constructor(
|
||||||
private val flags: FeatureFlags,
|
@Application private val applicationContext: Context,
|
||||||
|
flags: FeatureFlags,
|
||||||
@Suppress("DEPRECATION") private val oldImpl: Lazy<UserSwitcherControllerOldImpl>,
|
@Suppress("DEPRECATION") private val oldImpl: Lazy<UserSwitcherControllerOldImpl>,
|
||||||
|
private val userInteractorLazy: Lazy<UserInteractor>,
|
||||||
|
private val guestUserInteractorLazy: Lazy<GuestUserInteractor>,
|
||||||
|
private val keyguardInteractorLazy: Lazy<KeyguardInteractor>,
|
||||||
|
private val activityStarter: ActivityStarter,
|
||||||
) : UserSwitcherController {
|
) : UserSwitcherController {
|
||||||
|
|
||||||
private val useInteractor: Boolean =
|
private val useInteractor: Boolean =
|
||||||
@@ -42,15 +57,21 @@ constructor(
|
|||||||
!flags.isEnabled(Flags.USER_INTERACTOR_AND_REPO_USE_CONTROLLER)
|
!flags.isEnabled(Flags.USER_INTERACTOR_AND_REPO_USE_CONTROLLER)
|
||||||
private val _oldImpl: UserSwitcherControllerOldImpl
|
private val _oldImpl: UserSwitcherControllerOldImpl
|
||||||
get() = oldImpl.get()
|
get() = oldImpl.get()
|
||||||
|
private val userInteractor: UserInteractor by lazy { userInteractorLazy.get() }
|
||||||
|
private val guestUserInteractor: GuestUserInteractor by lazy { guestUserInteractorLazy.get() }
|
||||||
|
private val keyguardInteractor: KeyguardInteractor by lazy { keyguardInteractorLazy.get() }
|
||||||
|
|
||||||
private fun notYetImplemented(): Nothing {
|
private val callbackCompatMap =
|
||||||
error("Not yet implemented!")
|
mutableMapOf<UserSwitcherController.UserSwitchCallback, UserInteractor.UserCallback>()
|
||||||
|
|
||||||
|
private fun notSupported(): Nothing {
|
||||||
|
error("Not supported in the new implementation!")
|
||||||
}
|
}
|
||||||
|
|
||||||
override val users: ArrayList<UserRecord>
|
override val users: ArrayList<UserRecord>
|
||||||
get() =
|
get() =
|
||||||
if (useInteractor) {
|
if (useInteractor) {
|
||||||
notYetImplemented()
|
userInteractor.userRecords.value
|
||||||
} else {
|
} else {
|
||||||
_oldImpl.users
|
_oldImpl.users
|
||||||
}
|
}
|
||||||
@@ -58,15 +79,13 @@ constructor(
|
|||||||
override val isSimpleUserSwitcher: Boolean
|
override val isSimpleUserSwitcher: Boolean
|
||||||
get() =
|
get() =
|
||||||
if (useInteractor) {
|
if (useInteractor) {
|
||||||
notYetImplemented()
|
userInteractor.isSimpleUserSwitcher
|
||||||
} else {
|
} else {
|
||||||
_oldImpl.isSimpleUserSwitcher
|
_oldImpl.isSimpleUserSwitcher
|
||||||
}
|
}
|
||||||
|
|
||||||
override fun init(view: View) {
|
override fun init(view: View) {
|
||||||
if (useInteractor) {
|
if (!useInteractor) {
|
||||||
notYetImplemented()
|
|
||||||
} else {
|
|
||||||
_oldImpl.init(view)
|
_oldImpl.init(view)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -74,7 +93,7 @@ constructor(
|
|||||||
override val currentUserRecord: UserRecord?
|
override val currentUserRecord: UserRecord?
|
||||||
get() =
|
get() =
|
||||||
if (useInteractor) {
|
if (useInteractor) {
|
||||||
notYetImplemented()
|
userInteractor.selectedUserRecord.value
|
||||||
} else {
|
} else {
|
||||||
_oldImpl.currentUserRecord
|
_oldImpl.currentUserRecord
|
||||||
}
|
}
|
||||||
@@ -82,7 +101,14 @@ constructor(
|
|||||||
override val currentUserName: String?
|
override val currentUserName: String?
|
||||||
get() =
|
get() =
|
||||||
if (useInteractor) {
|
if (useInteractor) {
|
||||||
notYetImplemented()
|
currentUserRecord?.let {
|
||||||
|
LegacyUserUiHelper.getUserRecordName(
|
||||||
|
context = applicationContext,
|
||||||
|
record = it,
|
||||||
|
isGuestUserAutoCreated = userInteractor.isGuestUserAutoCreated,
|
||||||
|
isGuestUserResetting = userInteractor.isGuestUserResetting,
|
||||||
|
)
|
||||||
|
}
|
||||||
} else {
|
} else {
|
||||||
_oldImpl.currentUserName
|
_oldImpl.currentUserName
|
||||||
}
|
}
|
||||||
@@ -92,7 +118,7 @@ constructor(
|
|||||||
dialogShower: UserSwitchDialogController.DialogShower?
|
dialogShower: UserSwitchDialogController.DialogShower?
|
||||||
) {
|
) {
|
||||||
if (useInteractor) {
|
if (useInteractor) {
|
||||||
notYetImplemented()
|
userInteractor.selectUser(userId)
|
||||||
} else {
|
} else {
|
||||||
_oldImpl.onUserSelected(userId, dialogShower)
|
_oldImpl.onUserSelected(userId, dialogShower)
|
||||||
}
|
}
|
||||||
@@ -101,7 +127,7 @@ constructor(
|
|||||||
override val isAddUsersFromLockScreenEnabled: Flow<Boolean>
|
override val isAddUsersFromLockScreenEnabled: Flow<Boolean>
|
||||||
get() =
|
get() =
|
||||||
if (useInteractor) {
|
if (useInteractor) {
|
||||||
notYetImplemented()
|
notSupported()
|
||||||
} else {
|
} else {
|
||||||
_oldImpl.isAddUsersFromLockScreenEnabled
|
_oldImpl.isAddUsersFromLockScreenEnabled
|
||||||
}
|
}
|
||||||
@@ -109,7 +135,7 @@ constructor(
|
|||||||
override val isGuestUserAutoCreated: Boolean
|
override val isGuestUserAutoCreated: Boolean
|
||||||
get() =
|
get() =
|
||||||
if (useInteractor) {
|
if (useInteractor) {
|
||||||
notYetImplemented()
|
userInteractor.isGuestUserAutoCreated
|
||||||
} else {
|
} else {
|
||||||
_oldImpl.isGuestUserAutoCreated
|
_oldImpl.isGuestUserAutoCreated
|
||||||
}
|
}
|
||||||
@@ -117,7 +143,7 @@ constructor(
|
|||||||
override val isGuestUserResetting: Boolean
|
override val isGuestUserResetting: Boolean
|
||||||
get() =
|
get() =
|
||||||
if (useInteractor) {
|
if (useInteractor) {
|
||||||
notYetImplemented()
|
userInteractor.isGuestUserResetting
|
||||||
} else {
|
} else {
|
||||||
_oldImpl.isGuestUserResetting
|
_oldImpl.isGuestUserResetting
|
||||||
}
|
}
|
||||||
@@ -126,7 +152,7 @@ constructor(
|
|||||||
dialogShower: UserSwitchDialogController.DialogShower?,
|
dialogShower: UserSwitchDialogController.DialogShower?,
|
||||||
) {
|
) {
|
||||||
if (useInteractor) {
|
if (useInteractor) {
|
||||||
notYetImplemented()
|
notSupported()
|
||||||
} else {
|
} else {
|
||||||
_oldImpl.createAndSwitchToGuestUser(dialogShower)
|
_oldImpl.createAndSwitchToGuestUser(dialogShower)
|
||||||
}
|
}
|
||||||
@@ -134,7 +160,7 @@ constructor(
|
|||||||
|
|
||||||
override fun showAddUserDialog(dialogShower: UserSwitchDialogController.DialogShower?) {
|
override fun showAddUserDialog(dialogShower: UserSwitchDialogController.DialogShower?) {
|
||||||
if (useInteractor) {
|
if (useInteractor) {
|
||||||
notYetImplemented()
|
notSupported()
|
||||||
} else {
|
} else {
|
||||||
_oldImpl.showAddUserDialog(dialogShower)
|
_oldImpl.showAddUserDialog(dialogShower)
|
||||||
}
|
}
|
||||||
@@ -142,23 +168,31 @@ constructor(
|
|||||||
|
|
||||||
override fun startSupervisedUserActivity() {
|
override fun startSupervisedUserActivity() {
|
||||||
if (useInteractor) {
|
if (useInteractor) {
|
||||||
notYetImplemented()
|
notSupported()
|
||||||
} else {
|
} else {
|
||||||
_oldImpl.startSupervisedUserActivity()
|
_oldImpl.startSupervisedUserActivity()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
override fun onDensityOrFontScaleChanged() {
|
override fun onDensityOrFontScaleChanged() {
|
||||||
if (useInteractor) {
|
if (!useInteractor) {
|
||||||
notYetImplemented()
|
|
||||||
} else {
|
|
||||||
_oldImpl.onDensityOrFontScaleChanged()
|
_oldImpl.onDensityOrFontScaleChanged()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
override fun addAdapter(adapter: WeakReference<BaseUserSwitcherAdapter>) {
|
override fun addAdapter(adapter: WeakReference<BaseUserSwitcherAdapter>) {
|
||||||
if (useInteractor) {
|
if (useInteractor) {
|
||||||
notYetImplemented()
|
userInteractor.addCallback(
|
||||||
|
object : UserInteractor.UserCallback {
|
||||||
|
override fun isEvictable(): Boolean {
|
||||||
|
return adapter.get() == null
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun onUserStateChanged() {
|
||||||
|
adapter.get()?.notifyDataSetChanged()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
)
|
||||||
} else {
|
} else {
|
||||||
_oldImpl.addAdapter(adapter)
|
_oldImpl.addAdapter(adapter)
|
||||||
}
|
}
|
||||||
@@ -169,7 +203,11 @@ constructor(
|
|||||||
dialogShower: UserSwitchDialogController.DialogShower?,
|
dialogShower: UserSwitchDialogController.DialogShower?,
|
||||||
) {
|
) {
|
||||||
if (useInteractor) {
|
if (useInteractor) {
|
||||||
notYetImplemented()
|
if (LegacyUserDataHelper.isUser(record)) {
|
||||||
|
userInteractor.selectUser(record.resolveId())
|
||||||
|
} else {
|
||||||
|
userInteractor.executeAction(LegacyUserDataHelper.toUserActionModel(record))
|
||||||
|
}
|
||||||
} else {
|
} else {
|
||||||
_oldImpl.onUserListItemClicked(record, dialogShower)
|
_oldImpl.onUserListItemClicked(record, dialogShower)
|
||||||
}
|
}
|
||||||
@@ -177,7 +215,10 @@ constructor(
|
|||||||
|
|
||||||
override fun removeGuestUser(guestUserId: Int, targetUserId: Int) {
|
override fun removeGuestUser(guestUserId: Int, targetUserId: Int) {
|
||||||
if (useInteractor) {
|
if (useInteractor) {
|
||||||
notYetImplemented()
|
userInteractor.removeGuestUser(
|
||||||
|
guestUserId = guestUserId,
|
||||||
|
targetUserId = targetUserId,
|
||||||
|
)
|
||||||
} else {
|
} else {
|
||||||
_oldImpl.removeGuestUser(guestUserId, targetUserId)
|
_oldImpl.removeGuestUser(guestUserId, targetUserId)
|
||||||
}
|
}
|
||||||
@@ -189,7 +230,7 @@ constructor(
|
|||||||
forceRemoveGuestOnExit: Boolean
|
forceRemoveGuestOnExit: Boolean
|
||||||
) {
|
) {
|
||||||
if (useInteractor) {
|
if (useInteractor) {
|
||||||
notYetImplemented()
|
userInteractor.exitGuestUser(guestUserId, targetUserId, forceRemoveGuestOnExit)
|
||||||
} else {
|
} else {
|
||||||
_oldImpl.exitGuestUser(guestUserId, targetUserId, forceRemoveGuestOnExit)
|
_oldImpl.exitGuestUser(guestUserId, targetUserId, forceRemoveGuestOnExit)
|
||||||
}
|
}
|
||||||
@@ -197,7 +238,7 @@ constructor(
|
|||||||
|
|
||||||
override fun schedulePostBootGuestCreation() {
|
override fun schedulePostBootGuestCreation() {
|
||||||
if (useInteractor) {
|
if (useInteractor) {
|
||||||
notYetImplemented()
|
guestUserInteractor.onDeviceBootCompleted()
|
||||||
} else {
|
} else {
|
||||||
_oldImpl.schedulePostBootGuestCreation()
|
_oldImpl.schedulePostBootGuestCreation()
|
||||||
}
|
}
|
||||||
@@ -206,14 +247,14 @@ constructor(
|
|||||||
override val isKeyguardShowing: Boolean
|
override val isKeyguardShowing: Boolean
|
||||||
get() =
|
get() =
|
||||||
if (useInteractor) {
|
if (useInteractor) {
|
||||||
notYetImplemented()
|
keyguardInteractor.isKeyguardShowing()
|
||||||
} else {
|
} else {
|
||||||
_oldImpl.isKeyguardShowing
|
_oldImpl.isKeyguardShowing
|
||||||
}
|
}
|
||||||
|
|
||||||
override fun startActivity(intent: Intent) {
|
override fun startActivity(intent: Intent) {
|
||||||
if (useInteractor) {
|
if (useInteractor) {
|
||||||
notYetImplemented()
|
activityStarter.startActivity(intent, /* dismissShade= */ false)
|
||||||
} else {
|
} else {
|
||||||
_oldImpl.startActivity(intent)
|
_oldImpl.startActivity(intent)
|
||||||
}
|
}
|
||||||
@@ -221,7 +262,7 @@ constructor(
|
|||||||
|
|
||||||
override fun refreshUsers(forcePictureLoadForId: Int) {
|
override fun refreshUsers(forcePictureLoadForId: Int) {
|
||||||
if (useInteractor) {
|
if (useInteractor) {
|
||||||
notYetImplemented()
|
userInteractor.refreshUsers()
|
||||||
} else {
|
} else {
|
||||||
_oldImpl.refreshUsers(forcePictureLoadForId)
|
_oldImpl.refreshUsers(forcePictureLoadForId)
|
||||||
}
|
}
|
||||||
@@ -229,7 +270,14 @@ constructor(
|
|||||||
|
|
||||||
override fun addUserSwitchCallback(callback: UserSwitcherController.UserSwitchCallback) {
|
override fun addUserSwitchCallback(callback: UserSwitcherController.UserSwitchCallback) {
|
||||||
if (useInteractor) {
|
if (useInteractor) {
|
||||||
notYetImplemented()
|
val interactorCallback =
|
||||||
|
object : UserInteractor.UserCallback {
|
||||||
|
override fun onUserStateChanged() {
|
||||||
|
callback.onUserSwitched()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
callbackCompatMap[callback] = interactorCallback
|
||||||
|
userInteractor.addCallback(interactorCallback)
|
||||||
} else {
|
} else {
|
||||||
_oldImpl.addUserSwitchCallback(callback)
|
_oldImpl.addUserSwitchCallback(callback)
|
||||||
}
|
}
|
||||||
@@ -237,7 +285,10 @@ constructor(
|
|||||||
|
|
||||||
override fun removeUserSwitchCallback(callback: UserSwitcherController.UserSwitchCallback) {
|
override fun removeUserSwitchCallback(callback: UserSwitcherController.UserSwitchCallback) {
|
||||||
if (useInteractor) {
|
if (useInteractor) {
|
||||||
notYetImplemented()
|
val interactorCallback = callbackCompatMap.remove(callback)
|
||||||
|
if (interactorCallback != null) {
|
||||||
|
userInteractor.removeCallback(interactorCallback)
|
||||||
|
}
|
||||||
} else {
|
} else {
|
||||||
_oldImpl.removeUserSwitchCallback(callback)
|
_oldImpl.removeUserSwitchCallback(callback)
|
||||||
}
|
}
|
||||||
@@ -245,7 +296,7 @@ constructor(
|
|||||||
|
|
||||||
override fun dump(pw: PrintWriter, args: Array<out String>) {
|
override fun dump(pw: PrintWriter, args: Array<out String>) {
|
||||||
if (useInteractor) {
|
if (useInteractor) {
|
||||||
notYetImplemented()
|
userInteractor.dump(pw)
|
||||||
} else {
|
} else {
|
||||||
_oldImpl.dump(pw, args)
|
_oldImpl.dump(pw, args)
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -173,7 +173,7 @@ constructor(
|
|||||||
}
|
}
|
||||||
|
|
||||||
/** Removes the guest user from the device. */
|
/** Removes the guest user from the device. */
|
||||||
private suspend fun remove(
|
suspend fun remove(
|
||||||
@UserIdInt guestUserId: Int,
|
@UserIdInt guestUserId: Int,
|
||||||
@UserIdInt targetUserId: Int,
|
@UserIdInt targetUserId: Int,
|
||||||
showDialog: (ShowDialogRequestModel) -> Unit,
|
showDialog: (ShowDialogRequestModel) -> Unit,
|
||||||
|
|||||||
@@ -52,8 +52,7 @@ import com.android.systemui.user.legacyhelper.data.LegacyUserDataHelper
|
|||||||
import com.android.systemui.user.shared.model.UserActionModel
|
import com.android.systemui.user.shared.model.UserActionModel
|
||||||
import com.android.systemui.user.shared.model.UserModel
|
import com.android.systemui.user.shared.model.UserModel
|
||||||
import com.android.systemui.util.kotlin.pairwise
|
import com.android.systemui.util.kotlin.pairwise
|
||||||
import java.util.Collections
|
import java.io.PrintWriter
|
||||||
import java.util.WeakHashMap
|
|
||||||
import javax.inject.Inject
|
import javax.inject.Inject
|
||||||
import kotlinx.coroutines.CoroutineDispatcher
|
import kotlinx.coroutines.CoroutineDispatcher
|
||||||
import kotlinx.coroutines.CoroutineScope
|
import kotlinx.coroutines.CoroutineScope
|
||||||
@@ -70,6 +69,9 @@ import kotlinx.coroutines.flow.launchIn
|
|||||||
import kotlinx.coroutines.flow.map
|
import kotlinx.coroutines.flow.map
|
||||||
import kotlinx.coroutines.flow.onEach
|
import kotlinx.coroutines.flow.onEach
|
||||||
import kotlinx.coroutines.flow.stateIn
|
import kotlinx.coroutines.flow.stateIn
|
||||||
|
import kotlinx.coroutines.launch
|
||||||
|
import kotlinx.coroutines.sync.Mutex
|
||||||
|
import kotlinx.coroutines.sync.withLock
|
||||||
import kotlinx.coroutines.withContext
|
import kotlinx.coroutines.withContext
|
||||||
|
|
||||||
/** Encapsulates business logic to interact with user data and systems. */
|
/** Encapsulates business logic to interact with user data and systems. */
|
||||||
@@ -96,7 +98,9 @@ constructor(
|
|||||||
* Defines interface for classes that can be notified when the state of users on the device is
|
* Defines interface for classes that can be notified when the state of users on the device is
|
||||||
* changed.
|
* changed.
|
||||||
*/
|
*/
|
||||||
fun interface UserCallback {
|
interface UserCallback {
|
||||||
|
/** Returns `true` if this callback can be cleaned-up. */
|
||||||
|
fun isEvictable(): Boolean = false
|
||||||
/** Notifies that the state of users on the device has changed. */
|
/** Notifies that the state of users on the device has changed. */
|
||||||
fun onUserStateChanged()
|
fun onUserStateChanged()
|
||||||
}
|
}
|
||||||
@@ -110,7 +114,8 @@ constructor(
|
|||||||
com.android.internal.R.string.config_supervisedUserCreationPackage
|
com.android.internal.R.string.config_supervisedUserCreationPackage
|
||||||
)
|
)
|
||||||
|
|
||||||
private val callbacks = Collections.newSetFromMap(WeakHashMap<UserCallback, Boolean>())
|
private val callbackMutex = Mutex()
|
||||||
|
private val callbacks = mutableSetOf<UserCallback>()
|
||||||
|
|
||||||
/** List of current on-device users to select from. */
|
/** List of current on-device users to select from. */
|
||||||
val users: Flow<List<UserModel>>
|
val users: Flow<List<UserModel>>
|
||||||
@@ -263,6 +268,7 @@ constructor(
|
|||||||
}
|
}
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
.onEach { notifyCallbacks() }
|
||||||
.stateIn(
|
.stateIn(
|
||||||
scope = applicationScope,
|
scope = applicationScope,
|
||||||
started = SharingStarted.Eagerly,
|
started = SharingStarted.Eagerly,
|
||||||
@@ -307,30 +313,6 @@ constructor(
|
|||||||
error("Not supported in the old implementation!")
|
error("Not supported in the old implementation!")
|
||||||
}
|
}
|
||||||
|
|
||||||
fun addCallback(callback: UserCallback) {
|
|
||||||
callbacks.add(callback)
|
|
||||||
}
|
|
||||||
|
|
||||||
fun removeCallback(callback: UserCallback) {
|
|
||||||
callbacks.remove(callback)
|
|
||||||
}
|
|
||||||
|
|
||||||
fun onDialogShown() {
|
|
||||||
_dialogShowRequests.value = null
|
|
||||||
}
|
|
||||||
|
|
||||||
fun onDialogDismissed() {
|
|
||||||
_dialogDismissRequests.value = null
|
|
||||||
}
|
|
||||||
|
|
||||||
private fun showDialog(request: ShowDialogRequestModel) {
|
|
||||||
_dialogShowRequests.value = request
|
|
||||||
}
|
|
||||||
|
|
||||||
private fun dismissDialog() {
|
|
||||||
_dialogDismissRequests.value = Unit
|
|
||||||
}
|
|
||||||
|
|
||||||
init {
|
init {
|
||||||
if (isNewImpl) {
|
if (isNewImpl) {
|
||||||
refreshUsersScheduler.refreshIfNotPaused()
|
refreshUsersScheduler.refreshIfNotPaused()
|
||||||
@@ -364,6 +346,46 @@ constructor(
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fun addCallback(callback: UserCallback) {
|
||||||
|
applicationScope.launch { callbackMutex.withLock { callbacks.add(callback) } }
|
||||||
|
}
|
||||||
|
|
||||||
|
fun removeCallback(callback: UserCallback) {
|
||||||
|
applicationScope.launch { callbackMutex.withLock { callbacks.remove(callback) } }
|
||||||
|
}
|
||||||
|
|
||||||
|
fun refreshUsers() {
|
||||||
|
refreshUsersScheduler.refreshIfNotPaused()
|
||||||
|
}
|
||||||
|
|
||||||
|
fun onDialogShown() {
|
||||||
|
_dialogShowRequests.value = null
|
||||||
|
}
|
||||||
|
|
||||||
|
fun onDialogDismissed() {
|
||||||
|
_dialogDismissRequests.value = null
|
||||||
|
}
|
||||||
|
|
||||||
|
fun dump(pw: PrintWriter) {
|
||||||
|
pw.println("UserInteractor state:")
|
||||||
|
pw.println(" lastSelectedNonGuestUserId=${repository.lastSelectedNonGuestUserId}")
|
||||||
|
|
||||||
|
val users = userRecords.value.filter { it.info != null }
|
||||||
|
pw.println(" userCount=${userRecords.value.count { LegacyUserDataHelper.isUser(it) }}")
|
||||||
|
for (i in users.indices) {
|
||||||
|
pw.println(" ${users[i]}")
|
||||||
|
}
|
||||||
|
|
||||||
|
val actions = userRecords.value.filter { it.info == null }
|
||||||
|
pw.println(" actionCount=${userRecords.value.count { !LegacyUserDataHelper.isUser(it) }}")
|
||||||
|
for (i in actions.indices) {
|
||||||
|
pw.println(" ${actions[i]}")
|
||||||
|
}
|
||||||
|
|
||||||
|
pw.println("isSimpleUserSwitcher=$isSimpleUserSwitcher")
|
||||||
|
pw.println("isGuestUserAutoCreated=$isGuestUserAutoCreated")
|
||||||
|
}
|
||||||
|
|
||||||
fun onDeviceBootCompleted() {
|
fun onDeviceBootCompleted() {
|
||||||
guestUserInteractor.onDeviceBootCompleted()
|
guestUserInteractor.onDeviceBootCompleted()
|
||||||
}
|
}
|
||||||
@@ -460,6 +482,60 @@ constructor(
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fun exitGuestUser(
|
||||||
|
@UserIdInt guestUserId: Int,
|
||||||
|
@UserIdInt targetUserId: Int,
|
||||||
|
forceRemoveGuestOnExit: Boolean,
|
||||||
|
) {
|
||||||
|
guestUserInteractor.exit(
|
||||||
|
guestUserId = guestUserId,
|
||||||
|
targetUserId = targetUserId,
|
||||||
|
forceRemoveGuestOnExit = forceRemoveGuestOnExit,
|
||||||
|
showDialog = this::showDialog,
|
||||||
|
dismissDialog = this::dismissDialog,
|
||||||
|
switchUser = this::switchUser,
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
|
fun removeGuestUser(
|
||||||
|
@UserIdInt guestUserId: Int,
|
||||||
|
@UserIdInt targetUserId: Int,
|
||||||
|
) {
|
||||||
|
applicationScope.launch {
|
||||||
|
guestUserInteractor.remove(
|
||||||
|
guestUserId = guestUserId,
|
||||||
|
targetUserId = targetUserId,
|
||||||
|
::showDialog,
|
||||||
|
::dismissDialog,
|
||||||
|
::selectUser,
|
||||||
|
)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private fun showDialog(request: ShowDialogRequestModel) {
|
||||||
|
_dialogShowRequests.value = request
|
||||||
|
}
|
||||||
|
|
||||||
|
private fun dismissDialog() {
|
||||||
|
_dialogDismissRequests.value = Unit
|
||||||
|
}
|
||||||
|
|
||||||
|
private fun notifyCallbacks() {
|
||||||
|
applicationScope.launch {
|
||||||
|
callbackMutex.withLock {
|
||||||
|
val iterator = callbacks.iterator()
|
||||||
|
while (iterator.hasNext()) {
|
||||||
|
val callback = iterator.next()
|
||||||
|
if (!callback.isEvictable()) {
|
||||||
|
callback.onUserStateChanged()
|
||||||
|
} else {
|
||||||
|
iterator.remove()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
private suspend fun toRecord(
|
private suspend fun toRecord(
|
||||||
userInfo: UserInfo,
|
userInfo: UserInfo,
|
||||||
selectedUserId: Int,
|
selectedUserId: Int,
|
||||||
@@ -498,21 +574,6 @@ constructor(
|
|||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
private fun exitGuestUser(
|
|
||||||
@UserIdInt guestUserId: Int,
|
|
||||||
@UserIdInt targetUserId: Int,
|
|
||||||
forceRemoveGuestOnExit: Boolean,
|
|
||||||
) {
|
|
||||||
guestUserInteractor.exit(
|
|
||||||
guestUserId = guestUserId,
|
|
||||||
targetUserId = targetUserId,
|
|
||||||
forceRemoveGuestOnExit = forceRemoveGuestOnExit,
|
|
||||||
showDialog = this::showDialog,
|
|
||||||
dismissDialog = this::dismissDialog,
|
|
||||||
switchUser = this::switchUser,
|
|
||||||
)
|
|
||||||
}
|
|
||||||
|
|
||||||
private fun switchUser(userId: Int) {
|
private fun switchUser(userId: Int) {
|
||||||
// TODO(b/246631653): track jank and lantecy like in the old impl.
|
// TODO(b/246631653): track jank and lantecy like in the old impl.
|
||||||
refreshUsersScheduler.pause()
|
refreshUsersScheduler.pause()
|
||||||
@@ -533,7 +594,7 @@ constructor(
|
|||||||
dismissDialog()
|
dismissDialog()
|
||||||
val selectedUserId = intent.getIntExtra(Intent.EXTRA_USER_HANDLE, -1)
|
val selectedUserId = intent.getIntExtra(Intent.EXTRA_USER_HANDLE, -1)
|
||||||
if (previousUserInfo?.id != selectedUserId) {
|
if (previousUserInfo?.id != selectedUserId) {
|
||||||
callbacks.forEach { it.onUserStateChanged() }
|
notifyCallbacks()
|
||||||
restartSecondaryService(selectedUserId)
|
restartSecondaryService(selectedUserId)
|
||||||
}
|
}
|
||||||
if (guestUserInteractor.isGuestUserAutoCreated) {
|
if (guestUserInteractor.isGuestUserAutoCreated) {
|
||||||
|
|||||||
@@ -83,6 +83,21 @@ object LegacyUserDataHelper {
|
|||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fun toUserActionModel(record: UserRecord): UserActionModel {
|
||||||
|
check(!isUser(record))
|
||||||
|
|
||||||
|
return when {
|
||||||
|
record.isAddUser -> UserActionModel.ADD_USER
|
||||||
|
record.isAddSupervisedUser -> UserActionModel.ADD_SUPERVISED_USER
|
||||||
|
record.isGuest -> UserActionModel.ENTER_GUEST_MODE
|
||||||
|
else -> error("Not a known action: $record")
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
fun isUser(record: UserRecord): Boolean {
|
||||||
|
return record.info != null
|
||||||
|
}
|
||||||
|
|
||||||
private fun getEnforcedAdmin(
|
private fun getEnforcedAdmin(
|
||||||
context: Context,
|
context: Context,
|
||||||
selectedUserId: Int,
|
selectedUserId: Int,
|
||||||
|
|||||||
@@ -289,15 +289,73 @@ class GuestUserInteractorTest : SysuiTestCase() {
|
|||||||
verifyDidNotExit()
|
verifyDidNotExit()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
fun `remove - returns to target user`() =
|
||||||
|
runBlocking(IMMEDIATE) {
|
||||||
|
whenever(manager.markGuestForDeletion(anyInt())).thenReturn(true)
|
||||||
|
repository.setSelectedUserInfo(GUEST_USER_INFO)
|
||||||
|
|
||||||
|
val targetUserId = NON_GUEST_USER_INFO.id
|
||||||
|
underTest.remove(
|
||||||
|
guestUserId = GUEST_USER_INFO.id,
|
||||||
|
targetUserId = targetUserId,
|
||||||
|
showDialog = showDialog,
|
||||||
|
dismissDialog = dismissDialog,
|
||||||
|
switchUser = switchUser,
|
||||||
|
)
|
||||||
|
|
||||||
|
verify(manager).markGuestForDeletion(GUEST_USER_INFO.id)
|
||||||
|
verify(manager).removeUser(GUEST_USER_INFO.id)
|
||||||
|
verify(switchUser).invoke(targetUserId)
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
fun `remove - selected different from guest user - do nothing`() =
|
||||||
|
runBlocking(IMMEDIATE) {
|
||||||
|
whenever(manager.markGuestForDeletion(anyInt())).thenReturn(true)
|
||||||
|
repository.setSelectedUserInfo(NON_GUEST_USER_INFO)
|
||||||
|
|
||||||
|
underTest.remove(
|
||||||
|
guestUserId = GUEST_USER_INFO.id,
|
||||||
|
targetUserId = 123,
|
||||||
|
showDialog = showDialog,
|
||||||
|
dismissDialog = dismissDialog,
|
||||||
|
switchUser = switchUser,
|
||||||
|
)
|
||||||
|
|
||||||
|
verifyDidNotRemove()
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
fun `remove - selected is actually not a guest user - do nothing`() =
|
||||||
|
runBlocking(IMMEDIATE) {
|
||||||
|
whenever(manager.markGuestForDeletion(anyInt())).thenReturn(true)
|
||||||
|
repository.setSelectedUserInfo(NON_GUEST_USER_INFO)
|
||||||
|
|
||||||
|
underTest.remove(
|
||||||
|
guestUserId = NON_GUEST_USER_INFO.id,
|
||||||
|
targetUserId = 123,
|
||||||
|
showDialog = showDialog,
|
||||||
|
dismissDialog = dismissDialog,
|
||||||
|
switchUser = switchUser,
|
||||||
|
)
|
||||||
|
|
||||||
|
verifyDidNotRemove()
|
||||||
|
}
|
||||||
|
|
||||||
private fun setAllowedToAdd(isAllowed: Boolean = true) {
|
private fun setAllowedToAdd(isAllowed: Boolean = true) {
|
||||||
whenever(deviceProvisionedController.isDeviceProvisioned).thenReturn(isAllowed)
|
whenever(deviceProvisionedController.isDeviceProvisioned).thenReturn(isAllowed)
|
||||||
whenever(devicePolicyManager.isDeviceManaged).thenReturn(!isAllowed)
|
whenever(devicePolicyManager.isDeviceManaged).thenReturn(!isAllowed)
|
||||||
}
|
}
|
||||||
|
|
||||||
private fun verifyDidNotExit() {
|
private fun verifyDidNotExit() {
|
||||||
|
verifyDidNotRemove()
|
||||||
verify(manager, never()).getUserInfo(anyInt())
|
verify(manager, never()).getUserInfo(anyInt())
|
||||||
verify(manager, never()).markGuestForDeletion(anyInt())
|
|
||||||
verify(uiEventLogger, never()).log(any())
|
verify(uiEventLogger, never()).log(any())
|
||||||
|
}
|
||||||
|
|
||||||
|
private fun verifyDidNotRemove() {
|
||||||
|
verify(manager, never()).markGuestForDeletion(anyInt())
|
||||||
verify(showDialog, never()).invoke(any())
|
verify(showDialog, never()).invoke(any())
|
||||||
verify(dismissDialog, never()).invoke()
|
verify(dismissDialog, never()).invoke()
|
||||||
verify(switchUser, never()).invoke(anyInt())
|
verify(switchUser, never()).invoke(anyInt())
|
||||||
|
|||||||
Reference in New Issue
Block a user