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.settingslib.RestrictedLockUtilsInternal 26 import com.android.systemui.R 27 import com.android.systemui.user.data.source.UserRecord 28 import com.android.systemui.user.shared.model.UserActionModel 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 40 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 65 fun createRecord( 66 context: Context, 67 selectedUserId: Int, 68 actionType: UserActionModel, 69 isRestricted: Boolean, 70 isSwitchToEnabled: Boolean, 71 ): UserRecord { 72 return UserRecord( 73 isGuest = actionType == UserActionModel.ENTER_GUEST_MODE, 74 isAddUser = actionType == UserActionModel.ADD_USER, 75 isAddSupervisedUser = actionType == UserActionModel.ADD_SUPERVISED_USER, 76 isRestricted = isRestricted, 77 isSwitchToEnabled = isSwitchToEnabled, 78 enforcedAdmin = 79 getEnforcedAdmin( 80 context = context, 81 selectedUserId = selectedUserId, 82 ), 83 isManageUsers = actionType == UserActionModel.NAVIGATE_TO_USER_MANAGEMENT, 84 ) 85 } 86 87 fun toUserActionModel(record: UserRecord): UserActionModel { 88 check(!isUser(record)) 89 90 return when { 91 record.isAddUser -> UserActionModel.ADD_USER 92 record.isAddSupervisedUser -> UserActionModel.ADD_SUPERVISED_USER 93 record.isGuest -> UserActionModel.ENTER_GUEST_MODE 94 record.isManageUsers -> UserActionModel.NAVIGATE_TO_USER_MANAGEMENT 95 else -> error("Not a known action: $record") 96 } 97 } 98 99 fun isUser(record: UserRecord): Boolean { 100 return record.info != null 101 } 102 103 private fun getEnforcedAdmin( 104 context: Context, 105 selectedUserId: Int, 106 ): EnforcedAdmin? { 107 val admin = 108 RestrictedLockUtilsInternal.checkIfRestrictionEnforced( 109 context, 110 UserManager.DISALLOW_ADD_USER, 111 selectedUserId, 112 ) 113 ?: return null 114 115 return if ( 116 !RestrictedLockUtilsInternal.hasBaseUserRestriction( 117 context, 118 UserManager.DISALLOW_ADD_USER, 119 selectedUserId, 120 ) 121 ) { 122 admin 123 } else { 124 null 125 } 126 } 127 128 private fun getPicture( 129 context: Context, 130 manager: UserManager, 131 userInfo: UserInfo, 132 picture: Bitmap?, 133 ): Bitmap? { 134 if (userInfo.isGuest) { 135 return null 136 } 137 138 if (picture != null) { 139 return picture 140 } 141 142 val unscaledOrNull = manager.getUserIcon(userInfo.id) ?: return null 143 144 val avatarSize = context.resources.getDimensionPixelSize(R.dimen.max_avatar_size) 145 return Bitmap.createScaledBitmap( 146 unscaledOrNull, 147 avatarSize, 148 avatarSize, 149 /* filter= */ true, 150 ) 151 } 152 } 153