1 /* 2 * Copyright (C) 2022 The Android Open Source Project 3 * 4 * Licensed under the Apache License, Version 2.0 (the "License"); 5 * you may not use this file except in compliance with the License. 6 * You may obtain a copy of the License at 7 * 8 * http://www.apache.org/licenses/LICENSE-2.0 9 * 10 * Unless required by applicable law or agreed to in writing, software 11 * distributed under the License is distributed on an "AS IS" BASIS, 12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 * See the License for the specific language governing permissions and 14 * limitations under the License. 15 * 16 */ 17 18 package com.android.systemui.user.data.repository 19 20 import android.content.pm.UserInfo 21 import android.os.UserHandle 22 import com.android.systemui.dagger.SysUISingleton 23 import com.android.systemui.user.data.model.SelectedUserModel 24 import com.android.systemui.user.data.model.SelectionStatus 25 import com.android.systemui.user.data.model.UserSwitcherSettingsModel 26 import dagger.Binds 27 import dagger.Module 28 import java.util.concurrent.atomic.AtomicBoolean 29 import javax.inject.Inject 30 import kotlinx.coroutines.flow.Flow 31 import kotlinx.coroutines.flow.MutableStateFlow 32 import kotlinx.coroutines.flow.StateFlow 33 import kotlinx.coroutines.flow.asStateFlow 34 import kotlinx.coroutines.flow.map 35 import kotlinx.coroutines.yield 36 37 @SysUISingleton 38 class FakeUserRepository @Inject constructor() : UserRepository { 39 companion object { 40 // User id to represent a non system (human) user id. We presume this is the main user. 41 const val MAIN_USER_ID = 10 42 43 const val DEFAULT_SELECTED_USER = 0 44 private val DEFAULT_SELECTED_USER_INFO = 45 UserInfo( 46 /* id= */ DEFAULT_SELECTED_USER, 47 /* name= */ "default selected user", 48 /* flags= */ 0, 49 ) 50 private val MAIN_USER = 51 UserInfo( 52 /* id= */ MAIN_USER_ID, 53 /* name= */ "main user", 54 /* flags= */ UserInfo.FLAG_MAIN, 55 ) 56 } 57 58 private val _userSwitcherSettings = MutableStateFlow(UserSwitcherSettingsModel()) 59 override val userSwitcherSettings: Flow<UserSwitcherSettingsModel> = 60 _userSwitcherSettings.asStateFlow() 61 62 private val _userInfos = MutableStateFlow<List<UserInfo>>(emptyList()) 63 override val userInfos: Flow<List<UserInfo>> = _userInfos.asStateFlow() 64 65 override val selectedUser = 66 MutableStateFlow( 67 SelectedUserModel(DEFAULT_SELECTED_USER_INFO, SelectionStatus.SELECTION_COMPLETE) 68 ) <lambda>null69 override val selectedUserInfo: Flow<UserInfo> = selectedUser.map { it.userInfo } 70 71 private val _isSecondaryUserLogoutEnabled = MutableStateFlow<Boolean>(false) 72 override val isSecondaryUserLogoutEnabled: StateFlow<Boolean> = 73 _isSecondaryUserLogoutEnabled.asStateFlow() 74 75 private val _isLogoutToSystemUserEnabled = MutableStateFlow<Boolean>(false) 76 override val isLogoutToSystemUserEnabled: StateFlow<Boolean> = 77 _isLogoutToSystemUserEnabled.asStateFlow() 78 79 override var mainUserId: Int = MAIN_USER_ID 80 override var lastSelectedNonGuestUserId: Int = mainUserId 81 82 private var _isGuestUserAutoCreated: Boolean = false 83 override val isGuestUserAutoCreated: Boolean 84 get() = _isGuestUserAutoCreated 85 86 override var isGuestUserResetting: Boolean = false 87 88 override val isGuestUserCreationScheduled = AtomicBoolean() 89 90 override var isStatusBarUserChipEnabled: Boolean = false 91 92 override var secondaryUserId: Int = UserHandle.USER_NULL 93 94 override var isRefreshUsersPaused: Boolean = false 95 getMainUserIdnull96 override suspend fun getMainUserId(): Int? { 97 return MAIN_USER_ID 98 } 99 100 var refreshUsersCallCount: Int = 0 101 private set 102 refreshUsersnull103 override fun refreshUsers() { 104 refreshUsersCallCount++ 105 } 106 getSelectedUserInfonull107 override fun getSelectedUserInfo(): UserInfo { 108 return selectedUser.value.userInfo 109 } 110 isSimpleUserSwitchernull111 override fun isSimpleUserSwitcher(): Boolean { 112 return _userSwitcherSettings.value.isSimpleUserSwitcher 113 } 114 isUserSwitcherEnablednull115 override fun isUserSwitcherEnabled(): Boolean { 116 return _userSwitcherSettings.value.isUserSwitcherEnabled 117 } 118 setSecondaryUserLogoutEnablednull119 fun setSecondaryUserLogoutEnabled(logoutEnabled: Boolean) { 120 _isSecondaryUserLogoutEnabled.value = logoutEnabled 121 } 122 123 var logOutSecondaryUserCallCount: Int = 0 124 private set 125 logOutSecondaryUsernull126 override suspend fun logOutSecondaryUser() { 127 logOutSecondaryUserCallCount++ 128 } 129 setLogoutToSystemUserEnablednull130 fun setLogoutToSystemUserEnabled(logoutEnabled: Boolean) { 131 _isLogoutToSystemUserEnabled.value = logoutEnabled 132 } 133 134 var logOutToSystemUserCallCount: Int = 0 135 private set 136 logOutToSystemUsernull137 override suspend fun logOutToSystemUser() { 138 logOutToSystemUserCallCount++ 139 } 140 setUserInfosnull141 fun setUserInfos(infos: List<UserInfo>) { 142 _userInfos.value = infos 143 } 144 setSelectedUserInfonull145 suspend fun setSelectedUserInfo( 146 userInfo: UserInfo, 147 selectionStatus: SelectionStatus = SelectionStatus.SELECTION_COMPLETE, 148 ) { 149 check(_userInfos.value.contains(userInfo)) { 150 "Cannot select the following user, it is not in the list of user infos: $userInfo!" 151 } 152 153 selectedUser.value = SelectedUserModel(userInfo, selectionStatus) 154 yield() 155 } 156 157 /** Resets the current user to the default of [DEFAULT_SELECTED_USER_INFO]. */ asDefaultUsernull158 suspend fun asDefaultUser(): UserInfo { 159 setUserInfos(listOf(DEFAULT_SELECTED_USER_INFO)) 160 setSelectedUserInfo(DEFAULT_SELECTED_USER_INFO) 161 return DEFAULT_SELECTED_USER_INFO 162 } 163 164 /** Makes the current user [MAIN_USER]. */ asMainUsernull165 suspend fun asMainUser(): UserInfo { 166 setUserInfos(listOf(MAIN_USER)) 167 setSelectedUserInfo(MAIN_USER) 168 return MAIN_USER 169 } 170 setSettingsnull171 suspend fun setSettings(settings: UserSwitcherSettingsModel) { 172 _userSwitcherSettings.value = settings 173 yield() 174 } 175 setGuestUserAutoCreatednull176 fun setGuestUserAutoCreated(value: Boolean) { 177 _isGuestUserAutoCreated = value 178 } 179 } 180 181 @Module 182 interface FakeUserRepositoryModule { bindFakenull183 @Binds fun bindFake(fake: FakeUserRepository): UserRepository 184 } 185