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