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