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