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 final public String tag; 169 final public int label; 170 final public int description; 171 172 public PolicyInfo(int identIn, String tagIn, int labelIn, int descriptionIn) { 173 ident = identIn; 174 tag = tagIn; 175 label = labelIn; 176 description = descriptionIn; 177 } 178 } 179 180 static ArrayList<PolicyInfo> sPoliciesDisplayOrder = new ArrayList<PolicyInfo>(); 181 static HashMap<String, Integer> sKnownPolicies = new HashMap<String, Integer>(); 182 static SparseArray<PolicyInfo> sRevKnownPolicies = new SparseArray<PolicyInfo>(); 183 184 static { 185 sPoliciesDisplayOrder.add(new PolicyInfo(USES_POLICY_WIPE_DATA, "wipe-data", 186 com.android.internal.R.string.policylab_wipeData, 187 com.android.internal.R.string.policydesc_wipeData)); 188 sPoliciesDisplayOrder.add(new PolicyInfo(USES_POLICY_RESET_PASSWORD, "reset-password", 189 com.android.internal.R.string.policylab_resetPassword, 190 com.android.internal.R.string.policydesc_resetPassword)); 191 sPoliciesDisplayOrder.add(new PolicyInfo(USES_POLICY_LIMIT_PASSWORD, "limit-password", 192 com.android.internal.R.string.policylab_limitPassword, 193 com.android.internal.R.string.policydesc_limitPassword)); 194 sPoliciesDisplayOrder.add(new PolicyInfo(USES_POLICY_WATCH_LOGIN, "watch-login", 195 com.android.internal.R.string.policylab_watchLogin, 196 com.android.internal.R.string.policydesc_watchLogin)); 197 sPoliciesDisplayOrder.add(new PolicyInfo(USES_POLICY_FORCE_LOCK, "force-lock", 198 com.android.internal.R.string.policylab_forceLock, 199 com.android.internal.R.string.policydesc_forceLock)); 200 sPoliciesDisplayOrder.add(new PolicyInfo(USES_POLICY_SETS_GLOBAL_PROXY, "set-global-proxy", 201 com.android.internal.R.string.policylab_setGlobalProxy, 202 com.android.internal.R.string.policydesc_setGlobalProxy)); 203 sPoliciesDisplayOrder.add(new PolicyInfo(USES_POLICY_EXPIRE_PASSWORD, "expire-password", 204 com.android.internal.R.string.policylab_expirePassword, 205 com.android.internal.R.string.policydesc_expirePassword)); 206 sPoliciesDisplayOrder.add(new PolicyInfo(USES_ENCRYPTED_STORAGE, "encrypted-storage", 207 com.android.internal.R.string.policylab_encryptedStorage, 208 com.android.internal.R.string.policydesc_encryptedStorage)); 209 sPoliciesDisplayOrder.add(new PolicyInfo(USES_POLICY_DISABLE_CAMERA, "disable-camera", 210 com.android.internal.R.string.policylab_disableCamera, 211 com.android.internal.R.string.policydesc_disableCamera)); 212 sPoliciesDisplayOrder.add(new PolicyInfo( 213 USES_POLICY_DISABLE_KEYGUARD_FEATURES, "disable-keyguard-features", 214 com.android.internal.R.string.policylab_disableKeyguardFeatures, 215 com.android.internal.R.string.policydesc_disableKeyguardFeatures)); 216 217 for (int i=0; i<sPoliciesDisplayOrder.size(); i++) { 218 PolicyInfo pi = sPoliciesDisplayOrder.get(i); 219 sRevKnownPolicies.put(pi.ident, pi); 220 sKnownPolicies.put(pi.tag, pi.ident); 221 } 222 } 223 224 /** 225 * The BroadcastReceiver that implements this device admin component. 226 */ 227 final ResolveInfo mReceiver; 228 229 /** 230 * Whether this should be visible to the user. 231 */ 232 boolean mVisible; 233 234 /** 235 * The policies this administrator needs access to. 236 */ 237 int mUsesPolicies; 238 239 /** 240 * Constructor. 241 * 242 * @param context The Context in which we are parsing the device admin. 243 * @param receiver The ResolveInfo returned from the package manager about 244 * this device admin's component. 245 */ 246 public DeviceAdminInfo(Context context, ResolveInfo receiver) 247 throws XmlPullParserException, IOException { 248 mReceiver = receiver; 249 ActivityInfo ai = receiver.activityInfo; 250 251 PackageManager pm = context.getPackageManager(); 252 253 XmlResourceParser parser = null; 254 try { 255 parser = ai.loadXmlMetaData(pm, DeviceAdminReceiver.DEVICE_ADMIN_META_DATA); 256 if (parser == null) { 257 throw new XmlPullParserException("No " 258 + DeviceAdminReceiver.DEVICE_ADMIN_META_DATA + " meta-data"); 259 } 260 261 Resources res = pm.getResourcesForApplication(ai.applicationInfo); 262 263 AttributeSet attrs = Xml.asAttributeSet(parser); 264 265 int type; 266 while ((type=parser.next()) != XmlPullParser.END_DOCUMENT 267 && type != XmlPullParser.START_TAG) { 268 } 269 270 String nodeName = parser.getName(); 271 if (!"device-admin".equals(nodeName)) { 272 throw new XmlPullParserException( 273 "Meta-data does not start with device-admin tag"); 274 } 275 276 TypedArray sa = res.obtainAttributes(attrs, 277 com.android.internal.R.styleable.DeviceAdmin); 278 279 mVisible = sa.getBoolean( 280 com.android.internal.R.styleable.DeviceAdmin_visible, true); 281 282 sa.recycle(); 283 284 int outerDepth = parser.getDepth(); 285 while ((type=parser.next()) != XmlPullParser.END_DOCUMENT 286 && (type != XmlPullParser.END_TAG || parser.getDepth() > outerDepth)) { 287 if (type == XmlPullParser.END_TAG || type == XmlPullParser.TEXT) { 288 continue; 289 } 290 String tagName = parser.getName(); 291 if (tagName.equals("uses-policies")) { 292 int innerDepth = parser.getDepth(); 293 while ((type=parser.next()) != XmlPullParser.END_DOCUMENT 294 && (type != XmlPullParser.END_TAG || parser.getDepth() > innerDepth)) { 295 if (type == XmlPullParser.END_TAG || type == XmlPullParser.TEXT) { 296 continue; 297 } 298 String policyName = parser.getName(); 299 Integer val = sKnownPolicies.get(policyName); 300 if (val != null) { 301 mUsesPolicies |= 1 << val.intValue(); 302 } else { 303 Log.w(TAG, "Unknown tag under uses-policies of " 304 + getComponent() + ": " + policyName); 305 } 306 } 307 } 308 } 309 } catch (NameNotFoundException e) { 310 throw new XmlPullParserException( 311 "Unable to create context for: " + ai.packageName); 312 } finally { 313 if (parser != null) parser.close(); 314 } 315 } 316 317 DeviceAdminInfo(Parcel source) { 318 mReceiver = ResolveInfo.CREATOR.createFromParcel(source); 319 mUsesPolicies = source.readInt(); 320 } 321 322 /** 323 * Return the .apk package that implements this device admin. 324 */ 325 public String getPackageName() { 326 return mReceiver.activityInfo.packageName; 327 } 328 329 /** 330 * Return the class name of the receiver component that implements 331 * this device admin. 332 */ 333 public String getReceiverName() { 334 return mReceiver.activityInfo.name; 335 } 336 337 /** 338 * Return the raw information about the receiver implementing this 339 * device admin. Do not modify the returned object. 340 */ 341 public ActivityInfo getActivityInfo() { 342 return mReceiver.activityInfo; 343 } 344 345 /** 346 * Return the component of the receiver that implements this device admin. 347 */ 348 public ComponentName getComponent() { 349 return new ComponentName(mReceiver.activityInfo.packageName, 350 mReceiver.activityInfo.name); 351 } 352 353 /** 354 * Load the user-displayed label for this device admin. 355 * 356 * @param pm Supply a PackageManager used to load the device admin's 357 * resources. 358 */ 359 public CharSequence loadLabel(PackageManager pm) { 360 return mReceiver.loadLabel(pm); 361 } 362 363 /** 364 * Load user-visible description associated with this device admin. 365 * 366 * @param pm Supply a PackageManager used to load the device admin's 367 * resources. 368 */ 369 public CharSequence loadDescription(PackageManager pm) throws NotFoundException { 370 if (mReceiver.activityInfo.descriptionRes != 0) { 371 String packageName = mReceiver.resolvePackageName; 372 ApplicationInfo applicationInfo = null; 373 if (packageName == null) { 374 packageName = mReceiver.activityInfo.packageName; 375 applicationInfo = mReceiver.activityInfo.applicationInfo; 376 } 377 return pm.getText(packageName, 378 mReceiver.activityInfo.descriptionRes, applicationInfo); 379 } 380 throw new NotFoundException(); 381 } 382 383 /** 384 * Load the user-displayed icon for this device admin. 385 * 386 * @param pm Supply a PackageManager used to load the device admin's 387 * resources. 388 */ 389 public Drawable loadIcon(PackageManager pm) { 390 return mReceiver.loadIcon(pm); 391 } 392 393 /** 394 * Returns whether this device admin would like to be visible to the 395 * user, even when it is not enabled. 396 */ 397 public boolean isVisible() { 398 return mVisible; 399 } 400 401 /** 402 * Return true if the device admin has requested that it be able to use 403 * the given policy control. The possible policy identifier inputs are: 404 * {@link #USES_POLICY_LIMIT_PASSWORD}, {@link #USES_POLICY_WATCH_LOGIN}, 405 * {@link #USES_POLICY_RESET_PASSWORD}, {@link #USES_POLICY_FORCE_LOCK}, 406 * {@link #USES_POLICY_WIPE_DATA}, 407 * {@link #USES_POLICY_EXPIRE_PASSWORD}, {@link #USES_ENCRYPTED_STORAGE}, 408 * {@link #USES_POLICY_DISABLE_CAMERA}. 409 */ 410 public boolean usesPolicy(int policyIdent) { 411 return (mUsesPolicies & (1<<policyIdent)) != 0; 412 } 413 414 /** 415 * Return the XML tag name for the given policy identifier. Valid identifiers 416 * are as per {@link #usesPolicy(int)}. If the given identifier is not 417 * known, null is returned. 418 */ 419 public String getTagForPolicy(int policyIdent) { 420 return sRevKnownPolicies.get(policyIdent).tag; 421 } 422 423 /** @hide */ 424 public ArrayList<PolicyInfo> getUsedPolicies() { 425 ArrayList<PolicyInfo> res = new ArrayList<PolicyInfo>(); 426 for (int i=0; i<sPoliciesDisplayOrder.size(); i++) { 427 PolicyInfo pi = sPoliciesDisplayOrder.get(i); 428 if (usesPolicy(pi.ident)) { 429 res.add(pi); 430 } 431 } 432 return res; 433 } 434 435 /** @hide */ 436 public void writePoliciesToXml(XmlSerializer out) 437 throws IllegalArgumentException, IllegalStateException, IOException { 438 out.attribute(null, "flags", Integer.toString(mUsesPolicies)); 439 } 440 441 /** @hide */ 442 public void readPoliciesFromXml(XmlPullParser parser) 443 throws XmlPullParserException, IOException { 444 mUsesPolicies = Integer.parseInt( 445 parser.getAttributeValue(null, "flags")); 446 } 447 448 public void dump(Printer pw, String prefix) { 449 pw.println(prefix + "Receiver:"); 450 mReceiver.dump(pw, prefix + " "); 451 } 452 453 @Override 454 public String toString() { 455 return "DeviceAdminInfo{" + mReceiver.activityInfo.name + "}"; 456 } 457 458 /** 459 * Used to package this object into a {@link Parcel}. 460 * 461 * @param dest The {@link Parcel} to be written. 462 * @param flags The flags used for parceling. 463 */ 464 public void writeToParcel(Parcel dest, int flags) { 465 mReceiver.writeToParcel(dest, flags); 466 dest.writeInt(mUsesPolicies); 467 } 468 469 /** 470 * Used to make this class parcelable. 471 */ 472 public static final Parcelable.Creator<DeviceAdminInfo> CREATOR = 473 new Parcelable.Creator<DeviceAdminInfo>() { 474 public DeviceAdminInfo createFromParcel(Parcel source) { 475 return new DeviceAdminInfo(source); 476 } 477 478 public DeviceAdminInfo[] newArray(int size) { 479 return new DeviceAdminInfo[size]; 480 } 481 }; 482 483 public int describeContents() { 484 return 0; 485 } 486} 487