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