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 android.car.userlib; 18 19 import android.Manifest; 20 import android.annotation.Nullable; 21 import android.annotation.RequiresPermission; 22 import android.annotation.SystemApi; 23 import android.app.ActivityManager; 24 import android.content.BroadcastReceiver; 25 import android.content.Context; 26 import android.content.Intent; 27 import android.content.IntentFilter; 28 import android.content.pm.UserInfo; 29 import android.graphics.Bitmap; 30 import android.graphics.drawable.BitmapDrawable; 31 import android.graphics.drawable.Drawable; 32 import android.os.Bundle; 33 import android.os.UserHandle; 34 import android.os.UserManager; 35 import android.provider.Settings; 36 import android.sysprop.CarProperties; 37 import android.telephony.TelephonyManager; 38 import android.text.TextUtils; 39 import android.util.Log; 40 41 import com.android.internal.annotations.VisibleForTesting; 42 import com.android.internal.os.RoSystemProperties; 43 import com.android.internal.util.UserIcons; 44 45 import com.google.android.collect.Sets; 46 47 import java.util.ArrayList; 48 import java.util.Collections; 49 import java.util.Iterator; 50 import java.util.List; 51 import java.util.Set; 52 53 /** 54 * Helper class for {@link UserManager}, this is meant to be used by builds that support 55 * Multi-user model with headless user 0. User 0 is not associated with a real person, and 56 * can not be brought to foreground. 57 * 58 * <p>This class provides method for user management, including creating, removing, adding 59 * and switching users. Methods related to get users will exclude system user by default. 60 * 61 * @hide 62 */ 63 public final class CarUserManagerHelper { 64 private static final String TAG = "CarUserManagerHelper"; 65 66 private static final int BOOT_USER_NOT_FOUND = -1; 67 68 /** 69 * Default set of restrictions for Non-Admin users. 70 */ 71 private static final Set<String> DEFAULT_NON_ADMIN_RESTRICTIONS = Sets.newArraySet( 72 UserManager.DISALLOW_FACTORY_RESET 73 ); 74 75 /** 76 * Additional optional set of restrictions for Non-Admin users. These are the restrictions 77 * configurable via Settings. 78 */ 79 public static final Set<String> OPTIONAL_NON_ADMIN_RESTRICTIONS = Sets.newArraySet( 80 UserManager.DISALLOW_ADD_USER, 81 UserManager.DISALLOW_OUTGOING_CALLS, 82 UserManager.DISALLOW_SMS, 83 UserManager.DISALLOW_INSTALL_APPS, 84 UserManager.DISALLOW_UNINSTALL_APPS 85 ); 86 87 /** 88 * Default set of restrictions for Guest users. 89 */ 90 private static final Set<String> DEFAULT_GUEST_RESTRICTIONS = Sets.newArraySet( 91 UserManager.DISALLOW_FACTORY_RESET, 92 UserManager.DISALLOW_REMOVE_USER, 93 UserManager.DISALLOW_MODIFY_ACCOUNTS, 94 UserManager.DISALLOW_INSTALL_APPS, 95 UserManager.DISALLOW_INSTALL_UNKNOWN_SOURCES, 96 UserManager.DISALLOW_UNINSTALL_APPS 97 ); 98 99 private final Context mContext; 100 private final UserManager mUserManager; 101 private final ActivityManager mActivityManager; 102 private final TestableFrameworkWrapper mTestableFrameworkWrapper; 103 private String mDefaultAdminName; 104 private Bitmap mDefaultGuestUserIcon; 105 private ArrayList<OnUsersUpdateListener> mUpdateListeners; 106 private final BroadcastReceiver mUserChangeReceiver = new BroadcastReceiver() { 107 @Override 108 public void onReceive(Context context, Intent intent) { 109 ArrayList<OnUsersUpdateListener> copyOfUpdateListeners; 110 synchronized (mUpdateListeners) { 111 copyOfUpdateListeners = new ArrayList(mUpdateListeners); 112 } 113 114 for (OnUsersUpdateListener listener : copyOfUpdateListeners) { 115 listener.onUsersUpdate(); 116 } 117 } 118 }; 119 120 /** 121 * Initializes with a default name for admin users. 122 * 123 * @param context Application Context 124 */ CarUserManagerHelper(Context context)125 public CarUserManagerHelper(Context context) { 126 this(context, new TestableFrameworkWrapper()); 127 } 128 129 @VisibleForTesting CarUserManagerHelper(Context context, TestableFrameworkWrapper testableFrameworkWrapper)130 CarUserManagerHelper(Context context, TestableFrameworkWrapper testableFrameworkWrapper) { 131 mUpdateListeners = new ArrayList<>(); 132 mContext = context.getApplicationContext(); 133 mUserManager = (UserManager) mContext.getSystemService(Context.USER_SERVICE); 134 mActivityManager = (ActivityManager) mContext.getSystemService(Context.ACTIVITY_SERVICE); 135 mTestableFrameworkWrapper = testableFrameworkWrapper; 136 } 137 138 /** 139 * Registers a listener for updates to all users - removing, adding users or changing user info. 140 * 141 * @param listener Instance of {@link OnUsersUpdateListener}. 142 */ registerOnUsersUpdateListener(OnUsersUpdateListener listener)143 public void registerOnUsersUpdateListener(OnUsersUpdateListener listener) { 144 if (listener == null) { 145 return; 146 } 147 148 synchronized (mUpdateListeners) { 149 if (mUpdateListeners.isEmpty()) { 150 // First listener being added, register receiver. 151 registerReceiver(); 152 } 153 154 if (!mUpdateListeners.contains(listener)) { 155 mUpdateListeners.add(listener); 156 } 157 } 158 } 159 160 /** 161 * Unregisters on user update listener. 162 * Unregisters {@code BroadcastReceiver} if no listeners remain. 163 * 164 * @param listener Instance of {@link OnUsersUpdateListener} to unregister. 165 */ unregisterOnUsersUpdateListener(OnUsersUpdateListener listener)166 public void unregisterOnUsersUpdateListener(OnUsersUpdateListener listener) { 167 synchronized (mUpdateListeners) { 168 if (mUpdateListeners.contains(listener)) { 169 mUpdateListeners.remove(listener); 170 171 if (mUpdateListeners.isEmpty()) { 172 // No more listeners, unregister broadcast receiver. 173 unregisterReceiver(); 174 } 175 } 176 } 177 } 178 179 /** 180 * Set last active user. 181 * 182 * @param userId last active user id. 183 */ setLastActiveUser(int userId)184 public void setLastActiveUser(int userId) { 185 Settings.Global.putInt( 186 mContext.getContentResolver(), Settings.Global.LAST_ACTIVE_USER_ID, userId); 187 } 188 189 /** 190 * Set last active user. 191 * 192 * @param userId last active user id. 193 * @param skipGlobalSetting whether to skip set the global settings value. 194 * @deprecated Use {@link #setLastActiveUser(int)} instead. 195 */ 196 @Deprecated setLastActiveUser(int userId, boolean skipGlobalSetting)197 public void setLastActiveUser(int userId, boolean skipGlobalSetting) { 198 if (!skipGlobalSetting) { 199 Settings.Global.putInt( 200 mContext.getContentResolver(), Settings.Global.LAST_ACTIVE_USER_ID, userId); 201 } 202 } 203 204 /** 205 * Get user id for the last active user. 206 * 207 * @return user id of the last active user. 208 */ getLastActiveUser()209 public int getLastActiveUser() { 210 return Settings.Global.getInt( 211 mContext.getContentResolver(), Settings.Global.LAST_ACTIVE_USER_ID, 212 /* default user id= */ UserHandle.USER_SYSTEM); 213 } 214 215 /** 216 * Gets the user id for the initial user to boot into. This is only applicable for headless 217 * system user model. This method checks for a system property and will only work for system 218 * apps. 219 * 220 * This method checks for the initial user via three mechanisms in this order: 221 * <ol> 222 * <li>Check for a boot user override via {@link CarProperties#boot_user_override_id()}</li> 223 * <li>Check for the last active user in the system</li> 224 * <li>Fallback to the smallest user id that is not {@link UserHandle.USER_SYSTEM}</li> 225 * </ol> 226 * 227 * If any step fails to retrieve the stored id or the retrieved id does not exist on device, 228 * then it will move onto the next step. 229 * 230 * @return user id of the initial user to boot into on the device. 231 */ 232 @SystemApi getInitialUser()233 public int getInitialUser() { 234 List<Integer> allUsers = userInfoListToUserIdList(getAllPersistentUsers()); 235 236 int bootUserOverride = mTestableFrameworkWrapper.getBootUserOverrideId(BOOT_USER_NOT_FOUND); 237 238 // If an override user is present and a real user, return it 239 if (bootUserOverride != BOOT_USER_NOT_FOUND 240 && allUsers.contains(bootUserOverride)) { 241 if (Log.isLoggable(TAG, Log.DEBUG)) { 242 Log.d(TAG, "Boot user id override found for initial user, user id: " 243 + bootUserOverride); 244 } 245 return bootUserOverride; 246 } 247 248 // If the last active user is not the SYSTEM user and is a real user, return it 249 int lastActiveUser = getLastActiveUser(); 250 if (lastActiveUser != UserHandle.USER_SYSTEM 251 && allUsers.contains(lastActiveUser)) { 252 if (Log.isLoggable(TAG, Log.DEBUG)) { 253 Log.d(TAG, "Last active user loaded for initial user, user id: " 254 + lastActiveUser); 255 } 256 return lastActiveUser; 257 } 258 259 // If all else fails, return the smallest user id 260 int returnId = Collections.min(allUsers); 261 if (Log.isLoggable(TAG, Log.DEBUG)) { 262 Log.d(TAG, "Saved ids were invalid. Returning smallest user id, user id: " 263 + returnId); 264 } 265 return returnId; 266 } 267 userInfoListToUserIdList(List<UserInfo> allUsers)268 private List<Integer> userInfoListToUserIdList(List<UserInfo> allUsers) { 269 ArrayList<Integer> list = new ArrayList<>(allUsers.size()); 270 for (UserInfo userInfo : allUsers) { 271 list.add(userInfo.id); 272 } 273 return list; 274 } 275 276 /** 277 * Sets default guest restrictions that will be applied every time a Guest user is created. 278 * 279 * <p> Restrictions are written to disk and persistent across boots. 280 */ initDefaultGuestRestrictions()281 public void initDefaultGuestRestrictions() { 282 Bundle defaultGuestRestrictions = new Bundle(); 283 for (String restriction : DEFAULT_GUEST_RESTRICTIONS) { 284 defaultGuestRestrictions.putBoolean(restriction, true); 285 } 286 mUserManager.setDefaultGuestRestrictions(defaultGuestRestrictions); 287 } 288 289 /** 290 * Returns {@code true} if the system is in the headless user 0 model. 291 * 292 * @return {@boolean true} if headless system user. 293 */ isHeadlessSystemUser()294 public boolean isHeadlessSystemUser() { 295 return RoSystemProperties.MULTIUSER_HEADLESS_SYSTEM_USER; 296 } 297 298 /** 299 * Gets UserInfo for the system user. 300 * 301 * @return {@link UserInfo} for the system user. 302 */ getSystemUserInfo()303 public UserInfo getSystemUserInfo() { 304 return mUserManager.getUserInfo(UserHandle.USER_SYSTEM); 305 } 306 307 /** 308 * Gets UserInfo for the current foreground user. 309 * 310 * Concept of foreground user is relevant for the multi-user deployment. Foreground user 311 * corresponds to the currently "logged in" user. 312 * 313 * @return {@link UserInfo} for the foreground user. 314 */ getCurrentForegroundUserInfo()315 public UserInfo getCurrentForegroundUserInfo() { 316 return mUserManager.getUserInfo(getCurrentForegroundUserId()); 317 } 318 319 /** 320 * @return Id of the current foreground user. 321 */ getCurrentForegroundUserId()322 public int getCurrentForegroundUserId() { 323 return mActivityManager.getCurrentUser(); 324 } 325 326 /** 327 * Gets UserInfo for the user running the caller process. 328 * 329 * <p>Differentiation between foreground user and current process user is relevant for 330 * multi-user deployments. 331 * 332 * <p>Some multi-user aware components (like SystemUI) needs to run a singleton component 333 * in system user. Current process user is always the same for that component, even when 334 * the foreground user changes. 335 * 336 * @return {@link UserInfo} for the user running the current process. 337 */ getCurrentProcessUserInfo()338 public UserInfo getCurrentProcessUserInfo() { 339 return mUserManager.getUserInfo(getCurrentProcessUserId()); 340 } 341 342 /** 343 * @return Id for the user running the current process. 344 */ getCurrentProcessUserId()345 public int getCurrentProcessUserId() { 346 return UserHandle.myUserId(); 347 } 348 349 /** 350 * Gets all the existing users on the system that are not currently running as 351 * the foreground user. 352 * These are all the users that can be switched to from the foreground user. 353 * 354 * @return List of {@code UserInfo} for each user that is not the foreground user. 355 */ getAllSwitchableUsers()356 public List<UserInfo> getAllSwitchableUsers() { 357 if (isHeadlessSystemUser()) { 358 return getAllUsersExceptSystemUserAndSpecifiedUser(getCurrentForegroundUserId()); 359 } else { 360 return getAllUsersExceptSpecifiedUser(getCurrentForegroundUserId()); 361 } 362 } 363 364 /** 365 * Gets all the users that can be brought to the foreground on the system. 366 * 367 * @return List of {@code UserInfo} for users that associated with a real person. 368 */ getAllUsers()369 public List<UserInfo> getAllUsers() { 370 if (isHeadlessSystemUser()) { 371 return getAllUsersExceptSystemUserAndSpecifiedUser(UserHandle.USER_SYSTEM); 372 } else { 373 return mUserManager.getUsers(/* excludeDying= */ true); 374 } 375 } 376 377 /** 378 * Gets all the users that are non-ephemeral and can be brought to the foreground on the system. 379 * 380 * @return List of {@code UserInfo} for non-ephemeral users that associated with a real person. 381 */ getAllPersistentUsers()382 public List<UserInfo> getAllPersistentUsers() { 383 List<UserInfo> users = getAllUsers(); 384 for (Iterator<UserInfo> iterator = users.iterator(); iterator.hasNext(); ) { 385 UserInfo userInfo = iterator.next(); 386 if (userInfo.isEphemeral()) { 387 // Remove user that is ephemeral. 388 iterator.remove(); 389 } 390 } 391 return users; 392 } 393 394 /** 395 * Gets all the users that can be brought to the foreground on the system that have admin roles. 396 * 397 * @return List of {@code UserInfo} for admin users that associated with a real person. 398 */ getAllAdminUsers()399 public List<UserInfo> getAllAdminUsers() { 400 List<UserInfo> users = getAllUsers(); 401 402 for (Iterator<UserInfo> iterator = users.iterator(); iterator.hasNext(); ) { 403 UserInfo userInfo = iterator.next(); 404 if (!userInfo.isAdmin()) { 405 // Remove user that is not admin. 406 iterator.remove(); 407 } 408 } 409 return users; 410 } 411 412 /** 413 * Gets all users that are not guests. 414 * 415 * @return List of {@code UserInfo} for all users who are not guest users. 416 */ getAllUsersExceptGuests()417 public List<UserInfo> getAllUsersExceptGuests() { 418 List<UserInfo> users = getAllUsers(); 419 420 for (Iterator<UserInfo> iterator = users.iterator(); iterator.hasNext(); ) { 421 UserInfo userInfo = iterator.next(); 422 if (userInfo.isGuest()) { 423 // Remove guests. 424 iterator.remove(); 425 } 426 } 427 return users; 428 } 429 430 /** 431 * Get all the users except the one with userId passed in. 432 * 433 * @param userId of the user not to be returned. 434 * @return All users other than user with userId. 435 */ getAllUsersExceptSpecifiedUser(int userId)436 private List<UserInfo> getAllUsersExceptSpecifiedUser(int userId) { 437 List<UserInfo> users = mUserManager.getUsers(/* excludeDying= */true); 438 439 for (Iterator<UserInfo> iterator = users.iterator(); iterator.hasNext(); ) { 440 UserInfo userInfo = iterator.next(); 441 if (userInfo.id == userId) { 442 // Remove user with userId from the list. 443 iterator.remove(); 444 } 445 } 446 return users; 447 } 448 449 /** 450 * Get all the users except system user and the one with userId passed in. 451 * 452 * @param userId of the user not to be returned. 453 * @return All users other than system user and user with userId. 454 */ getAllUsersExceptSystemUserAndSpecifiedUser(int userId)455 private List<UserInfo> getAllUsersExceptSystemUserAndSpecifiedUser(int userId) { 456 List<UserInfo> users = mUserManager.getUsers(/* excludeDying= */true); 457 458 for (Iterator<UserInfo> iterator = users.iterator(); iterator.hasNext(); ) { 459 UserInfo userInfo = iterator.next(); 460 if (userInfo.id == userId || userInfo.id == UserHandle.USER_SYSTEM) { 461 // Remove user with userId from the list. 462 iterator.remove(); 463 } 464 } 465 return users; 466 } 467 468 /** 469 * Maximum number of users allowed on the device. This includes real users, managed profiles 470 * and restricted users, but excludes guests. 471 * 472 * <p> It excludes system user in headless system user model. 473 * 474 * @return Maximum number of users that can be present on the device. 475 */ getMaxSupportedUsers()476 public int getMaxSupportedUsers() { 477 if (isHeadlessSystemUser()) { 478 return mTestableFrameworkWrapper.userManagerGetMaxSupportedUsers() - 1; 479 } 480 return mTestableFrameworkWrapper.userManagerGetMaxSupportedUsers(); 481 } 482 483 /** 484 * Get the maximum number of real (non-guest, non-managed profile) users that can be created on 485 * the device. This is a dynamic value and it decreases with the increase of the number of 486 * managed profiles on the device. 487 * 488 * <p> It excludes system user in headless system user model. 489 * 490 * @return Maximum number of real users that can be created. 491 */ getMaxSupportedRealUsers()492 public int getMaxSupportedRealUsers() { 493 return getMaxSupportedUsers() - getManagedProfilesCount(); 494 } 495 496 /** 497 * Returns true if the maximum number of users on the device has been reached, false otherwise. 498 */ isUserLimitReached()499 public boolean isUserLimitReached() { 500 int countNonGuestUsers = getAllUsersExceptGuests().size(); 501 int maxSupportedUsers = getMaxSupportedUsers(); 502 503 if (countNonGuestUsers > maxSupportedUsers) { 504 Log.e(TAG, "There are more users on the device than allowed."); 505 return true; 506 } 507 508 return getAllUsersExceptGuests().size() == maxSupportedUsers; 509 } 510 getManagedProfilesCount()511 private int getManagedProfilesCount() { 512 List<UserInfo> users = getAllUsers(); 513 514 // Count all users that are managed profiles of another user. 515 int managedProfilesCount = 0; 516 for (UserInfo user : users) { 517 if (user.isManagedProfile()) { 518 managedProfilesCount++; 519 } 520 } 521 return managedProfilesCount; 522 } 523 524 // User information accessors 525 526 /** 527 * Checks whether the user is system user. 528 * 529 * @param userInfo User to check against system user. 530 * @return {@code true} if system user, {@code false} otherwise. 531 */ isSystemUser(UserInfo userInfo)532 public boolean isSystemUser(UserInfo userInfo) { 533 return userInfo.id == UserHandle.USER_SYSTEM; 534 } 535 536 /** 537 * Checks whether the user is last active user. 538 * 539 * @param userInfo User to check against last active user. 540 * @return {@code true} if is last active user, {@code false} otherwise. 541 */ isLastActiveUser(UserInfo userInfo)542 public boolean isLastActiveUser(UserInfo userInfo) { 543 return userInfo.id == getLastActiveUser(); 544 } 545 546 /** 547 * Checks whether passed in user is the foreground user. 548 * 549 * @param userInfo User to check. 550 * @return {@code true} if foreground user, {@code false} otherwise. 551 */ isForegroundUser(UserInfo userInfo)552 public boolean isForegroundUser(UserInfo userInfo) { 553 return getCurrentForegroundUserId() == userInfo.id; 554 } 555 556 /** 557 * Checks whether passed in user is the user that's running the current process. 558 * 559 * @param userInfo User to check. 560 * @return {@code true} if user running the process, {@code false} otherwise. 561 */ isCurrentProcessUser(UserInfo userInfo)562 public boolean isCurrentProcessUser(UserInfo userInfo) { 563 return getCurrentProcessUserId() == userInfo.id; 564 } 565 566 // Foreground user information accessors. 567 568 /** 569 * Checks if the foreground user is a guest user. 570 */ isForegroundUserGuest()571 public boolean isForegroundUserGuest() { 572 return getCurrentForegroundUserInfo().isGuest(); 573 } 574 575 /** 576 * Checks if the foreground user is a demo user. 577 */ isForegroundUserDemo()578 public boolean isForegroundUserDemo() { 579 return getCurrentForegroundUserInfo().isDemo(); 580 } 581 582 /** 583 * Checks if the foreground user is ephemeral. 584 */ isForegroundUserEphemeral()585 public boolean isForegroundUserEphemeral() { 586 return getCurrentForegroundUserInfo().isEphemeral(); 587 } 588 589 /** 590 * Checks if the given user is non-ephemeral. 591 * 592 * @param userId User to check 593 * @return {@code true} if given user is persistent user. 594 */ isPersistentUser(int userId)595 public boolean isPersistentUser(int userId) { 596 UserInfo user = mUserManager.getUserInfo(userId); 597 return !user.isEphemeral(); 598 } 599 600 /** 601 * Returns whether this user can be removed from the system. 602 * 603 * @param userInfo User to be removed 604 * @return {@code true} if they can be removed, {@code false} otherwise. 605 */ canUserBeRemoved(UserInfo userInfo)606 public boolean canUserBeRemoved(UserInfo userInfo) { 607 return !isSystemUser(userInfo); 608 } 609 610 /** 611 * Returns whether a user has a restriction. 612 * 613 * @param restriction Restriction to check. Should be a UserManager.* restriction. 614 * @param userInfo the user whose restriction is to be checked 615 */ hasUserRestriction(String restriction, UserInfo userInfo)616 public boolean hasUserRestriction(String restriction, UserInfo userInfo) { 617 return mUserManager.hasUserRestriction(restriction, userInfo.getUserHandle()); 618 } 619 620 /** 621 * Return whether the foreground user has a restriction. 622 * 623 * @param restriction Restriction to check. Should be a UserManager.* restriction. 624 * @return Whether that restriction exists for the foreground user. 625 */ foregroundUserHasUserRestriction(String restriction)626 public boolean foregroundUserHasUserRestriction(String restriction) { 627 return hasUserRestriction(restriction, getCurrentForegroundUserInfo()); 628 } 629 630 /** 631 * Checks if the foreground user can add new users. 632 */ canForegroundUserAddUsers()633 public boolean canForegroundUserAddUsers() { 634 return !foregroundUserHasUserRestriction(UserManager.DISALLOW_ADD_USER); 635 } 636 637 /** 638 * Checks if the current process user can modify accounts. Demo and Guest users cannot modify 639 * accounts even if the DISALLOW_MODIFY_ACCOUNTS restriction is not applied. 640 */ canForegroundUserModifyAccounts()641 public boolean canForegroundUserModifyAccounts() { 642 return !foregroundUserHasUserRestriction(UserManager.DISALLOW_MODIFY_ACCOUNTS) 643 && !isForegroundUserDemo() 644 && !isForegroundUserGuest(); 645 } 646 647 /** 648 * Returns whether the foreground user can switch to other users. 649 * 650 * <p>For instance switching users is not allowed if the current user is in a phone call, 651 * or {@link #{UserManager.DISALLOW_USER_SWITCH} is set. 652 */ canForegroundUserSwitchUsers()653 public boolean canForegroundUserSwitchUsers() { 654 boolean inIdleCallState = TelephonyManager.getDefault().getCallState() 655 == TelephonyManager.CALL_STATE_IDLE; 656 boolean disallowUserSwitching = 657 foregroundUserHasUserRestriction(UserManager.DISALLOW_USER_SWITCH); 658 return (inIdleCallState && !disallowUserSwitching); 659 } 660 661 // Current process user information accessors 662 663 /** 664 * Checks whether this process is running under the system user. 665 */ isCurrentProcessSystemUser()666 public boolean isCurrentProcessSystemUser() { 667 return mUserManager.isSystemUser(); 668 } 669 670 /** 671 * Checks if the calling app is running in a demo user. 672 */ isCurrentProcessDemoUser()673 public boolean isCurrentProcessDemoUser() { 674 return mUserManager.isDemoUser(); 675 } 676 677 /** 678 * Checks if the calling app is running as an admin user. 679 */ isCurrentProcessAdminUser()680 public boolean isCurrentProcessAdminUser() { 681 return mUserManager.isAdminUser(); 682 } 683 684 /** 685 * Checks if the calling app is running as a guest user. 686 */ isCurrentProcessGuestUser()687 public boolean isCurrentProcessGuestUser() { 688 return mUserManager.isGuestUser(); 689 } 690 691 /** 692 * Check is the calling app is running as a restricted profile user (ie. a LinkedUser). 693 * Restricted profiles are only available when {@link #isHeadlessSystemUser()} is false. 694 */ isCurrentProcessRestrictedProfileUser()695 public boolean isCurrentProcessRestrictedProfileUser() { 696 return mUserManager.isRestrictedProfile(); 697 } 698 699 // Current process user restriction accessors 700 701 /** 702 * Return whether the user running the current process has a restriction. 703 * 704 * @param restriction Restriction to check. Should be a UserManager.* restriction. 705 * @return Whether that restriction exists for the user running the process. 706 */ isCurrentProcessUserHasRestriction(String restriction)707 public boolean isCurrentProcessUserHasRestriction(String restriction) { 708 return mUserManager.hasUserRestriction(restriction); 709 } 710 711 /** 712 * Checks if the current process user can modify accounts. Demo and Guest users cannot modify 713 * accounts even if the DISALLOW_MODIFY_ACCOUNTS restriction is not applied. 714 */ canCurrentProcessModifyAccounts()715 public boolean canCurrentProcessModifyAccounts() { 716 return !isCurrentProcessUserHasRestriction(UserManager.DISALLOW_MODIFY_ACCOUNTS) 717 && !isCurrentProcessDemoUser() 718 && !isCurrentProcessGuestUser(); 719 } 720 721 /** 722 * Checks if the user running the current process can add new users. 723 */ canCurrentProcessAddUsers()724 public boolean canCurrentProcessAddUsers() { 725 return !isCurrentProcessUserHasRestriction(UserManager.DISALLOW_ADD_USER); 726 } 727 728 /** 729 * Checks if the user running the current process can remove users. 730 */ canCurrentProcessRemoveUsers()731 public boolean canCurrentProcessRemoveUsers() { 732 return !isCurrentProcessUserHasRestriction(UserManager.DISALLOW_REMOVE_USER); 733 } 734 735 /** 736 * Returns whether the current process user can switch to other users. 737 * 738 * <p>For instance switching users is not allowed if the user is in a phone call, 739 * or {@link #{UserManager.DISALLOW_USER_SWITCH} is set. 740 */ canCurrentProcessSwitchUsers()741 public boolean canCurrentProcessSwitchUsers() { 742 boolean inIdleCallState = TelephonyManager.getDefault().getCallState() 743 == TelephonyManager.CALL_STATE_IDLE; 744 boolean disallowUserSwitching = 745 isCurrentProcessUserHasRestriction(UserManager.DISALLOW_USER_SWITCH); 746 return (inIdleCallState && !disallowUserSwitching); 747 } 748 749 /** 750 * Grants admin permissions to the user. 751 * 752 * @param user User to be upgraded to Admin status. 753 */ 754 @RequiresPermission(allOf = { 755 Manifest.permission.INTERACT_ACROSS_USERS_FULL, 756 Manifest.permission.MANAGE_USERS 757 }) grantAdminPermissions(UserInfo user)758 public void grantAdminPermissions(UserInfo user) { 759 if (!isCurrentProcessAdminUser()) { 760 Log.w(TAG, "Only admin users can assign admin permissions."); 761 return; 762 } 763 764 mUserManager.setUserAdmin(user.id); 765 766 // Remove restrictions imposed on non-admins. 767 setDefaultNonAdminRestrictions(user, /* enable= */ false); 768 setOptionalNonAdminRestrictions(user, /* enable= */ false); 769 } 770 771 /** 772 * Creates a new user on the system with a default user name. This user name is set during 773 * constrution. The created user would be granted admin role. Only admins can create other 774 * admins. 775 * 776 * @return Newly created admin user, null if failed to create a user. 777 */ 778 @Nullable createNewAdminUser()779 public UserInfo createNewAdminUser() { 780 return createNewAdminUser(getDefaultAdminName()); 781 } 782 783 /** 784 * Creates a new user on the system, the created user would be granted admin role. 785 * Only admins can create other admins. 786 * 787 * @param userName Name to give to the newly created user. 788 * @return Newly created admin user, null if failed to create a user. 789 */ 790 @Nullable createNewAdminUser(String userName)791 public UserInfo createNewAdminUser(String userName) { 792 if (!(isCurrentProcessAdminUser() || isCurrentProcessSystemUser())) { 793 // Only Admins or System user can create other privileged users. 794 Log.e(TAG, "Only admin users and system user can create other admins."); 795 return null; 796 } 797 798 UserInfo user = mUserManager.createUser(userName, UserInfo.FLAG_ADMIN); 799 if (user == null) { 800 // Couldn't create user, most likely because there are too many. 801 Log.w(TAG, "can't create admin user."); 802 return null; 803 } 804 assignDefaultIcon(user); 805 806 return user; 807 } 808 809 /** 810 * Creates a new non-admin user on the system. 811 * 812 * @param userName Name to give to the newly created user. 813 * @return Newly created non-admin user, null if failed to create a user. 814 */ 815 @Nullable createNewNonAdminUser(String userName)816 public UserInfo createNewNonAdminUser(String userName) { 817 UserInfo user = mUserManager.createUser(userName, 0); 818 if (user == null) { 819 // Couldn't create user, most likely because there are too many. 820 Log.w(TAG, "can't create non-admin user."); 821 return null; 822 } 823 setDefaultNonAdminRestrictions(user, /* enable= */ true); 824 825 // Each non-admin has sms and outgoing call restrictions applied by the UserManager on 826 // creation. We want to enable these permissions by default in the car. 827 setUserRestriction(user, UserManager.DISALLOW_SMS, /* enable= */ false); 828 setUserRestriction(user, UserManager.DISALLOW_OUTGOING_CALLS, /* enable= */ false); 829 830 assignDefaultIcon(user); 831 return user; 832 } 833 834 /** 835 * Sets the values of default Non-Admin restrictions to the passed in value. 836 * 837 * @param userInfo User to set restrictions on. 838 * @param enable If true, restriction is ON, If false, restriction is OFF. 839 */ setDefaultNonAdminRestrictions(UserInfo userInfo, boolean enable)840 private void setDefaultNonAdminRestrictions(UserInfo userInfo, boolean enable) { 841 for (String restriction : DEFAULT_NON_ADMIN_RESTRICTIONS) { 842 setUserRestriction(userInfo, restriction, enable); 843 } 844 } 845 846 /** 847 * Sets the values of settings controllable restrictions to the passed in value. 848 * 849 * @param userInfo User to set restrictions on. 850 * @param enable If true, restriction is ON, If false, restriction is OFF. 851 */ setOptionalNonAdminRestrictions(UserInfo userInfo, boolean enable)852 private void setOptionalNonAdminRestrictions(UserInfo userInfo, boolean enable) { 853 for (String restriction : OPTIONAL_NON_ADMIN_RESTRICTIONS) { 854 setUserRestriction(userInfo, restriction, enable); 855 } 856 } 857 858 /** 859 * Sets the value of the specified restriction for the specified user. 860 * 861 * @param userInfo the user whose restriction is to be changed 862 * @param restriction the key of the restriction 863 * @param enable the value for the restriction. if true, turns the restriction ON, if false, 864 * turns the restriction OFF. 865 */ setUserRestriction(UserInfo userInfo, String restriction, boolean enable)866 public void setUserRestriction(UserInfo userInfo, String restriction, boolean enable) { 867 UserHandle userHandle = UserHandle.of(userInfo.id); 868 mUserManager.setUserRestriction(restriction, enable, userHandle); 869 } 870 871 /** 872 * Tries to remove the user that's passed in. System user cannot be removed. 873 * If the user to be removed is user currently running the process, 874 * it switches to the guest user first, and then removes the user. 875 * If the user being removed is the last admin user, this will create a new admin user. 876 * 877 * @param userInfo User to be removed 878 * @param guestUserName User name to use for the guest user if we need to switch to it 879 * @return {@code true} if user is successfully removed, {@code false} otherwise. 880 */ removeUser(UserInfo userInfo, String guestUserName)881 public boolean removeUser(UserInfo userInfo, String guestUserName) { 882 if (isSystemUser(userInfo)) { 883 Log.w(TAG, "User " + userInfo.id + " is system user, could not be removed."); 884 return false; 885 } 886 887 // Try to create a new admin before deleting the current one. 888 if (userInfo.isAdmin() && getAllAdminUsers().size() <= 1) { 889 return removeLastAdmin(userInfo); 890 } 891 892 if (!isCurrentProcessAdminUser() && !isCurrentProcessUser(userInfo)) { 893 // If the caller is non-admin, they can only delete themselves. 894 Log.e(TAG, "Non-admins cannot remove other users."); 895 return false; 896 } 897 898 if (userInfo.id == getCurrentForegroundUserId()) { 899 if (!canCurrentProcessSwitchUsers()) { 900 // If we can't switch to a different user, we can't exit this one and therefore 901 // can't delete it. 902 Log.w(TAG, "User switching is not allowed. Current user cannot be deleted"); 903 return false; 904 } 905 startGuestSession(guestUserName); 906 } 907 908 return mUserManager.removeUser(userInfo.id); 909 } 910 removeLastAdmin(UserInfo userInfo)911 private boolean removeLastAdmin(UserInfo userInfo) { 912 if (Log.isLoggable(TAG, Log.INFO)) { 913 Log.i(TAG, "User " + userInfo.id 914 + " is the last admin user on device. Creating a new admin."); 915 } 916 917 UserInfo newAdmin = createNewAdminUser(getDefaultAdminName()); 918 if (newAdmin == null) { 919 Log.w(TAG, "Couldn't create another admin, cannot delete current user."); 920 return false; 921 } 922 923 switchToUser(newAdmin); 924 return mUserManager.removeUser(userInfo.id); 925 } 926 927 /** 928 * Switches (logs in) to another user given user id. 929 * 930 * @param id User id to switch to. 931 * @return {@code true} if user switching succeed. 932 */ switchToUserId(int id)933 public boolean switchToUserId(int id) { 934 if (id == UserHandle.USER_SYSTEM && isHeadlessSystemUser()) { 935 // System User doesn't associate with real person, can not be switched to. 936 return false; 937 } 938 if (!canCurrentProcessSwitchUsers()) { 939 return false; 940 } 941 if (id == getCurrentForegroundUserId()) { 942 return false; 943 } 944 return mActivityManager.switchUser(id); 945 } 946 947 /** 948 * Switches (logs in) to another user. 949 * 950 * @param userInfo User to switch to. 951 * @return {@code true} if user switching succeed. 952 */ switchToUser(UserInfo userInfo)953 public boolean switchToUser(UserInfo userInfo) { 954 return switchToUserId(userInfo.id); 955 } 956 957 /** 958 * Creates a new guest or finds the existing one, and switches into it. 959 * 960 * @param guestName Username for the guest user. 961 * @return {@code true} if switch to guest user succeed. 962 */ startGuestSession(String guestName)963 public boolean startGuestSession(String guestName) { 964 UserInfo guest = createNewOrFindExistingGuest(guestName); 965 if (guest == null) { 966 return false; 967 } 968 return switchToUserId(guest.id); 969 } 970 971 /** 972 * Creates and returns a new guest user or returns the existing one. 973 * Returns null if it fails to create a new guest. 974 * 975 * @param guestName Username for guest if new guest is being created. 976 */ 977 @Nullable createNewOrFindExistingGuest(String guestName)978 public UserInfo createNewOrFindExistingGuest(String guestName) { 979 // CreateGuest will return null if a guest already exists. 980 UserInfo newGuest = mUserManager.createGuest(mContext, guestName); 981 if (newGuest != null) { 982 assignDefaultIcon(newGuest); 983 return newGuest; 984 } 985 986 UserInfo existingGuest = findExistingGuestUser(); 987 if (existingGuest == null) { 988 // Most likely a guest got removed just before we tried to look for it. 989 Log.w(TAG, "Couldn't create a new guest and couldn't find an existing one."); 990 } 991 992 return existingGuest; 993 } 994 995 /** 996 * Returns UserInfo for the existing guest user, or null if there are no guests on the device. 997 */ 998 @Nullable findExistingGuestUser()999 private UserInfo findExistingGuestUser() { 1000 for (UserInfo userInfo : getAllUsers()) { 1001 if (userInfo.isGuest() && !userInfo.guestToRemove) { 1002 return userInfo; 1003 } 1004 } 1005 return null; 1006 } 1007 1008 /** 1009 * Gets a bitmap representing the user's default avatar. 1010 * 1011 * @param userInfo User whose avatar should be returned. 1012 * @return Default user icon 1013 */ getUserDefaultIcon(UserInfo userInfo)1014 public Bitmap getUserDefaultIcon(UserInfo userInfo) { 1015 return UserIcons.convertToBitmap( 1016 UserIcons.getDefaultUserIcon(mContext.getResources(), userInfo.id, false)); 1017 } 1018 1019 /** 1020 * Gets a bitmap representing the default icon for a Guest user. 1021 * 1022 * @return Default guest user icon 1023 */ getGuestDefaultIcon()1024 public Bitmap getGuestDefaultIcon() { 1025 if (mDefaultGuestUserIcon == null) { 1026 mDefaultGuestUserIcon = UserIcons.convertToBitmap(UserIcons.getDefaultUserIcon( 1027 mContext.getResources(), UserHandle.USER_NULL, false)); 1028 } 1029 return mDefaultGuestUserIcon; 1030 } 1031 1032 /** 1033 * Gets an icon for the user. 1034 * 1035 * @param userInfo User for which we want to get the icon. 1036 * @return a Bitmap for the icon 1037 */ getUserIcon(UserInfo userInfo)1038 public Bitmap getUserIcon(UserInfo userInfo) { 1039 Bitmap picture = mUserManager.getUserIcon(userInfo.id); 1040 1041 if (picture == null) { 1042 return assignDefaultIcon(userInfo); 1043 } 1044 1045 return picture; 1046 } 1047 1048 /** 1049 * Method for scaling a Bitmap icon to a desirable size. 1050 * 1051 * @param icon Bitmap to scale. 1052 * @param desiredSize Wanted size for the icon. 1053 * @return Drawable for the icon, scaled to the new size. 1054 */ scaleUserIcon(Bitmap icon, int desiredSize)1055 public Drawable scaleUserIcon(Bitmap icon, int desiredSize) { 1056 Bitmap scaledIcon = Bitmap.createScaledBitmap( 1057 icon, desiredSize, desiredSize, true /* filter */); 1058 return new BitmapDrawable(mContext.getResources(), scaledIcon); 1059 } 1060 1061 /** 1062 * Sets new Username for the user. 1063 * 1064 * @param user User whose name should be changed. 1065 * @param name New username. 1066 */ setUserName(UserInfo user, String name)1067 public void setUserName(UserInfo user, String name) { 1068 mUserManager.setUserName(user.id, name); 1069 } 1070 registerReceiver()1071 private void registerReceiver() { 1072 IntentFilter filter = new IntentFilter(); 1073 filter.addAction(Intent.ACTION_USER_REMOVED); 1074 filter.addAction(Intent.ACTION_USER_ADDED); 1075 filter.addAction(Intent.ACTION_USER_INFO_CHANGED); 1076 filter.addAction(Intent.ACTION_USER_SWITCHED); 1077 filter.addAction(Intent.ACTION_USER_STOPPED); 1078 filter.addAction(Intent.ACTION_USER_UNLOCKED); 1079 mContext.registerReceiverAsUser(mUserChangeReceiver, UserHandle.ALL, filter, null, null); 1080 } 1081 1082 // Assigns a default icon to a user according to the user's id. assignDefaultIcon(UserInfo userInfo)1083 private Bitmap assignDefaultIcon(UserInfo userInfo) { 1084 Bitmap bitmap = userInfo.isGuest() 1085 ? getGuestDefaultIcon() : getUserDefaultIcon(userInfo); 1086 mUserManager.setUserIcon(userInfo.id, bitmap); 1087 return bitmap; 1088 } 1089 unregisterReceiver()1090 private void unregisterReceiver() { 1091 mContext.unregisterReceiver(mUserChangeReceiver); 1092 } 1093 getDefaultAdminName()1094 private String getDefaultAdminName() { 1095 if (TextUtils.isEmpty(mDefaultAdminName)) { 1096 mDefaultAdminName = mContext.getString(com.android.internal.R.string.owner_name); 1097 } 1098 return mDefaultAdminName; 1099 } 1100 1101 @VisibleForTesting setDefaultAdminName(String defaultAdminName)1102 void setDefaultAdminName(String defaultAdminName) { 1103 mDefaultAdminName = defaultAdminName; 1104 } 1105 1106 /** 1107 * Interface for listeners that want to register for receiving updates to changes to the users 1108 * on the system including removing and adding users, and changing user info. 1109 */ 1110 public interface OnUsersUpdateListener { 1111 /** 1112 * Method that will get called when users list has been changed. 1113 */ onUsersUpdate()1114 void onUsersUpdate(); 1115 } 1116 } 1117