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