• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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