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.legacyhelper.data
19 
20 import android.content.Context
21 import android.content.pm.UserInfo
22 import android.graphics.Bitmap
23 import android.os.UserManager
24 import com.android.settingslib.RestrictedLockUtils.EnforcedAdmin
25 import com.android.systemui.res.R
26 import com.android.systemui.user.data.source.UserRecord
27 import com.android.systemui.user.shared.model.UserActionModel
28 import com.android.systemui.utils.UserRestrictionChecker
29 
30 /**
31  * Defines utility functions for helping with legacy data code for users.
32  *
33  * We need these to avoid code duplication between logic inside the UserSwitcherController and in
34  * modern architecture classes such as repositories, interactors, and view-models. If we ever
35  * simplify UserSwitcherController (or delete it), the code here could be moved into its call-sites.
36  */
37 object LegacyUserDataHelper {
38 
39     @JvmStatic
createRecordnull40     fun createRecord(
41         context: Context,
42         manager: UserManager,
43         picture: Bitmap?,
44         userInfo: UserInfo,
45         isCurrent: Boolean,
46         canSwitchUsers: Boolean,
47     ): UserRecord {
48         val isGuest = userInfo.isGuest
49         return UserRecord(
50             info = userInfo,
51             picture =
52                 getPicture(
53                     manager = manager,
54                     context = context,
55                     userInfo = userInfo,
56                     picture = picture,
57                 ),
58             isGuest = isGuest,
59             isCurrent = isCurrent,
60             isSwitchToEnabled = canSwitchUsers || (isCurrent && !isGuest),
61         )
62     }
63 
64     @JvmStatic
createRecordnull65     fun createRecord(
66         context: Context,
67         selectedUserId: Int,
68         actionType: UserActionModel,
69         isRestricted: Boolean,
70         isSwitchToEnabled: Boolean,
71         userRestrictionChecker: UserRestrictionChecker,
72     ): UserRecord {
73         return UserRecord(
74             isGuest = actionType == UserActionModel.ENTER_GUEST_MODE,
75             isAddUser = actionType == UserActionModel.ADD_USER,
76             isAddSupervisedUser = actionType == UserActionModel.ADD_SUPERVISED_USER,
77             isRestricted = isRestricted,
78             isSwitchToEnabled = isSwitchToEnabled,
79             enforcedAdmin =
80                 getEnforcedAdmin(
81                     context = context,
82                     selectedUserId = selectedUserId,
83                     userRestrictionChecker = userRestrictionChecker,
84                 ),
85             isManageUsers = actionType == UserActionModel.NAVIGATE_TO_USER_MANAGEMENT,
86         )
87     }
88 
toUserActionModelnull89     fun toUserActionModel(record: UserRecord): UserActionModel {
90         check(!isUser(record))
91 
92         return when {
93             record.isAddUser -> UserActionModel.ADD_USER
94             record.isAddSupervisedUser -> UserActionModel.ADD_SUPERVISED_USER
95             record.isGuest -> UserActionModel.ENTER_GUEST_MODE
96             record.isManageUsers -> UserActionModel.NAVIGATE_TO_USER_MANAGEMENT
97             else -> error("Not a known action: $record")
98         }
99     }
100 
isUsernull101     fun isUser(record: UserRecord): Boolean {
102         return record.info != null
103     }
104 
getEnforcedAdminnull105     private fun getEnforcedAdmin(
106         context: Context,
107         selectedUserId: Int,
108         userRestrictionChecker: UserRestrictionChecker
109     ): EnforcedAdmin? {
110         val admin =
111             userRestrictionChecker.checkIfRestrictionEnforced(
112                 context,
113                 UserManager.DISALLOW_ADD_USER,
114                 selectedUserId,
115             )
116                 ?: return null
117 
118         return if (
119             !userRestrictionChecker.hasBaseUserRestriction(
120                 context,
121                 UserManager.DISALLOW_ADD_USER,
122                 selectedUserId,
123             )
124         ) {
125             admin
126         } else {
127             null
128         }
129     }
130 
getPicturenull131     private fun getPicture(
132         context: Context,
133         manager: UserManager,
134         userInfo: UserInfo,
135         picture: Bitmap?,
136     ): Bitmap? {
137         if (userInfo.isGuest) {
138             return null
139         }
140 
141         if (picture != null) {
142             return picture
143         }
144 
145         val unscaledOrNull = manager.getUserIcon(userInfo.id) ?: return null
146 
147         val avatarSize = context.resources.getDimensionPixelSize(R.dimen.max_avatar_size)
148         return Bitmap.createScaledBitmap(
149             unscaledOrNull,
150             avatarSize,
151             avatarSize,
152             /* filter= */ true,
153         )
154     }
155 }
156