• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (C) 2010 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.app.admin;
18 
19 import android.annotation.IntDef;
20 import android.annotation.NonNull;
21 import android.compat.annotation.UnsupportedAppUsage;
22 import android.content.ComponentName;
23 import android.content.Context;
24 import android.content.pm.ActivityInfo;
25 import android.content.pm.PackageManager;
26 import android.content.pm.PackageManager.NameNotFoundException;
27 import android.content.pm.ResolveInfo;
28 import android.content.res.Resources;
29 import android.content.res.Resources.NotFoundException;
30 import android.content.res.TypedArray;
31 import android.content.res.XmlResourceParser;
32 import android.graphics.drawable.Drawable;
33 import android.os.Build;
34 import android.os.Parcel;
35 import android.os.Parcelable;
36 import android.os.PersistableBundle;
37 import android.util.AttributeSet;
38 import android.util.Log;
39 import android.util.Printer;
40 import android.util.SparseArray;
41 import android.util.Xml;
42 
43 import com.android.modules.utils.TypedXmlPullParser;
44 import com.android.modules.utils.TypedXmlSerializer;
45 
46 import org.xmlpull.v1.XmlPullParser;
47 import org.xmlpull.v1.XmlPullParserException;
48 
49 import java.io.IOException;
50 import java.lang.annotation.Retention;
51 import java.lang.annotation.RetentionPolicy;
52 import java.util.ArrayList;
53 import java.util.HashMap;
54 
55 /**
56  * This class is used to specify meta information of a device administrator
57  * component.
58  */
59 public final class DeviceAdminInfo implements Parcelable {
60     static final String TAG = "DeviceAdminInfo";
61 
62     /**
63      * A type of policy that this device admin can use: limit the passwords
64      * that the user can select, via {@link DevicePolicyManager#setPasswordQuality}
65      * and {@link DevicePolicyManager#setPasswordMinimumLength}.
66      *
67      * <p>To control this policy, the device admin must be a device owner or profile owner,
68      * and must have a "limit-password" tag in the "uses-policies" section of its meta-data.
69      * If used by a device owner, the policy only affects the primary user and its profiles,
70      * but not any secondary users on the device.
71      */
72     public static final int USES_POLICY_LIMIT_PASSWORD = 0;
73 
74     /**
75      * A type of policy that this device admin can use: able to watch login
76      * attempts from the user, via {@link DeviceAdminReceiver#ACTION_PASSWORD_FAILED},
77      * {@link DeviceAdminReceiver#ACTION_PASSWORD_SUCCEEDED}, and
78      * {@link DevicePolicyManager#getCurrentFailedPasswordAttempts}.
79      *
80      * <p>To control this policy, the device admin must have a "watch-login"
81      * tag in the "uses-policies" section of its meta-data.
82      */
83     public static final int USES_POLICY_WATCH_LOGIN = 1;
84 
85     /**
86      * A type of policy that this device admin can use: able to reset the
87      * user's password via
88      * {@link DevicePolicyManager#resetPassword}.
89      *
90      * <p>To control this policy, the device admin must have a "reset-password"
91      * tag in the "uses-policies" section of its meta-data.
92      */
93     public static final int USES_POLICY_RESET_PASSWORD = 2;
94 
95     /**
96      * A type of policy that this device admin can use: able to force the device
97      * to lock via{@link DevicePolicyManager#lockNow} or limit the
98      * maximum lock timeout for the device via
99      * {@link DevicePolicyManager#setMaximumTimeToLock}.
100      *
101      * <p>To control this policy, the device admin must have a "force-lock"
102      * tag in the "uses-policies" section of its meta-data.
103      */
104     public static final int USES_POLICY_FORCE_LOCK = 3;
105 
106     /**
107      * A type of policy that this device admin can use: able to factory
108      * reset the device, erasing all of the user's data, via
109      * {@link DevicePolicyManager#wipeData}.
110      *
111      * <p>To control this policy, the device admin must have a "wipe-data"
112      * tag in the "uses-policies" section of its meta-data.
113      */
114     public static final int USES_POLICY_WIPE_DATA = 4;
115 
116     /**
117      * A type of policy that this device admin can use: able to specify the
118      * device Global Proxy, via {@link DevicePolicyManager#setGlobalProxy}.
119      *
120      * <p>To control this policy, the device admin must have a "set-global-proxy"
121      * tag in the "uses-policies" section of its meta-data.
122      * @hide
123      */
124     public static final int USES_POLICY_SETS_GLOBAL_PROXY = 5;
125 
126     /**
127      * A type of policy that this device admin can use: force the user to
128      * change their password after an administrator-defined time limit.
129      *
130      * <p>To control this policy, the device admin must be a device owner or profile owner,
131      * and must have an "expire-password" tag in the "uses-policies" section of its meta-data.
132      * If used by a device owner, the policy only affects the primary user and its profiles,
133      * but not any secondary users on the device.
134      */
135     public static final int USES_POLICY_EXPIRE_PASSWORD = 6;
136 
137     /**
138      * A type of policy that this device admin can use: require encryption of stored data.
139      *
140      * <p>To control this policy, the device admin must have a "encrypted-storage"
141      * tag in the "uses-policies" section of its meta-data.
142      */
143     public static final int USES_ENCRYPTED_STORAGE = 7;
144 
145     /**
146      * A type of policy that this device admin can use: disables use of all device cameras.
147      *
148      * <p>To control this policy, the device admin must be a device owner or profile owner,
149      * and must have a "disable-camera" tag in the "uses-policies" section of its meta-data.
150      * If used by a device owner, the policy affects all users on the device.
151      */
152     public static final int USES_POLICY_DISABLE_CAMERA = 8;
153 
154     /**
155      * A type of policy that this device admin can use: disables use of keyguard features.
156      *
157      * <p>To control this policy, the device admin must be a device owner or profile owner,
158      * and must have a "disable-keyguard-features" tag in the "uses-policies" section of its
159      * meta-data.  If used by a device owner, the policy only affects the primary user and
160      * its profiles, but not any secondary users on the device.
161      */
162     public static final int USES_POLICY_DISABLE_KEYGUARD_FEATURES = 9;
163 
164 
165     /**
166      * Value for {@link #getHeadlessDeviceOwnerMode} which indicates that this DPC should not
167      * be provisioned into Device Owner mode on a Headless System User Mode device.
168      */
169     public static final int HEADLESS_DEVICE_OWNER_MODE_UNSUPPORTED = 0;
170 
171     /**
172      * Value for {@link #getHeadlessDeviceOwnerMode} which indicates that this DPC should be
173      * provisioned into "affiliated" mode when on a Headless System User Mode device.
174      *
175      * <p>This mode adds a Profile Owner to all users other than the user the Device Owner is on.
176      *
177      * <p>Starting from Android version {@link android.os.Build.VERSION_CODES#VANILLA_ICE_CREAM},
178      * DPCs should set the value of attribute "headless-device-owner-mode" inside the
179      * "headless-system-user" tag as "affiliated".
180      */
181     public static final int HEADLESS_DEVICE_OWNER_MODE_AFFILIATED = 1;
182 
183     /**
184      * Value for {@link #getHeadlessDeviceOwnerMode} which indicates that this DPC should be
185      * provisioned into the first secondary user when on a Headless System User Mode device.
186      *
187      * <p>This mode only allows a single secondary user on the device blocking the creation of
188      * additional secondary users.
189      *
190      * <p>Starting from Android version {@link android.os.Build.VERSION_CODES#VANILLA_ICE_CREAM},
191      * DPCs should set the value of attribute "headless-device-owner-mode" inside the
192      * "headless-system-user" tag as "single_user".
193      */
194     public static final int HEADLESS_DEVICE_OWNER_MODE_SINGLE_USER = 2;
195 
196     /**
197      * @hide
198      */
199     @IntDef({HEADLESS_DEVICE_OWNER_MODE_UNSUPPORTED, HEADLESS_DEVICE_OWNER_MODE_AFFILIATED,
200             HEADLESS_DEVICE_OWNER_MODE_SINGLE_USER})
201     @Retention(RetentionPolicy.SOURCE)
202     public @interface HeadlessDeviceOwnerMode {}
203 
204     /** @hide */
205     public static class PolicyInfo {
206         public final int ident;
207         @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.P, trackingBug = 115609023)
208         public final String tag;
209         public final int label;
210         public final int description;
211         public final int labelForSecondaryUsers;
212         public final int descriptionForSecondaryUsers;
213 
PolicyInfo(int ident, String tag, int label, int description)214         public PolicyInfo(int ident, String tag, int label, int description) {
215             this(ident, tag, label, description, label, description);
216         }
217 
PolicyInfo(int ident, String tag, int label, int description, int labelForSecondaryUsers, int descriptionForSecondaryUsers)218         public PolicyInfo(int ident, String tag, int label, int description,
219                 int labelForSecondaryUsers, int descriptionForSecondaryUsers) {
220             this.ident = ident;
221             this.tag = tag;
222             this.label = label;
223             this.description = description;
224             this.labelForSecondaryUsers = labelForSecondaryUsers;
225             this.descriptionForSecondaryUsers = descriptionForSecondaryUsers;
226         }
227     }
228 
229     static ArrayList<PolicyInfo> sPoliciesDisplayOrder = new ArrayList<PolicyInfo>();
230     static HashMap<String, Integer> sKnownPolicies = new HashMap<String, Integer>();
231     static SparseArray<PolicyInfo> sRevKnownPolicies = new SparseArray<PolicyInfo>();
232 
233     static {
sPoliciesDisplayOrder.add(new PolicyInfo(USES_POLICY_WIPE_DATA, "wipe-data", com.android.internal.R.string.policylab_wipeData, com.android.internal.R.string.policydesc_wipeData, com.android.internal.R.string.policylab_wipeData_secondaryUser, com.android.internal.R.string.policydesc_wipeData_secondaryUser ))234         sPoliciesDisplayOrder.add(new PolicyInfo(USES_POLICY_WIPE_DATA, "wipe-data",
235                 com.android.internal.R.string.policylab_wipeData,
236                 com.android.internal.R.string.policydesc_wipeData,
237                 com.android.internal.R.string.policylab_wipeData_secondaryUser,
238                 com.android.internal.R.string.policydesc_wipeData_secondaryUser
239                 ));
sPoliciesDisplayOrder.add(new PolicyInfo(USES_POLICY_RESET_PASSWORD, "reset-password", com.android.internal.R.string.policylab_resetPassword, com.android.internal.R.string.policydesc_resetPassword))240         sPoliciesDisplayOrder.add(new PolicyInfo(USES_POLICY_RESET_PASSWORD, "reset-password",
241                 com.android.internal.R.string.policylab_resetPassword,
242                 com.android.internal.R.string.policydesc_resetPassword));
sPoliciesDisplayOrder.add(new PolicyInfo(USES_POLICY_LIMIT_PASSWORD, "limit-password", com.android.internal.R.string.policylab_limitPassword, com.android.internal.R.string.policydesc_limitPassword))243         sPoliciesDisplayOrder.add(new PolicyInfo(USES_POLICY_LIMIT_PASSWORD, "limit-password",
244                 com.android.internal.R.string.policylab_limitPassword,
245                 com.android.internal.R.string.policydesc_limitPassword));
sPoliciesDisplayOrder.add(new PolicyInfo(USES_POLICY_WATCH_LOGIN, "watch-login", com.android.internal.R.string.policylab_watchLogin, com.android.internal.R.string.policydesc_watchLogin, com.android.internal.R.string.policylab_watchLogin, com.android.internal.R.string.policydesc_watchLogin_secondaryUser ))246         sPoliciesDisplayOrder.add(new PolicyInfo(USES_POLICY_WATCH_LOGIN, "watch-login",
247                 com.android.internal.R.string.policylab_watchLogin,
248                 com.android.internal.R.string.policydesc_watchLogin,
249                 com.android.internal.R.string.policylab_watchLogin,
250                 com.android.internal.R.string.policydesc_watchLogin_secondaryUser
251         ));
sPoliciesDisplayOrder.add(new PolicyInfo(USES_POLICY_FORCE_LOCK, "force-lock", com.android.internal.R.string.policylab_forceLock, com.android.internal.R.string.policydesc_forceLock))252         sPoliciesDisplayOrder.add(new PolicyInfo(USES_POLICY_FORCE_LOCK, "force-lock",
253                 com.android.internal.R.string.policylab_forceLock,
254                 com.android.internal.R.string.policydesc_forceLock));
sPoliciesDisplayOrder.add(new PolicyInfo(USES_POLICY_SETS_GLOBAL_PROXY, "set-global-proxy", com.android.internal.R.string.policylab_setGlobalProxy, com.android.internal.R.string.policydesc_setGlobalProxy))255         sPoliciesDisplayOrder.add(new PolicyInfo(USES_POLICY_SETS_GLOBAL_PROXY, "set-global-proxy",
256                 com.android.internal.R.string.policylab_setGlobalProxy,
257                 com.android.internal.R.string.policydesc_setGlobalProxy));
sPoliciesDisplayOrder.add(new PolicyInfo(USES_POLICY_EXPIRE_PASSWORD, "expire-password", com.android.internal.R.string.policylab_expirePassword, com.android.internal.R.string.policydesc_expirePassword))258         sPoliciesDisplayOrder.add(new PolicyInfo(USES_POLICY_EXPIRE_PASSWORD, "expire-password",
259                 com.android.internal.R.string.policylab_expirePassword,
260                 com.android.internal.R.string.policydesc_expirePassword));
sPoliciesDisplayOrder.add(new PolicyInfo(USES_ENCRYPTED_STORAGE, "encrypted-storage", com.android.internal.R.string.policylab_encryptedStorage, com.android.internal.R.string.policydesc_encryptedStorage))261         sPoliciesDisplayOrder.add(new PolicyInfo(USES_ENCRYPTED_STORAGE, "encrypted-storage",
262                 com.android.internal.R.string.policylab_encryptedStorage,
263                 com.android.internal.R.string.policydesc_encryptedStorage));
sPoliciesDisplayOrder.add(new PolicyInfo(USES_POLICY_DISABLE_CAMERA, "disable-camera", com.android.internal.R.string.policylab_disableCamera, com.android.internal.R.string.policydesc_disableCamera))264         sPoliciesDisplayOrder.add(new PolicyInfo(USES_POLICY_DISABLE_CAMERA, "disable-camera",
265                 com.android.internal.R.string.policylab_disableCamera,
266                 com.android.internal.R.string.policydesc_disableCamera));
sPoliciesDisplayOrder.add(new PolicyInfo( USES_POLICY_DISABLE_KEYGUARD_FEATURES, "disable-keyguard-features", com.android.internal.R.string.policylab_disableKeyguardFeatures, com.android.internal.R.string.policydesc_disableKeyguardFeatures))267         sPoliciesDisplayOrder.add(new PolicyInfo(
268                 USES_POLICY_DISABLE_KEYGUARD_FEATURES, "disable-keyguard-features",
269                 com.android.internal.R.string.policylab_disableKeyguardFeatures,
270                 com.android.internal.R.string.policydesc_disableKeyguardFeatures));
271 
272         for (int i=0; i<sPoliciesDisplayOrder.size(); i++) {
273             PolicyInfo pi = sPoliciesDisplayOrder.get(i);
sRevKnownPolicies.put(pi.ident, pi)274             sRevKnownPolicies.put(pi.ident, pi);
sKnownPolicies.put(pi.tag, pi.ident)275             sKnownPolicies.put(pi.tag, pi.ident);
276         }
277     }
278 
279     /**
280      * The BroadcastReceiver that implements this device admin component.
281      */
282     final ActivityInfo mActivityInfo;
283 
284     /**
285      * Whether this should be visible to the user.
286      */
287     boolean mVisible;
288 
289     /**
290      * The policies this administrator needs access to.
291      */
292     int mUsesPolicies;
293 
294     /**
295      * Whether this administrator can be a target in an ownership transfer.
296      *
297      * @see DevicePolicyManager#transferOwnership(ComponentName, ComponentName, PersistableBundle)
298      */
299     boolean mSupportsTransferOwnership;
300 
301     @HeadlessDeviceOwnerMode int mHeadlessDeviceOwnerMode = HEADLESS_DEVICE_OWNER_MODE_UNSUPPORTED;
302 
303     /**
304      * Constructor.
305      *
306      * @param context The Context in which we are parsing the device admin.
307      * @param resolveInfo The ResolveInfo returned from the package manager about
308      * this device admin's component.
309      */
DeviceAdminInfo(Context context, ResolveInfo resolveInfo)310     public DeviceAdminInfo(Context context, ResolveInfo resolveInfo)
311             throws XmlPullParserException, IOException {
312         this(context, resolveInfo.activityInfo);
313     }
314     /**
315      * Constructor.
316      *
317      * @param context The Context in which we are parsing the device admin.
318      * @param activityInfo The ActivityInfo returned from the package manager about
319      * this device admin's component.
320      *
321      * @hide
322      */
DeviceAdminInfo(Context context, ActivityInfo activityInfo)323     public DeviceAdminInfo(Context context, ActivityInfo activityInfo)
324             throws XmlPullParserException, IOException {
325         mActivityInfo = activityInfo;
326 
327         PackageManager pm = context.getPackageManager();
328 
329         XmlResourceParser parser = null;
330         try {
331             parser = mActivityInfo.loadXmlMetaData(pm, DeviceAdminReceiver.DEVICE_ADMIN_META_DATA);
332             if (parser == null) {
333                 throw new XmlPullParserException("No "
334                         + DeviceAdminReceiver.DEVICE_ADMIN_META_DATA + " meta-data");
335             }
336 
337             Resources res = pm.getResourcesForApplication(mActivityInfo.applicationInfo);
338 
339             AttributeSet attrs = Xml.asAttributeSet(parser);
340 
341             int type;
342             while ((type=parser.next()) != XmlPullParser.END_DOCUMENT
343                     && type != XmlPullParser.START_TAG) {
344             }
345 
346             String nodeName = parser.getName();
347             if (!"device-admin".equals(nodeName)) {
348                 throw new XmlPullParserException(
349                         "Meta-data does not start with device-admin tag");
350             }
351 
352             TypedArray sa = res.obtainAttributes(attrs,
353                     com.android.internal.R.styleable.DeviceAdmin);
354 
355             mVisible = sa.getBoolean(
356                     com.android.internal.R.styleable.DeviceAdmin_visible, true);
357 
358             sa.recycle();
359 
360             int outerDepth = parser.getDepth();
361             while ((type=parser.next()) != XmlPullParser.END_DOCUMENT
362                    && (type != XmlPullParser.END_TAG || parser.getDepth() > outerDepth)) {
363                 if (type == XmlPullParser.END_TAG || type == XmlPullParser.TEXT) {
364                     continue;
365                 }
366                 String tagName = parser.getName();
367                 if (tagName.equals("uses-policies")) {
368                     int innerDepth = parser.getDepth();
369                     while ((type=parser.next()) != XmlPullParser.END_DOCUMENT
370                            && (type != XmlPullParser.END_TAG || parser.getDepth() > innerDepth)) {
371                         if (type == XmlPullParser.END_TAG || type == XmlPullParser.TEXT) {
372                             continue;
373                         }
374                         String policyName = parser.getName();
375                         Integer val = sKnownPolicies.get(policyName);
376                         if (val != null) {
377                             mUsesPolicies |= 1 << val.intValue();
378                         } else {
379                             Log.w(TAG, "Unknown tag under uses-policies of "
380                                     + getComponent() + ": " + policyName);
381                         }
382                     }
383                 } else if (tagName.equals("support-transfer-ownership")) {
384                     if (parser.next() != XmlPullParser.END_TAG) {
385                         throw new XmlPullParserException(
386                                 "support-transfer-ownership tag must be empty.");
387                     }
388                     mSupportsTransferOwnership = true;
389                 } else if (tagName.equals("headless-system-user")) {
390                     String deviceOwnerModeStringValue = parser.getAttributeValue(
391                             null, "headless-device-owner-mode");
392                     if (deviceOwnerModeStringValue == null) {
393                         deviceOwnerModeStringValue =
394                                 parser.getAttributeValue(null, "device-owner-mode");
395                     }
396 
397                     if ("unsupported".equalsIgnoreCase(deviceOwnerModeStringValue)) {
398                         mHeadlessDeviceOwnerMode = HEADLESS_DEVICE_OWNER_MODE_UNSUPPORTED;
399                     } else if ("affiliated".equalsIgnoreCase(deviceOwnerModeStringValue)) {
400                         mHeadlessDeviceOwnerMode = HEADLESS_DEVICE_OWNER_MODE_AFFILIATED;
401                     } else if ("single_user".equalsIgnoreCase(deviceOwnerModeStringValue)) {
402                         mHeadlessDeviceOwnerMode = HEADLESS_DEVICE_OWNER_MODE_SINGLE_USER;
403                     } else {
404                         Log.e(TAG, "Unknown headless-system-user mode: "
405                                 + deviceOwnerModeStringValue);
406                     }
407                 }
408             }
409         } catch (NameNotFoundException e) {
410             throw new XmlPullParserException(
411                     "Unable to create context for: " + mActivityInfo.packageName);
412         } finally {
413             if (parser != null) parser.close();
414         }
415     }
416 
DeviceAdminInfo(Parcel source)417     DeviceAdminInfo(Parcel source) {
418         mActivityInfo = ActivityInfo.CREATOR.createFromParcel(source);
419         mUsesPolicies = source.readInt();
420         mSupportsTransferOwnership = source.readBoolean();
421         mHeadlessDeviceOwnerMode = source.readInt();
422     }
423 
424     /**
425      * Return the .apk package that implements this device admin.
426      */
getPackageName()427     public String getPackageName() {
428         return mActivityInfo.packageName;
429     }
430 
431     /**
432      * Return the class name of the receiver component that implements
433      * this device admin.
434      */
getReceiverName()435     public String getReceiverName() {
436         return mActivityInfo.name;
437     }
438 
439     /**
440      * Return the raw information about the receiver implementing this
441      * device admin.  Do not modify the returned object.
442      */
getActivityInfo()443     public ActivityInfo getActivityInfo() {
444         return mActivityInfo;
445     }
446 
447     /**
448      * Return the component of the receiver that implements this device admin.
449      */
450     @NonNull
getComponent()451     public ComponentName getComponent() {
452         return new ComponentName(mActivityInfo.packageName,
453                 mActivityInfo.name);
454     }
455 
456     /**
457      * Load the user-displayed label for this device admin.
458      *
459      * @param pm Supply a PackageManager used to load the device admin's
460      * resources.
461      */
loadLabel(PackageManager pm)462     public CharSequence loadLabel(PackageManager pm) {
463         return mActivityInfo.loadLabel(pm);
464     }
465 
466     /**
467      * Load user-visible description associated with this device admin.
468      *
469      * @param pm Supply a PackageManager used to load the device admin's
470      * resources.
471      */
loadDescription(PackageManager pm)472     public CharSequence loadDescription(PackageManager pm) throws NotFoundException {
473         if (mActivityInfo.descriptionRes != 0) {
474             return pm.getText(mActivityInfo.packageName,
475                     mActivityInfo.descriptionRes, mActivityInfo.applicationInfo);
476         }
477         throw new NotFoundException();
478     }
479 
480     /**
481      * Load the user-displayed icon for this device admin.
482      *
483      * @param pm Supply a PackageManager used to load the device admin's
484      * resources.
485      */
loadIcon(PackageManager pm)486     public Drawable loadIcon(PackageManager pm) {
487         return mActivityInfo.loadIcon(pm);
488     }
489 
490     /**
491      * Returns whether this device admin would like to be visible to the
492      * user, even when it is not enabled.
493      */
isVisible()494     public boolean isVisible() {
495         return mVisible;
496     }
497 
498     /**
499      * Return true if the device admin has requested that it be able to use
500      * the given policy control.  The possible policy identifier inputs are:
501      * {@link #USES_POLICY_LIMIT_PASSWORD}, {@link #USES_POLICY_WATCH_LOGIN},
502      * {@link #USES_POLICY_RESET_PASSWORD}, {@link #USES_POLICY_FORCE_LOCK},
503      * {@link #USES_POLICY_WIPE_DATA},
504      * {@link #USES_POLICY_EXPIRE_PASSWORD}, {@link #USES_ENCRYPTED_STORAGE},
505      * {@link #USES_POLICY_DISABLE_CAMERA}.
506      */
usesPolicy(int policyIdent)507     public boolean usesPolicy(int policyIdent) {
508         return (mUsesPolicies & (1<<policyIdent)) != 0;
509     }
510 
511     /**
512      * Return the XML tag name for the given policy identifier.  Valid identifiers
513      * are as per {@link #usesPolicy(int)}.  If the given identifier is not
514      * known, null is returned.
515      */
getTagForPolicy(int policyIdent)516     public String getTagForPolicy(int policyIdent) {
517         return sRevKnownPolicies.get(policyIdent).tag;
518     }
519 
520     /**
521      * Return true if this administrator can be a target in an ownership transfer.
522      */
supportsTransferOwnership()523     public boolean supportsTransferOwnership() {
524         return mSupportsTransferOwnership;
525     }
526 
527     /**
528      * Returns the mode this DeviceAdmin wishes to use if provisioned as a Device Owner on a
529      * headless system user mode device.
530      */
getHeadlessDeviceOwnerMode()531     public @HeadlessDeviceOwnerMode int getHeadlessDeviceOwnerMode() {
532         return mHeadlessDeviceOwnerMode;
533     }
534 
535     /** @hide */
536     @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.R, trackingBug = 170729553)
getUsedPolicies()537     public ArrayList<PolicyInfo> getUsedPolicies() {
538         ArrayList<PolicyInfo> res = new ArrayList<PolicyInfo>();
539         for (int i=0; i<sPoliciesDisplayOrder.size(); i++) {
540             PolicyInfo pi = sPoliciesDisplayOrder.get(i);
541             if (usesPolicy(pi.ident)) {
542                 res.add(pi);
543             }
544         }
545         return res;
546     }
547 
548     /** @hide */
writePoliciesToXml(TypedXmlSerializer out)549     public void writePoliciesToXml(TypedXmlSerializer out)
550             throws IllegalArgumentException, IllegalStateException, IOException {
551         out.attributeInt(null, "flags", mUsesPolicies);
552     }
553 
554     /** @hide */
readPoliciesFromXml(TypedXmlPullParser parser)555     public void readPoliciesFromXml(TypedXmlPullParser parser)
556             throws XmlPullParserException, IOException {
557         mUsesPolicies = parser.getAttributeInt(null, "flags");
558     }
559 
dump(Printer pw, String prefix)560     public void dump(Printer pw, String prefix) {
561         pw.println("mVisible: " + mVisible);
562         pw.println("mUsesPolicies: " + mUsesPolicies);
563         pw.println("mSupportsTransferOwnership: " + mSupportsTransferOwnership);
564         pw.println("mHeadlessDeviceOwnerMode: " + mHeadlessDeviceOwnerMode);
565 
566         pw.println(prefix + "Receiver:");
567         mActivityInfo.dump(pw, prefix + "  ");
568     }
569 
570     @Override
toString()571     public String toString() {
572         return "DeviceAdminInfo{" + mActivityInfo.name + "}";
573     }
574 
575     /**
576      * Used to package this object into a {@link Parcel}.
577      *
578      * @param dest The {@link Parcel} to be written.
579      * @param flags The flags used for parceling.
580      */
writeToParcel(Parcel dest, int flags)581     public void writeToParcel(Parcel dest, int flags) {
582         mActivityInfo.writeToParcel(dest, flags);
583         dest.writeInt(mUsesPolicies);
584         dest.writeBoolean(mSupportsTransferOwnership);
585         dest.writeInt(mHeadlessDeviceOwnerMode);
586     }
587 
588     /**
589      * Used to make this class parcelable.
590      */
591     public static final @android.annotation.NonNull Parcelable.Creator<DeviceAdminInfo> CREATOR =
592             new Parcelable.Creator<DeviceAdminInfo>() {
593         public DeviceAdminInfo createFromParcel(Parcel source) {
594             return new DeviceAdminInfo(source);
595         }
596 
597         public DeviceAdminInfo[] newArray(int size) {
598             return new DeviceAdminInfo[size];
599         }
600     };
601 
describeContents()602     public int describeContents() {
603         return 0;
604     }
605 }
606