1 /* 2 * Copyright (C) 2018 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 package com.android.settingslib.users; 18 19 import android.app.ActivityManager; 20 import android.content.BroadcastReceiver; 21 import android.content.Context; 22 import android.content.Intent; 23 import android.content.IntentFilter; 24 import android.content.pm.UserInfo; 25 import android.graphics.Bitmap; 26 import android.graphics.drawable.BitmapDrawable; 27 import android.graphics.drawable.Drawable; 28 import android.os.SystemProperties; 29 import android.os.UserHandle; 30 import android.os.UserManager; 31 import android.util.Log; 32 33 import com.android.internal.util.UserIcons; 34 35 import java.util.Iterator; 36 import java.util.List; 37 38 /** 39 * Helper class for managing users, providing methods for removing, adding and switching users. 40 * 41 * @deprecated - Do not use 42 */ 43 @Deprecated 44 public final class UserManagerHelper { 45 private static final String TAG = "UserManagerHelper"; 46 private static final String HEADLESS_SYSTEM_USER = "android.car.systemuser.headless"; 47 private final Context mContext; 48 private final UserManager mUserManager; 49 private final ActivityManager mActivityManager; 50 private OnUsersUpdateListener mUpdateListener; 51 private final BroadcastReceiver mUserChangeReceiver = new BroadcastReceiver() { 52 @Override 53 public void onReceive(Context context, Intent intent) { 54 mUpdateListener.onUsersUpdate(); 55 } 56 }; 57 UserManagerHelper(Context context)58 public UserManagerHelper(Context context) { 59 mContext = context; 60 mUserManager = (UserManager) mContext.getSystemService(Context.USER_SERVICE); 61 mActivityManager = (ActivityManager) mContext.getSystemService(Context.ACTIVITY_SERVICE); 62 } 63 64 /** 65 * Registers a listener for updates to all users - removing, adding users or changing user info. 66 * 67 * @param listener Instance of {@link OnUsersUpdateListener}. 68 */ registerOnUsersUpdateListener(OnUsersUpdateListener listener)69 public void registerOnUsersUpdateListener(OnUsersUpdateListener listener) { 70 mUpdateListener = listener; 71 registerReceiver(); 72 } 73 74 /** 75 * Unregisters listener by unregistering {@code BroadcastReceiver}. 76 */ unregisterOnUsersUpdateListener()77 public void unregisterOnUsersUpdateListener() { 78 unregisterReceiver(); 79 } 80 81 /** 82 * Returns {@code true} if the system is in the headless user 0 model. 83 * 84 * @return {@boolean true} if headless system user. 85 */ isHeadlessSystemUser()86 public boolean isHeadlessSystemUser() { 87 return SystemProperties.getBoolean(HEADLESS_SYSTEM_USER, false); 88 } 89 90 /** 91 * Gets UserInfo for the foreground user. 92 * 93 * Concept of foreground user is relevant for the multi-user deployment. Foreground user 94 * corresponds to the currently "logged in" user. 95 * 96 * @return {@link UserInfo} for the foreground user. 97 */ getForegroundUserInfo()98 public UserInfo getForegroundUserInfo() { 99 return mUserManager.getUserInfo(getForegroundUserId()); 100 } 101 102 /** 103 * @return Id of the foreground user. 104 */ getForegroundUserId()105 public int getForegroundUserId() { 106 return mActivityManager.getCurrentUser(); 107 } 108 109 /** 110 * Gets UserInfo for the user running the caller process. 111 * 112 * Differentiation between foreground user and current process user is relevant for multi-user 113 * deployments. 114 * 115 * Some multi-user aware components (like SystemUI) might run as a singleton - one component 116 * for all users. Current process user is then always the same for that component, even when 117 * the foreground user changes. 118 * 119 * @return {@link UserInfo} for the user running the current process. 120 */ getCurrentProcessUserInfo()121 public UserInfo getCurrentProcessUserInfo() { 122 return mUserManager.getUserInfo(getCurrentProcessUserId()); 123 } 124 125 /** 126 * @return Id for the user running the current process. 127 */ getCurrentProcessUserId()128 public int getCurrentProcessUserId() { 129 return UserHandle.myUserId(); 130 } 131 132 /** 133 * Gets all the other users on the system that are not the user running the current process. 134 * 135 * @return List of {@code UserInfo} for each user that is not the user running the process. 136 */ getAllUsersExcludesCurrentProcessUser()137 public List<UserInfo> getAllUsersExcludesCurrentProcessUser() { 138 return getAllUsersExceptUser(getCurrentProcessUserId()); 139 } 140 141 /** 142 * Gets all the existing users on the system that are not the currently running as the 143 * foreground user. 144 * 145 * @return List of {@code UserInfo} for each user that is not the foreground user. 146 */ getAllUsersExcludesForegroundUser()147 public List<UserInfo> getAllUsersExcludesForegroundUser() { 148 return getAllUsersExceptUser(getForegroundUserId()); 149 } 150 151 /** 152 * Gets all the other users on the system that are not the system user. 153 * 154 * @return List of {@code UserInfo} for each user that is not the system user. 155 */ getAllUsersExcludesSystemUser()156 public List<UserInfo> getAllUsersExcludesSystemUser() { 157 return getAllUsersExceptUser(UserHandle.USER_SYSTEM); 158 } 159 160 /** 161 * Get all the users except the one with userId passed in. 162 * 163 * @param userId of the user not to be returned. 164 * @return All users other than user with userId. 165 */ getAllUsersExceptUser(int userId)166 public List<UserInfo> getAllUsersExceptUser(int userId) { 167 List<UserInfo> others = mUserManager.getUsers(/* excludeDying= */true); 168 169 for (Iterator<UserInfo> iterator = others.iterator(); iterator.hasNext(); ) { 170 UserInfo userInfo = iterator.next(); 171 if (userInfo.id == userId) { 172 // Remove user with userId from the list. 173 iterator.remove(); 174 } 175 } 176 return others; 177 } 178 179 /** 180 * Gets all the users on the system that are not currently being removed. 181 */ getAllUsers()182 public List<UserInfo> getAllUsers() { 183 if (isHeadlessSystemUser()) { 184 return getAllUsersExcludesSystemUser(); 185 } 186 return mUserManager.getUsers(/* excludeDying= */true); 187 } 188 189 // User information accessors 190 191 /** 192 * Checks whether the user is system user (admin). 193 * 194 * @param userInfo User to check against system user. 195 * @return {@code true} if system user, {@code false} otherwise. 196 */ userIsSystemUser(UserInfo userInfo)197 public boolean userIsSystemUser(UserInfo userInfo) { 198 return userInfo.id == UserHandle.USER_SYSTEM; 199 } 200 201 /** 202 * Returns whether this user can be removed from the system. 203 * 204 * @param userInfo User to be removed 205 * @return {@code true} if they can be removed, {@code false} otherwise. 206 */ userCanBeRemoved(UserInfo userInfo)207 public boolean userCanBeRemoved(UserInfo userInfo) { 208 return !userIsSystemUser(userInfo); 209 } 210 211 /** 212 * Checks whether passed in user is the foreground user. 213 * 214 * @param userInfo User to check. 215 * @return {@code true} if foreground user, {@code false} otherwise. 216 */ userIsForegroundUser(UserInfo userInfo)217 public boolean userIsForegroundUser(UserInfo userInfo) { 218 return getForegroundUserId() == userInfo.id; 219 } 220 221 /** 222 * Checks whether passed in user is the user that's running the current process. 223 * 224 * @param userInfo User to check. 225 * @return {@code true} if user running the process, {@code false} otherwise. 226 */ userIsRunningCurrentProcess(UserInfo userInfo)227 public boolean userIsRunningCurrentProcess(UserInfo userInfo) { 228 return getCurrentProcessUserId() == userInfo.id; 229 } 230 231 // Foreground user information accessors. 232 233 /** 234 * Checks if the foreground user is a guest user. 235 */ foregroundUserIsGuestUser()236 public boolean foregroundUserIsGuestUser() { 237 return getForegroundUserInfo().isGuest(); 238 } 239 240 /** 241 * Return whether the foreground user has a restriction. 242 * 243 * @param restriction Restriction to check. Should be a UserManager.* restriction. 244 * @return Whether that restriction exists for the foreground user. 245 */ foregroundUserHasUserRestriction(String restriction)246 public boolean foregroundUserHasUserRestriction(String restriction) { 247 return mUserManager.hasUserRestriction(restriction, getForegroundUserInfo().getUserHandle()); 248 } 249 250 /** 251 * Checks if the foreground user can add new users. 252 */ foregroundUserCanAddUsers()253 public boolean foregroundUserCanAddUsers() { 254 return !foregroundUserHasUserRestriction(UserManager.DISALLOW_ADD_USER); 255 } 256 257 // Current process user information accessors 258 259 /** 260 * Checks if the calling app is running in a demo user. 261 */ currentProcessRunningAsDemoUser()262 public boolean currentProcessRunningAsDemoUser() { 263 return mUserManager.isDemoUser(); 264 } 265 266 /** 267 * Checks if the calling app is running as a guest user. 268 */ currentProcessRunningAsGuestUser()269 public boolean currentProcessRunningAsGuestUser() { 270 return mUserManager.isGuestUser(); 271 } 272 273 /** 274 * Checks whether this process is running under the system user. 275 */ currentProcessRunningAsSystemUser()276 public boolean currentProcessRunningAsSystemUser() { 277 return mUserManager.isSystemUser(); 278 } 279 280 // Current process user restriction accessors 281 282 /** 283 * Return whether the user running the current process has a restriction. 284 * 285 * @param restriction Restriction to check. Should be a UserManager.* restriction. 286 * @return Whether that restriction exists for the user running the process. 287 */ currentProcessHasUserRestriction(String restriction)288 public boolean currentProcessHasUserRestriction(String restriction) { 289 return mUserManager.hasUserRestriction(restriction); 290 } 291 292 /** 293 * Checks if the user running the current process can add new users. 294 */ currentProcessCanAddUsers()295 public boolean currentProcessCanAddUsers() { 296 return !currentProcessHasUserRestriction(UserManager.DISALLOW_ADD_USER); 297 } 298 299 /** 300 * Checks if the user running the current process can remove users. 301 */ currentProcessCanRemoveUsers()302 public boolean currentProcessCanRemoveUsers() { 303 return !currentProcessHasUserRestriction(UserManager.DISALLOW_REMOVE_USER); 304 } 305 306 /** 307 * Checks if the user running the current process is allowed to switch to another user. 308 */ currentProcessCanSwitchUsers()309 public boolean currentProcessCanSwitchUsers() { 310 return !currentProcessHasUserRestriction(UserManager.DISALLOW_USER_SWITCH); 311 } 312 313 /** 314 * Checks if the current process user can modify accounts. Demo and Guest users cannot modify 315 * accounts even if the DISALLOW_MODIFY_ACCOUNTS restriction is not applied. 316 */ currentProcessCanModifyAccounts()317 public boolean currentProcessCanModifyAccounts() { 318 return !currentProcessHasUserRestriction(UserManager.DISALLOW_MODIFY_ACCOUNTS) 319 && !currentProcessRunningAsDemoUser() 320 && !currentProcessRunningAsGuestUser(); 321 } 322 323 // User actions 324 325 /** 326 * Creates a new user on the system. 327 * 328 * @param userName Name to give to the newly created user. 329 * @return Newly created user. 330 */ createNewUser(String userName)331 public UserInfo createNewUser(String userName) { 332 UserInfo user = mUserManager.createUser(userName, 0 /* flags */); 333 if (user == null) { 334 // Couldn't create user, most likely because there are too many, but we haven't 335 // been able to reload the list yet. 336 Log.w(TAG, "can't create user."); 337 return null; 338 } 339 assignDefaultIcon(user); 340 return user; 341 } 342 343 /** 344 * Tries to remove the user that's passed in. System user cannot be removed. 345 * If the user to be removed is user currently running the process, 346 * it switches to the system user first, and then removes the user. 347 * 348 * @param userInfo User to be removed 349 * @return {@code true} if user is successfully removed, {@code false} otherwise. 350 */ removeUser(UserInfo userInfo)351 public boolean removeUser(UserInfo userInfo) { 352 if (userIsSystemUser(userInfo)) { 353 Log.w(TAG, "User " + userInfo.id + " is system user, could not be removed."); 354 return false; 355 } 356 357 if (userInfo.id == getCurrentProcessUserId()) { 358 switchToUserId(UserHandle.USER_SYSTEM); 359 } 360 361 return mUserManager.removeUser(userInfo.id); 362 } 363 364 /** 365 * Switches (logs in) to another user. 366 * 367 * @param userInfo User to switch to. 368 */ switchToUser(UserInfo userInfo)369 public void switchToUser(UserInfo userInfo) { 370 if (userInfo.id == getForegroundUserId()) { 371 return; 372 } 373 374 switchToUserId(userInfo.id); 375 } 376 377 /** 378 * Creates a new guest session and switches into the guest session. 379 * 380 * @param guestName Username for the guest user. 381 */ startNewGuestSession(String guestName)382 public void startNewGuestSession(String guestName) { 383 UserInfo guest = mUserManager.createGuest(mContext, guestName); 384 if (guest == null) { 385 // Couldn't create user, most likely because there are too many, but we haven't 386 // been able to reload the list yet. 387 Log.w(TAG, "can't create user."); 388 return; 389 } 390 assignDefaultIcon(guest); 391 switchToUserId(guest.id); 392 } 393 394 /** 395 * Gets an icon for the user. 396 * 397 * @param userInfo User for which we want to get the icon. 398 * @return a Bitmap for the icon 399 */ getUserIcon(UserInfo userInfo)400 public Bitmap getUserIcon(UserInfo userInfo) { 401 Bitmap picture = mUserManager.getUserIcon(userInfo.id); 402 403 if (picture == null) { 404 return assignDefaultIcon(userInfo); 405 } 406 407 return picture; 408 } 409 410 /** 411 * Method for scaling a Bitmap icon to a desirable size. 412 * 413 * @param icon Bitmap to scale. 414 * @param desiredSize Wanted size for the icon. 415 * @return Drawable for the icon, scaled to the new size. 416 */ scaleUserIcon(Bitmap icon, int desiredSize)417 public Drawable scaleUserIcon(Bitmap icon, int desiredSize) { 418 Bitmap scaledIcon = Bitmap.createScaledBitmap( 419 icon, desiredSize, desiredSize, true /* filter */); 420 return new BitmapDrawable(mContext.getResources(), scaledIcon); 421 } 422 423 /** 424 * Sets new Username for the user. 425 * 426 * @param user User whose name should be changed. 427 * @param name New username. 428 */ setUserName(UserInfo user, String name)429 public void setUserName(UserInfo user, String name) { 430 mUserManager.setUserName(user.id, name); 431 } 432 433 /** 434 * Gets a bitmap representing the user's default avatar. 435 * 436 * @param userInfo User whose avatar should be returned. 437 * @return Default user icon 438 */ getUserDefaultIcon(UserInfo userInfo)439 public Bitmap getUserDefaultIcon(UserInfo userInfo) { 440 return UserIcons.convertToBitmap( 441 UserIcons.getDefaultUserIcon(mContext.getResources(), userInfo.id, false)); 442 } 443 444 /** 445 * Gets a bitmap representing the default icon for a Guest user. 446 * 447 * @return Degault guest icon 448 */ getGuestDefaultIcon()449 public Bitmap getGuestDefaultIcon() { 450 return UserIcons.convertToBitmap(UserIcons.getDefaultUserIcon( 451 mContext.getResources(), UserHandle.USER_NULL, false)); 452 } 453 registerReceiver()454 private void registerReceiver() { 455 IntentFilter filter = new IntentFilter(); 456 filter.addAction(Intent.ACTION_USER_REMOVED); 457 filter.addAction(Intent.ACTION_USER_ADDED); 458 filter.addAction(Intent.ACTION_USER_INFO_CHANGED); 459 filter.addAction(Intent.ACTION_USER_SWITCHED); 460 filter.addAction(Intent.ACTION_USER_STOPPED); 461 filter.addAction(Intent.ACTION_USER_UNLOCKED); 462 mContext.registerReceiverAsUser(mUserChangeReceiver, UserHandle.ALL, filter, null, null); 463 } 464 465 /** 466 * Assigns a default icon to a user according to the user's id. 467 * 468 * @param userInfo User to assign a default icon to. 469 * @return Bitmap that has been assigned to the user. 470 */ assignDefaultIcon(UserInfo userInfo)471 private Bitmap assignDefaultIcon(UserInfo userInfo) { 472 Bitmap bitmap = userInfo.isGuest() ? getGuestDefaultIcon() : getUserDefaultIcon(userInfo); 473 mUserManager.setUserIcon(userInfo.id, bitmap); 474 return bitmap; 475 } 476 switchToUserId(int id)477 private void switchToUserId(int id) { 478 try { 479 mActivityManager.switchUser(id); 480 } catch (Exception e) { 481 Log.e(TAG, "Couldn't switch user.", e); 482 } 483 } 484 unregisterReceiver()485 private void unregisterReceiver() { 486 mContext.unregisterReceiver(mUserChangeReceiver); 487 } 488 489 /** 490 * Interface for listeners that want to register for receiving updates to changes to the users 491 * on the system including removing and adding users, and changing user info. 492 */ 493 public interface OnUsersUpdateListener { 494 /** 495 * Method that will get called when users list has been changed. 496 */ onUsersUpdate()497 void onUsersUpdate(); 498 } 499 } 500