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