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