UserManager.java revision 409297da182267465adbc21cfb75a23e8d678117
1/*
2 * Copyright (C) 2012 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 */
16package android.os;
17
18import android.app.ActivityManager;
19import android.app.ActivityManagerNative;
20import android.content.Context;
21import android.content.pm.UserInfo;
22import android.content.res.Resources;
23import android.graphics.Bitmap;
24import android.graphics.Canvas;
25import android.graphics.Bitmap.Config;
26import android.graphics.Rect;
27import android.graphics.drawable.BitmapDrawable;
28import android.graphics.drawable.Drawable;
29import android.provider.Settings;
30import android.util.Log;
31import android.view.WindowManager.LayoutParams;
32
33import com.android.internal.R;
34
35import java.util.ArrayList;
36import java.util.List;
37
38/**
39 * Manages users and user details on a multi-user system.
40 */
41public class UserManager {
42
43    private static String TAG = "UserManager";
44    private final IUserManager mService;
45    private final Context mContext;
46
47    /**
48     * Key for user restrictions. Specifies if a user is disallowed from adding and removing
49     * accounts.
50     * The default value is <code>false</code>.
51     * <p/>
52     * Type: Boolean
53     * @see #setUserRestrictions(Bundle)
54     * @see #getUserRestrictions()
55     */
56    public static final String DISALLOW_MODIFY_ACCOUNTS = "no_modify_accounts";
57
58    /**
59     * Key for user restrictions. Specifies if a user is disallowed from changing Wi-Fi
60     * access points.
61     * The default value is <code>false</code>.
62     * <p/>
63     * Type: Boolean
64     * @see #setUserRestrictions(Bundle)
65     * @see #getUserRestrictions()
66     */
67    public static final String DISALLOW_CONFIG_WIFI = "no_config_wifi";
68
69    /**
70     * Key for user restrictions. Specifies if a user is disallowed from installing applications.
71     * The default value is <code>false</code>.
72     * <p/>
73     * Type: Boolean
74     * @see #setUserRestrictions(Bundle)
75     * @see #getUserRestrictions()
76     */
77    public static final String DISALLOW_INSTALL_APPS = "no_install_apps";
78
79    /**
80     * Key for user restrictions. Specifies if a user is disallowed from uninstalling applications.
81     * The default value is <code>false</code>.
82     * <p/>
83     * Type: Boolean
84     * @see #setUserRestrictions(Bundle)
85     * @see #getUserRestrictions()
86     */
87    public static final String DISALLOW_UNINSTALL_APPS = "no_uninstall_apps";
88
89    /**
90     * Key for user restrictions. Specifies if a user is disallowed from toggling location sharing.
91     * The default value is <code>false</code>.
92     * <p/>
93     * Type: Boolean
94     * @see #setUserRestrictions(Bundle)
95     * @see #getUserRestrictions()
96     */
97    public static final String DISALLOW_SHARE_LOCATION = "no_share_location";
98
99    /**
100     * Key for user restrictions. Specifies if a user is disallowed from enabling the
101     * "Unknown Sources" setting, that allows installation of apps from unknown sources.
102     * The default value is <code>false</code>.
103     * <p/>
104     * Type: Boolean
105     * @see #setUserRestrictions(Bundle)
106     * @see #getUserRestrictions()
107     */
108    public static final String DISALLOW_INSTALL_UNKNOWN_SOURCES = "no_install_unknown_sources";
109
110    /**
111     * Key for user restrictions. Specifies if a user is disallowed from configuring bluetooth.
112     * The default value is <code>false</code>.
113     * <p/>
114     * Type: Boolean
115     * @see #setUserRestrictions(Bundle)
116     * @see #getUserRestrictions()
117     */
118    public static final String DISALLOW_CONFIG_BLUETOOTH = "no_config_bluetooth";
119
120    /**
121     * Key for user restrictions. Specifies if a user is disallowed from transferring files over
122     * USB. The default value is <code>false</code>.
123     * <p/>
124     * Type: Boolean
125     * @see #setUserRestrictions(Bundle)
126     * @see #getUserRestrictions()
127     */
128    public static final String DISALLOW_USB_FILE_TRANSFER = "no_usb_file_transfer";
129
130    /**
131     * Key for user restrictions. Specifies if a user is disallowed from configuring user
132     * credentials. The default value is <code>false</code>.
133     * <p/>
134     * Type: Boolean
135     * @see #setUserRestrictions(Bundle)
136     * @see #getUserRestrictions()
137     */
138    public static final String DISALLOW_CONFIG_CREDENTIALS = "no_config_credentials";
139
140    /**
141     * Key for user restrictions. Specifies if a user is disallowed from removing users.
142     * The default value is <code>false</code>.
143     * <p/>
144     * Type: Boolean
145     * @see #setUserRestrictions(Bundle)
146     * @see #getUserRestrictions()
147     */
148    public static final String DISALLOW_REMOVE_USER = "no_remove_user";
149
150    /**
151     * Key for user restrictions. Specifies if a user is disallowed from enabling or
152     * accessing debugging features. The default value is <code>false</code>.
153     * <p/>
154     * Type: Boolean
155     * @see #setUserRestrictions(Bundle)
156     * @see #getUserRestrictions()
157     */
158    public static final String DISALLOW_DEBUGGING_FEATURES = "no_debugging_features";
159
160    /**
161     * Key for user restrictions. Specifies if a user is disallowed from configuring VPN.
162     * The default value is <code>false</code>.
163     * <p/>
164     * Type: Boolean
165     * @see #setUserRestrictions(Bundle)
166     * @see #getUserRestrictions()
167     */
168    public static final String DISALLOW_CONFIG_VPN = "no_config_vpn";
169
170    /**
171     * Key for user restrictions. Specifies if a user is disallowed from configuring Tethering
172     * & portable hotspots. The default value is <code>false</code>.
173     * <p/>
174     * Type: Boolean
175     * @see #setUserRestrictions(Bundle)
176     * @see #getUserRestrictions()
177     */
178    public static final String DISALLOW_CONFIG_TETHERING = "no_config_tethering";
179
180    /**
181     * Key for user restrictions. Specifies if a user is disallowed from factory resetting
182     * from Settings.
183     * The default value is <code>false</code>.
184     * <p>
185     * @see #setUserRestrictions(Bundle)
186     * @see #getUserRestrictions()
187     */
188    public static final String DISALLOW_FACTORY_RESET = "no_factory_reset";
189
190    /**
191     * Key for user restrictions. Specifies if a user is disallowed from adding new users and
192     * profiles. The default value is <code>false</code>.
193     * <p>
194     * Type: Boolean
195     * @see #setUserRestrictions(Bundle)
196     * @see #getUserRestrictions()
197     */
198    public static final String DISALLOW_ADD_USER = "no_add_user";
199
200    /**
201     * Key for user restrictions. Specifies if a user is disallowed from disabling application
202     * verification. The default value is <code>false</code>.
203     * <p>
204     * Type: Boolean
205     * @see #setUserRestrictions(Bundle)
206     * @see #getUserRestrictions()
207     */
208    public static final String ENSURE_VERIFY_APPS = "ensure_verify_apps";
209
210    /**
211     * Key for user restrictions. Specifies if a user is disallowed from configuring cell
212     * broadcasts. The default value is <code>false</code>.
213     * <p>
214     * Type: Boolean
215     * @see #setUserRestrictions(Bundle)
216     * @see #getUserRestrictions()
217     */
218    public static final String DISALLOW_CONFIG_CELL_BROADCASTS = "no_config_cell_broadcasts";
219
220    /**
221     * Key for user restrictions. Specifies if a user is disallowed from configuring mobile
222     * networks. The default value is <code>false</code>.
223     * <p>
224     * Type: Boolean
225     * @see #setUserRestrictions(Bundle)
226     * @see #getUserRestrictions()
227     */
228    public static final String DISALLOW_CONFIG_MOBILE_NETWORKS = "no_config_mobile_networks";
229
230    /**
231     * Key for user restrictions. Specifies if a user is disallowed from controlling
232     * applications in Settings. The default value is <code>false</code>.
233     * <p>
234     * Type: Boolean
235     * @see #setUserRestrictions(Bundle)
236     * @see #getUserRestrictions()
237     */
238    public static final String DISALLOW_APPS_CONTROL = "no_control_apps";
239
240    /**
241     * Key for user restrictions. Specifies if a user is disallowed from mounting
242     * physical external media. The default value is <code>false</code>.
243     * <p/>
244     * Type: Boolean
245     * @see #setUserRestrictions(Bundle)
246     * @see #getUserRestrictions()
247     */
248    public static final String DISALLOW_MOUNT_PHYSICAL_MEDIA = "no_physical_media";
249
250    /**
251     * Key for user restrictions. Specifies if a user is disallowed from adjusting microphone
252     * volume.
253     * The default value is <code>false</code>.
254     * <p/>
255     * Type: Boolean
256     * @see #setUserRestrictions(Bundle)
257     * @see #getUserRestrictions()
258     */
259    public static final String DISALLOW_UNMUTE_MICROPHONE = "no_unmute_microphone";
260
261    /**
262     * Key for user restrictions. Specifies if a user is disallowed from adjusting the master
263     * volume.
264     * The default value is <code>false</code>.
265     * <p/>
266     * Type: Boolean
267     * @see #setUserRestrictions(Bundle)
268     * @see #getUserRestrictions()
269     */
270    public static final String DISALLOW_ADJUST_VOLUME = "no_adjust_volume";
271
272    /**
273     * Key for user restrictions. Specifies that the user is not allowed to send or receive
274     * phone calls or text messages. Emergency calls may still be permitted.
275     * The default value is <code>false</code>.
276     * <p/>
277     * Type: Boolean
278     * @see #setUserRestrictions(Bundle)
279     * @see #getUserRestrictions()
280     */
281    public static final String DISALLOW_TELEPHONY = "no_telephony";
282
283    /**
284     * Key for user restrictions. Specifies that windows besides app windows should not be
285     * created. This will block the creation of the following types of windows.
286     * <li>{@link LayoutParams#TYPE_TOAST}</li>
287     * <li>{@link LayoutParams#TYPE_PHONE}</li>
288     * <li>{@link LayoutParams#TYPE_PRIORITY_PHONE}</li>
289     * <li>{@link LayoutParams#TYPE_SYSTEM_ALERT}</li>
290     * <li>{@link LayoutParams#TYPE_SYSTEM_ERROR}</li>
291     * <li>{@link LayoutParams#TYPE_SYSTEM_OVERLAY}</li>
292     *
293     * <p>The default value is <code>false</code>.
294     * <p/>
295     * Type: Boolean
296     * @see #setUserRestrictions(Bundle)
297     * @see #getUserRestrictions()
298     */
299    public static final String DISALLOW_CREATE_WINDOWS = "no_create_windows";
300
301    /** @hide */
302    public static final int PIN_VERIFICATION_FAILED_INCORRECT = -3;
303    /** @hide */
304    public static final int PIN_VERIFICATION_FAILED_NOT_SET = -2;
305    /** @hide */
306    public static final int PIN_VERIFICATION_SUCCESS = -1;
307
308    private static UserManager sInstance = null;
309
310    /** @hide */
311    public synchronized static UserManager get(Context context) {
312        if (sInstance == null) {
313            sInstance = (UserManager) context.getSystemService(Context.USER_SERVICE);
314        }
315        return sInstance;
316    }
317
318    /** @hide */
319    public UserManager(Context context, IUserManager service) {
320        mService = service;
321        mContext = context;
322    }
323
324    /**
325     * Returns whether the system supports multiple users.
326     * @return true if multiple users can be created by user, false if it is a single user device.
327     * @hide
328     */
329    public static boolean supportsMultipleUsers() {
330        return getMaxSupportedUsers() > 1
331                && SystemProperties.getBoolean("fw.show_multiuserui",
332                Resources.getSystem().getBoolean(R.bool.config_enableMultiUserUI));
333    }
334
335    /**
336     * Returns the user handle for the user that the calling process is running on.
337     *
338     * @return the user handle of the user making this call.
339     * @hide
340     */
341    public int getUserHandle() {
342        return UserHandle.myUserId();
343    }
344
345    /**
346     * Returns the user name of the user making this call.  This call is only
347     * available to applications on the system image; it requires the
348     * MANAGE_USERS permission.
349     * @return the user name
350     */
351    public String getUserName() {
352        try {
353            return mService.getUserInfo(getUserHandle()).name;
354        } catch (RemoteException re) {
355            Log.w(TAG, "Could not get user name", re);
356            return "";
357        }
358    }
359
360   /**
361     * Used to determine whether the user making this call is subject to
362     * teleportations.
363     * @return whether the user making this call is a goat
364     */
365    public boolean isUserAGoat() {
366        return false;
367    }
368
369    /**
370     * Used to check if the user making this call is linked to another user. Linked users may have
371     * a reduced number of available apps, app restrictions and account restrictions.
372     * @return whether the user making this call is a linked user
373     * @hide
374     */
375    public boolean isLinkedUser() {
376        try {
377            return mService.isRestricted();
378        } catch (RemoteException re) {
379            Log.w(TAG, "Could not check if user is limited ", re);
380            return false;
381        }
382    }
383
384    /**
385     * Checks if the calling app is running as a guest user.
386     * @return whether the caller is a guest user.
387     * @hide
388     */
389    public boolean isGuestUser() {
390        UserInfo user = getUserInfo(UserHandle.myUserId());
391        return user != null ? user.isGuest() : false;
392    }
393
394    /**
395     * Return whether the given user is actively running.  This means that
396     * the user is in the "started" state, not "stopped" -- it is currently
397     * allowed to run code through scheduled alarms, receiving broadcasts,
398     * etc.  A started user may be either the current foreground user or a
399     * background user; the result here does not distinguish between the two.
400     * @param user The user to retrieve the running state for.
401     */
402    public boolean isUserRunning(UserHandle user) {
403        try {
404            return ActivityManagerNative.getDefault().isUserRunning(
405                    user.getIdentifier(), false);
406        } catch (RemoteException e) {
407            return false;
408        }
409    }
410
411    /**
412     * Return whether the given user is actively running <em>or</em> stopping.
413     * This is like {@link #isUserRunning(UserHandle)}, but will also return
414     * true if the user had been running but is in the process of being stopped
415     * (but is not yet fully stopped, and still running some code).
416     * @param user The user to retrieve the running state for.
417     */
418    public boolean isUserRunningOrStopping(UserHandle user) {
419        try {
420            return ActivityManagerNative.getDefault().isUserRunning(
421                    user.getIdentifier(), true);
422        } catch (RemoteException e) {
423            return false;
424        }
425    }
426
427    /**
428     * Returns the UserInfo object describing a specific user.
429     * Requires {@link android.Manifest.permission#MANAGE_USERS} permission.
430     * @param userHandle the user handle of the user whose information is being requested.
431     * @return the UserInfo object for a specific user.
432     * @hide
433     */
434    public UserInfo getUserInfo(int userHandle) {
435        try {
436            return mService.getUserInfo(userHandle);
437        } catch (RemoteException re) {
438            Log.w(TAG, "Could not get user info", re);
439            return null;
440        }
441    }
442
443    /**
444     * Returns the user-wide restrictions imposed on this user.
445     * @return a Bundle containing all the restrictions.
446     */
447    public Bundle getUserRestrictions() {
448        return getUserRestrictions(Process.myUserHandle());
449    }
450
451    /**
452     * Returns the user-wide restrictions imposed on the user specified by <code>userHandle</code>.
453     * @param userHandle the UserHandle of the user for whom to retrieve the restrictions.
454     * @return a Bundle containing all the restrictions.
455     */
456    public Bundle getUserRestrictions(UserHandle userHandle) {
457        try {
458            return mService.getUserRestrictions(userHandle.getIdentifier());
459        } catch (RemoteException re) {
460            Log.w(TAG, "Could not get user restrictions", re);
461            return Bundle.EMPTY;
462        }
463    }
464
465    /**
466     * Sets all the user-wide restrictions for this user.
467     * Requires the MANAGE_USERS permission.
468     * @param restrictions the Bundle containing all the restrictions.
469     */
470    public void setUserRestrictions(Bundle restrictions) {
471        setUserRestrictions(restrictions, Process.myUserHandle());
472    }
473
474    /**
475     * Sets all the user-wide restrictions for the specified user.
476     * Requires the MANAGE_USERS permission.
477     * @param restrictions the Bundle containing all the restrictions.
478     * @param userHandle the UserHandle of the user for whom to set the restrictions.
479     */
480    public void setUserRestrictions(Bundle restrictions, UserHandle userHandle) {
481        try {
482            mService.setUserRestrictions(restrictions, userHandle.getIdentifier());
483        } catch (RemoteException re) {
484            Log.w(TAG, "Could not set user restrictions", re);
485        }
486    }
487
488    /**
489     * Sets the value of a specific restriction.
490     * Requires the MANAGE_USERS permission.
491     * @param key the key of the restriction
492     * @param value the value for the restriction
493     */
494    public void setUserRestriction(String key, boolean value) {
495        Bundle bundle = getUserRestrictions();
496        bundle.putBoolean(key, value);
497        setUserRestrictions(bundle);
498    }
499
500    /**
501     * @hide
502     * Sets the value of a specific restriction on a specific user.
503     * Requires the MANAGE_USERS permission.
504     * @param key the key of the restriction
505     * @param value the value for the restriction
506     * @param userHandle the user whose restriction is to be changed.
507     */
508    public void setUserRestriction(String key, boolean value, UserHandle userHandle) {
509        Bundle bundle = getUserRestrictions(userHandle);
510        bundle.putBoolean(key, value);
511        setUserRestrictions(bundle, userHandle);
512    }
513
514    /**
515     * Returns whether the current user has been disallowed from performing certain actions
516     * or setting certain settings.
517     *
518     * @param restrictionKey The string key representing the restriction.
519     * @return {@code true} if the current user has the given restriction, {@code false} otherwise.
520     */
521    public boolean hasUserRestriction(String restrictionKey) {
522        return hasUserRestriction(restrictionKey, Process.myUserHandle());
523    }
524
525    /**
526     * @hide
527     * Returns whether the given user has been disallowed from performing certain actions
528     * or setting certain settings.
529     * @param restrictionKey the string key representing the restriction
530     * @param userHandle the UserHandle of the user for whom to retrieve the restrictions.
531     */
532    public boolean hasUserRestriction(String restrictionKey, UserHandle userHandle) {
533        return getUserRestrictions(userHandle).getBoolean(restrictionKey, false);
534    }
535
536    /**
537     * Return the serial number for a user.  This is a device-unique
538     * number assigned to that user; if the user is deleted and then a new
539     * user created, the new users will not be given the same serial number.
540     * @param user The user whose serial number is to be retrieved.
541     * @return The serial number of the given user; returns -1 if the
542     * given UserHandle does not exist.
543     * @see #getUserForSerialNumber(long)
544     */
545    public long getSerialNumberForUser(UserHandle user) {
546        return getUserSerialNumber(user.getIdentifier());
547    }
548
549    /**
550     * Return the user associated with a serial number previously
551     * returned by {@link #getSerialNumberForUser(UserHandle)}.
552     * @param serialNumber The serial number of the user that is being
553     * retrieved.
554     * @return Return the user associated with the serial number, or null
555     * if there is not one.
556     * @see #getSerialNumberForUser(UserHandle)
557     */
558    public UserHandle getUserForSerialNumber(long serialNumber) {
559        int ident = getUserHandle((int)serialNumber);
560        return ident >= 0 ? new UserHandle(ident) : null;
561    }
562
563    /**
564     * Creates a user with the specified name and options.
565     * Requires {@link android.Manifest.permission#MANAGE_USERS} permission.
566     *
567     * @param name the user's name
568     * @param flags flags that identify the type of user and other properties.
569     * @see UserInfo
570     *
571     * @return the UserInfo object for the created user, or null if the user could not be created.
572     * @hide
573     */
574    public UserInfo createUser(String name, int flags) {
575        try {
576            return mService.createUser(name, flags);
577        } catch (RemoteException re) {
578            Log.w(TAG, "Could not create a user", re);
579            return null;
580        }
581    }
582
583    /**
584     * Creates a guest user and configures it.
585     * @param context an application context
586     * @param name the name to set for the user
587     * @hide
588     */
589    public UserInfo createGuest(Context context, String name) {
590        UserInfo guest = createUser(name, UserInfo.FLAG_GUEST);
591        if (guest != null) {
592            Settings.Secure.putStringForUser(context.getContentResolver(),
593                    Settings.Secure.SKIP_FIRST_USE_HINTS, "1", guest.id);
594        }
595        return guest;
596    }
597
598    /**
599     * Creates a user with the specified name and options as a profile of another user.
600     * Requires {@link android.Manifest.permission#MANAGE_USERS} permission.
601     *
602     * @param name the user's name
603     * @param flags flags that identify the type of user and other properties.
604     * @see UserInfo
605     * @param userHandle new user will be a profile of this use.
606     *
607     * @return the UserInfo object for the created user, or null if the user could not be created.
608     * @hide
609     */
610    public UserInfo createProfileForUser(String name, int flags, int userHandle) {
611        try {
612            return mService.createProfileForUser(name, flags, userHandle);
613        } catch (RemoteException re) {
614            Log.w(TAG, "Could not create a user", re);
615            return null;
616        }
617    }
618
619    /**
620     * Sets the user as enabled, if such an user exists.
621     * Requires {@link android.Manifest.permission#MANAGE_USERS} permission.
622     * Note that the default is true, it's only that managed profiles might not be enabled.
623     *
624     * @param userHandle the id of the profile to enable
625     * @hide
626     */
627    public void setUserEnabled(int userHandle) {
628        try {
629            mService.setUserEnabled(userHandle);
630        } catch (RemoteException e) {
631            Log.w(TAG, "Could not enable the profile", e);
632        }
633    }
634
635    /**
636     * Return the number of users currently created on the device.
637     */
638    public int getUserCount() {
639        List<UserInfo> users = getUsers();
640        return users != null ? users.size() : 1;
641    }
642
643    /**
644     * Returns information for all users on this device.
645     * Requires {@link android.Manifest.permission#MANAGE_USERS} permission.
646     * @return the list of users that were created.
647     * @hide
648     */
649    public List<UserInfo> getUsers() {
650        try {
651            return mService.getUsers(false);
652        } catch (RemoteException re) {
653            Log.w(TAG, "Could not get user list", re);
654            return null;
655        }
656    }
657
658    /**
659     * Returns list of the profiles of userHandle including
660     * userHandle itself.
661     * Note that it this returns both enabled and not enabled profiles. See
662     * {@link #getUserProfiles()} if you need only the enabled ones.
663     *
664     * Requires {@link android.Manifest.permission#MANAGE_USERS} permission.
665     * @param userHandle profiles of this user will be returned.
666     * @return the list of profiles.
667     * @hide
668     */
669    public List<UserInfo> getProfiles(int userHandle) {
670        try {
671            return mService.getProfiles(userHandle, false /* enabledOnly */);
672        } catch (RemoteException re) {
673            Log.w(TAG, "Could not get user list", re);
674            return null;
675        }
676    }
677
678    /**
679     * Returns a list of UserHandles for profiles associated with the user that the calling process
680     * is running on, including the user itself.
681     *
682     * @return A non-empty list of UserHandles associated with the calling user.
683     */
684    public List<UserHandle> getUserProfiles() {
685        ArrayList<UserHandle> profiles = new ArrayList<UserHandle>();
686        List<UserInfo> users = new ArrayList<UserInfo>();
687        try {
688            users = mService.getProfiles(UserHandle.myUserId(), true /* enabledOnly */);
689        } catch (RemoteException re) {
690            Log.w(TAG, "Could not get user list", re);
691            return null;
692        }
693        for (UserInfo info : users) {
694            UserHandle userHandle = new UserHandle(info.id);
695            profiles.add(userHandle);
696        }
697        return profiles;
698    }
699
700    /**
701     * Returns the parent of the profile which this method is called from
702     * or null if called from a user that is not a profile.
703     *
704     * @hide
705     */
706    public UserInfo getProfileParent(int userHandle) {
707        try {
708            return mService.getProfileParent(userHandle);
709        } catch (RemoteException re) {
710            Log.w(TAG, "Could not get profile parent", re);
711            return null;
712        }
713    }
714
715    /**
716     * If the target user is a managed profile of the calling user or the caller
717     * is itself a managed profile, then this returns a badged copy of the given
718     * icon to be able to distinguish it from the original icon.
719     * <P>
720     * If the original drawable is not a BitmapDrawable, then the original
721     * drawable is returned.
722     * </P>
723     *
724     * @param icon The icon to badge.
725     * @param user The target user.
726     * @return A drawable that combines the original icon and a badge as
727     *         determined by the system.
728     */
729    public Drawable getBadgedDrawableForUser(Drawable icon, UserHandle user) {
730        int badgeResId = getBadgeResIdForUser(user.getIdentifier());
731        if (badgeResId == 0) {
732            return icon;
733        } else {
734            Drawable badgeIcon = mContext.getPackageManager()
735                    .getDrawable("system", badgeResId, null);
736            return getMergedDrawable(icon, badgeIcon);
737        }
738    }
739
740    /**
741     * If the target user is a managed profile of the calling user or the caller
742     * is itself a managed profile, then this returns a copy of the label with
743     * badging for accessibility services like talkback. E.g. passing in "Email"
744     * and it might return "Work Email" for Email in the work profile.
745     *
746     * @param label The label to change.
747     * @param user The target user.
748     * @return A label that combines the original label and a badge as
749     *         determined by the system.
750     */
751    public String getBadgedLabelForUser(String label, UserHandle user) {
752        UserInfo userInfo = getUserIfProfile(user.getIdentifier());
753        if (userInfo != null && userInfo.isManagedProfile()) {
754            return Resources.getSystem().getString(
755                    R.string.managed_profile_label_badge, label);
756        }
757        return label;
758    }
759
760    /**
761     * If the target user is a managed profile of the calling user or the caller
762     * is itself a managed profile, then this returns a drawable to use as a small
763     * icon to include in a view to distinguish it from the original icon.
764     *
765     * @param user The target user.
766     * @return the drawable or null if no drawable is required.
767     * @hide
768     */
769    public Drawable getBadgeForUser(UserHandle user) {
770        UserInfo userInfo = getUserIfProfile(user.getIdentifier());
771        if (userInfo != null && userInfo.isManagedProfile()) {
772            return Resources.getSystem().getDrawable(
773                    com.android.internal.R.drawable.ic_corp_badge);
774        }
775        return null;
776    }
777
778    private int getBadgeResIdForUser(int userHandle) {
779        // Return the framework-provided badge.
780        UserInfo userInfo = getUserIfProfile(userHandle);
781        if (userInfo != null && userInfo.isManagedProfile()) {
782            return com.android.internal.R.drawable.ic_corp_icon_badge;
783        }
784        return 0;
785    }
786
787    /**
788     * @return UserInfo for userHandle if it exists and is a profile of the current
789     *         user or null.
790     */
791    private UserInfo getUserIfProfile(int userHandle) {
792        List<UserInfo> userProfiles = getProfiles(getUserHandle());
793        for (UserInfo user : userProfiles) {
794            if (user.id == userHandle) {
795                return user;
796            }
797        }
798        return null;
799    }
800
801    private Drawable getMergedDrawable(Drawable icon, Drawable badge) {
802        final int width = icon.getIntrinsicWidth();
803        final int height = icon.getIntrinsicHeight();
804        Bitmap bitmap = Bitmap.createBitmap(width, height, Config.ARGB_8888);
805        Canvas canvas = new Canvas(bitmap);
806        icon.setBounds(0, 0, width, height);
807        icon.draw(canvas);
808        badge.setBounds(0, 0, width, height);
809        badge.draw(canvas);
810        BitmapDrawable merged = new BitmapDrawable(bitmap);
811        if (icon instanceof BitmapDrawable) {
812            merged.setTargetDensity(((BitmapDrawable) icon).getBitmap().getDensity());
813        }
814        return merged;
815    }
816
817    /**
818     * Returns information for all users on this device. Requires
819     * {@link android.Manifest.permission#MANAGE_USERS} permission.
820     *
821     * @param excludeDying specify if the list should exclude users being
822     *            removed.
823     * @return the list of users that were created.
824     * @hide
825     */
826    public List<UserInfo> getUsers(boolean excludeDying) {
827        try {
828            return mService.getUsers(excludeDying);
829        } catch (RemoteException re) {
830            Log.w(TAG, "Could not get user list", re);
831            return null;
832        }
833    }
834
835    /**
836     * Removes a user and all associated data.
837     * Requires {@link android.Manifest.permission#MANAGE_USERS} permission.
838     * @param userHandle the integer handle of the user, where 0 is the primary user.
839     * @hide
840     */
841    public boolean removeUser(int userHandle) {
842        try {
843            return mService.removeUser(userHandle);
844        } catch (RemoteException re) {
845            Log.w(TAG, "Could not remove user ", re);
846            return false;
847        }
848    }
849
850    /**
851     * Updates the user's name.
852     * Requires {@link android.Manifest.permission#MANAGE_USERS} permission.
853     *
854     * @param userHandle the user's integer handle
855     * @param name the new name for the user
856     * @hide
857     */
858    public void setUserName(int userHandle, String name) {
859        try {
860            mService.setUserName(userHandle, name);
861        } catch (RemoteException re) {
862            Log.w(TAG, "Could not set the user name ", re);
863        }
864    }
865
866    /**
867     * Sets the user's photo.
868     * @param userHandle the user for whom to change the photo.
869     * @param icon the bitmap to set as the photo.
870     * @hide
871     */
872    public void setUserIcon(int userHandle, Bitmap icon) {
873        try {
874            mService.setUserIcon(userHandle, icon);
875        } catch (RemoteException re) {
876            Log.w(TAG, "Could not set the user icon ", re);
877        }
878    }
879
880    /**
881     * Returns a file descriptor for the user's photo. PNG data can be read from this file.
882     * @param userHandle the user whose photo we want to read.
883     * @return a {@link Bitmap} of the user's photo, or null if there's no photo.
884     * @hide
885     */
886    public Bitmap getUserIcon(int userHandle) {
887        try {
888            return mService.getUserIcon(userHandle);
889        } catch (RemoteException re) {
890            Log.w(TAG, "Could not get the user icon ", re);
891            return null;
892        }
893    }
894
895    /**
896     * Returns the maximum number of users that can be created on this device. A return value
897     * of 1 means that it is a single user device.
898     * @hide
899     * @return a value greater than or equal to 1
900     */
901    public static int getMaxSupportedUsers() {
902        // Don't allow multiple users on certain builds
903        if (android.os.Build.ID.startsWith("JVP")) return 1;
904        // Svelte devices don't get multi-user.
905        if (ActivityManager.isLowRamDeviceStatic()) return 1;
906        return SystemProperties.getInt("fw.max_users",
907                Resources.getSystem().getInteger(R.integer.config_multiuserMaximumUsers));
908    }
909
910    /**
911     * Returns true if the user switcher should be shown, this will be if there
912     * are multiple users that aren't managed profiles.
913     * @hide
914     * @return true if user switcher should be shown.
915     */
916    public boolean isUserSwitcherEnabled() {
917        List<UserInfo> users = getUsers(true);
918        if (users == null) {
919           return false;
920        }
921        int switchableUserCount = 0;
922        for (UserInfo user : users) {
923            if (user.supportsSwitchTo()) {
924                ++switchableUserCount;
925            }
926        }
927        final boolean guestEnabled = Settings.Global.getInt(mContext.getContentResolver(),
928                Settings.Global.GUEST_USER_ENABLED, 0) == 1;
929        return switchableUserCount > 1 || guestEnabled;
930    }
931
932    /**
933     * Returns a serial number on this device for a given userHandle. User handles can be recycled
934     * when deleting and creating users, but serial numbers are not reused until the device is wiped.
935     * @param userHandle
936     * @return a serial number associated with that user, or -1 if the userHandle is not valid.
937     * @hide
938     */
939    public int getUserSerialNumber(int userHandle) {
940        try {
941            return mService.getUserSerialNumber(userHandle);
942        } catch (RemoteException re) {
943            Log.w(TAG, "Could not get serial number for user " + userHandle);
944        }
945        return -1;
946    }
947
948    /**
949     * Returns a userHandle on this device for a given user serial number. User handles can be
950     * recycled when deleting and creating users, but serial numbers are not reused until the device
951     * is wiped.
952     * @param userSerialNumber
953     * @return the userHandle associated with that user serial number, or -1 if the serial number
954     * is not valid.
955     * @hide
956     */
957    public int getUserHandle(int userSerialNumber) {
958        try {
959            return mService.getUserHandle(userSerialNumber);
960        } catch (RemoteException re) {
961            Log.w(TAG, "Could not get userHandle for user " + userSerialNumber);
962        }
963        return -1;
964    }
965
966    /**
967     * Returns a Bundle containing any saved application restrictions for this user, for the
968     * given package name. Only an application with this package name can call this method.
969     * @param packageName the package name of the calling application
970     * @return a Bundle with the restrictions as key/value pairs, or null if there are no
971     * saved restrictions. The values can be of type Boolean, String or String[], depending
972     * on the restriction type, as defined by the application.
973     */
974    public Bundle getApplicationRestrictions(String packageName) {
975        try {
976            return mService.getApplicationRestrictions(packageName);
977        } catch (RemoteException re) {
978            Log.w(TAG, "Could not get application restrictions for package " + packageName);
979        }
980        return null;
981    }
982
983    /**
984     * @hide
985     */
986    public Bundle getApplicationRestrictions(String packageName, UserHandle user) {
987        try {
988            return mService.getApplicationRestrictionsForUser(packageName, user.getIdentifier());
989        } catch (RemoteException re) {
990            Log.w(TAG, "Could not get application restrictions for user " + user.getIdentifier());
991        }
992        return null;
993    }
994
995    /**
996     * @hide
997     */
998    public void setApplicationRestrictions(String packageName, Bundle restrictions,
999            UserHandle user) {
1000        try {
1001            mService.setApplicationRestrictions(packageName, restrictions, user.getIdentifier());
1002        } catch (RemoteException re) {
1003            Log.w(TAG, "Could not set application restrictions for user " + user.getIdentifier());
1004        }
1005    }
1006
1007    /**
1008     * Sets a new challenge PIN for restrictions. This is only for use by pre-installed
1009     * apps and requires the MANAGE_USERS permission.
1010     * @param newPin the PIN to use for challenge dialogs.
1011     * @return Returns true if the challenge PIN was set successfully.
1012     */
1013    public boolean setRestrictionsChallenge(String newPin) {
1014        try {
1015            return mService.setRestrictionsChallenge(newPin);
1016        } catch (RemoteException re) {
1017            Log.w(TAG, "Could not change restrictions pin");
1018        }
1019        return false;
1020    }
1021
1022    /**
1023     * @hide
1024     * @param pin The PIN to verify, or null to get the number of milliseconds to wait for before
1025     * allowing the user to enter the PIN.
1026     * @return Returns a positive number (including zero) for how many milliseconds before
1027     * you can accept another PIN, when the input is null or the input doesn't match the saved PIN.
1028     * Returns {@link #PIN_VERIFICATION_SUCCESS} if the input matches the saved PIN. Returns
1029     * {@link #PIN_VERIFICATION_FAILED_NOT_SET} if there is no PIN set.
1030     */
1031    public int checkRestrictionsChallenge(String pin) {
1032        try {
1033            return mService.checkRestrictionsChallenge(pin);
1034        } catch (RemoteException re) {
1035            Log.w(TAG, "Could not check restrictions pin");
1036        }
1037        return PIN_VERIFICATION_FAILED_INCORRECT;
1038    }
1039
1040    /**
1041     * @hide
1042     * Checks whether the user has restrictions that are PIN-protected. An application that
1043     * participates in restrictions can check if the owner has requested a PIN challenge for
1044     * any restricted operations. If there is a PIN in effect, the application should launch
1045     * the PIN challenge activity {@link android.content.Intent#ACTION_RESTRICTIONS_CHALLENGE}.
1046     * @see android.content.Intent#ACTION_RESTRICTIONS_CHALLENGE
1047     * @return whether a restrictions PIN is in effect.
1048     */
1049    public boolean hasRestrictionsChallenge() {
1050        try {
1051            return mService.hasRestrictionsChallenge();
1052        } catch (RemoteException re) {
1053            Log.w(TAG, "Could not change restrictions pin");
1054        }
1055        return false;
1056    }
1057
1058    /** @hide */
1059    public void removeRestrictions() {
1060        try {
1061            mService.removeRestrictions();
1062        } catch (RemoteException re) {
1063            Log.w(TAG, "Could not change restrictions pin");
1064        }
1065    }
1066
1067    /**
1068     * @hide
1069     * Set restrictions that should apply to any future guest user that's created.
1070     */
1071    public void setDefaultGuestRestrictions(Bundle restrictions) {
1072        try {
1073            mService.setDefaultGuestRestrictions(restrictions);
1074        } catch (RemoteException re) {
1075            Log.w(TAG, "Could not set guest restrictions");
1076        }
1077    }
1078
1079    /**
1080     * @hide
1081     * Gets the default guest restrictions.
1082     */
1083    public Bundle getDefaultGuestRestrictions() {
1084        try {
1085            return mService.getDefaultGuestRestrictions();
1086        } catch (RemoteException re) {
1087            Log.w(TAG, "Could not set guest restrictions");
1088        }
1089        return new Bundle();
1090    }
1091}
1092