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