DeviceAdminInfo.java revision 69238c6a37ae43c748ad9cd7613f2209149ee7da
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: limit the passwords 56 * that the user can select, via {@link DevicePolicyManager#setPasswordQuality} 57 * and {@link DevicePolicyManager#setPasswordMinimumLength}. 58 * 59 * <p>To control this policy, the device admin must have a "limit-password" 60 * tag in the "uses-policies" section of its meta-data. 61 */ 62 public static final int USES_POLICY_LIMIT_PASSWORD = 0; 63 64 /** 65 * A type of policy that this device admin can use: able to watch login 66 * attempts from the user, via {@link DeviceAdminReceiver#ACTION_PASSWORD_FAILED}, 67 * {@link DeviceAdminReceiver#ACTION_PASSWORD_SUCCEEDED}, and 68 * {@link DevicePolicyManager#getCurrentFailedPasswordAttempts}. 69 * 70 * <p>To control this policy, the device admin must have a "watch-login" 71 * tag in the "uses-policies" section of its meta-data. 72 */ 73 public static final int USES_POLICY_WATCH_LOGIN = 1; 74 75 /** 76 * A type of policy that this device admin can use: able to reset the 77 * user's password via 78 * {@link DevicePolicyManager#resetPassword}. 79 * 80 * <p>To control this policy, the device admin must have a "reset-password" 81 * tag in the "uses-policies" section of its meta-data. 82 */ 83 public static final int USES_POLICY_RESET_PASSWORD = 2; 84 85 /** 86 * A type of policy that this device admin can use: able to force the device 87 * to lock via{@link DevicePolicyManager#lockNow} or limit the 88 * maximum lock timeout for the device via 89 * {@link DevicePolicyManager#setMaximumTimeToLock}. 90 * 91 * <p>To control this policy, the device admin must have a "force-lock" 92 * tag in the "uses-policies" section of its meta-data. 93 */ 94 public static final int USES_POLICY_FORCE_LOCK = 3; 95 96 /** 97 * A type of policy that this device admin can use: able to factory 98 * reset the device, erasing all of the user's data, via 99 * {@link DevicePolicyManager#wipeData}. 100 * 101 * <p>To control this policy, the device admin must have a "wipe-data" 102 * tag in the "uses-policies" section of its meta-data. 103 */ 104 public static final int USES_POLICY_WIPE_DATA = 4; 105 106 /** 107 * A type of policy that this device admin can use: able to specify the 108 * device Global Proxy, via {@link DevicePolicyManager#setGlobalProxy}. 109 * 110 * <p>To control this policy, the device admin must have a "set-global-proxy" 111 * tag in the "uses-policies" section of its meta-data. 112 * @hide 113 */ 114 public static final int USES_POLICY_SETS_GLOBAL_PROXY = 5; 115 116 /** @hide */ 117 public static class PolicyInfo { 118 public final int ident; 119 final public String tag; 120 final public int label; 121 final public int description; 122 123 public PolicyInfo(int identIn, String tagIn, int labelIn, int descriptionIn) { 124 ident = identIn; 125 tag = tagIn; 126 label = labelIn; 127 description = descriptionIn; 128 } 129 } 130 131 static ArrayList<PolicyInfo> sPoliciesDisplayOrder = new ArrayList<PolicyInfo>(); 132 static HashMap<String, Integer> sKnownPolicies = new HashMap<String, Integer>(); 133 static SparseArray<PolicyInfo> sRevKnownPolicies = new SparseArray<PolicyInfo>(); 134 135 static { 136 sPoliciesDisplayOrder.add(new PolicyInfo(USES_POLICY_WIPE_DATA, "wipe-data", 137 com.android.internal.R.string.policylab_wipeData, 138 com.android.internal.R.string.policydesc_wipeData)); 139 sPoliciesDisplayOrder.add(new PolicyInfo(USES_POLICY_RESET_PASSWORD, "reset-password", 140 com.android.internal.R.string.policylab_resetPassword, 141 com.android.internal.R.string.policydesc_resetPassword)); 142 sPoliciesDisplayOrder.add(new PolicyInfo(USES_POLICY_LIMIT_PASSWORD, "limit-password", 143 com.android.internal.R.string.policylab_limitPassword, 144 com.android.internal.R.string.policydesc_limitPassword)); 145 sPoliciesDisplayOrder.add(new PolicyInfo(USES_POLICY_WATCH_LOGIN, "watch-login", 146 com.android.internal.R.string.policylab_watchLogin, 147 com.android.internal.R.string.policydesc_watchLogin)); 148 sPoliciesDisplayOrder.add(new PolicyInfo(USES_POLICY_FORCE_LOCK, "force-lock", 149 com.android.internal.R.string.policylab_forceLock, 150 com.android.internal.R.string.policydesc_forceLock)); 151 sPoliciesDisplayOrder.add(new PolicyInfo(USES_POLICY_SETS_GLOBAL_PROXY, "set-global-proxy", 152 com.android.internal.R.string.policylab_setGlobalProxy, 153 com.android.internal.R.string.policydesc_setGlobalProxy)); 154 155 for (int i=0; i<sPoliciesDisplayOrder.size(); i++) { 156 PolicyInfo pi = sPoliciesDisplayOrder.get(i); 157 sRevKnownPolicies.put(pi.ident, pi); 158 sKnownPolicies.put(pi.tag, pi.ident); 159 } 160 } 161 162 /** 163 * The BroadcastReceiver that implements this device admin component. 164 */ 165 final ResolveInfo mReceiver; 166 167 /** 168 * Whether this should be visible to the user. 169 */ 170 boolean mVisible; 171 172 /** 173 * The policies this administrator needs access to. 174 */ 175 int mUsesPolicies; 176 177 /** 178 * Constructor. 179 * 180 * @param context The Context in which we are parsing the device admin. 181 * @param receiver The ResolveInfo returned from the package manager about 182 * this device admin's component. 183 */ 184 public DeviceAdminInfo(Context context, ResolveInfo receiver) 185 throws XmlPullParserException, IOException { 186 mReceiver = receiver; 187 ActivityInfo ai = receiver.activityInfo; 188 189 PackageManager pm = context.getPackageManager(); 190 191 XmlResourceParser parser = null; 192 try { 193 parser = ai.loadXmlMetaData(pm, DeviceAdminReceiver.DEVICE_ADMIN_META_DATA); 194 if (parser == null) { 195 throw new XmlPullParserException("No " 196 + DeviceAdminReceiver.DEVICE_ADMIN_META_DATA + " meta-data"); 197 } 198 199 Resources res = pm.getResourcesForApplication(ai.applicationInfo); 200 201 AttributeSet attrs = Xml.asAttributeSet(parser); 202 203 int type; 204 while ((type=parser.next()) != XmlPullParser.END_DOCUMENT 205 && type != XmlPullParser.START_TAG) { 206 } 207 208 String nodeName = parser.getName(); 209 if (!"device-admin".equals(nodeName)) { 210 throw new XmlPullParserException( 211 "Meta-data does not start with device-admin tag"); 212 } 213 214 TypedArray sa = res.obtainAttributes(attrs, 215 com.android.internal.R.styleable.DeviceAdmin); 216 217 mVisible = sa.getBoolean( 218 com.android.internal.R.styleable.DeviceAdmin_visible, true); 219 220 sa.recycle(); 221 222 int outerDepth = parser.getDepth(); 223 while ((type=parser.next()) != XmlPullParser.END_DOCUMENT 224 && (type != XmlPullParser.END_TAG || parser.getDepth() > outerDepth)) { 225 if (type == XmlPullParser.END_TAG || type == XmlPullParser.TEXT) { 226 continue; 227 } 228 String tagName = parser.getName(); 229 if (tagName.equals("uses-policies")) { 230 int innerDepth = parser.getDepth(); 231 while ((type=parser.next()) != XmlPullParser.END_DOCUMENT 232 && (type != XmlPullParser.END_TAG || parser.getDepth() > innerDepth)) { 233 if (type == XmlPullParser.END_TAG || type == XmlPullParser.TEXT) { 234 continue; 235 } 236 String policyName = parser.getName(); 237 Integer val = sKnownPolicies.get(policyName); 238 if (val != null) { 239 mUsesPolicies |= 1 << val.intValue(); 240 } else { 241 Log.w(TAG, "Unknown tag under uses-policies of " 242 + getComponent() + ": " + policyName); 243 } 244 } 245 } 246 } 247 } catch (NameNotFoundException e) { 248 throw new XmlPullParserException( 249 "Unable to create context for: " + ai.packageName); 250 } finally { 251 if (parser != null) parser.close(); 252 } 253 } 254 255 DeviceAdminInfo(Parcel source) { 256 mReceiver = ResolveInfo.CREATOR.createFromParcel(source); 257 mUsesPolicies = source.readInt(); 258 } 259 260 /** 261 * Return the .apk package that implements this device admin. 262 */ 263 public String getPackageName() { 264 return mReceiver.activityInfo.packageName; 265 } 266 267 /** 268 * Return the class name of the receiver component that implements 269 * this device admin. 270 */ 271 public String getReceiverName() { 272 return mReceiver.activityInfo.name; 273 } 274 275 /** 276 * Return the raw information about the receiver implementing this 277 * device admin. Do not modify the returned object. 278 */ 279 public ActivityInfo getActivityInfo() { 280 return mReceiver.activityInfo; 281 } 282 283 /** 284 * Return the component of the receiver that implements this device admin. 285 */ 286 public ComponentName getComponent() { 287 return new ComponentName(mReceiver.activityInfo.packageName, 288 mReceiver.activityInfo.name); 289 } 290 291 /** 292 * Load the user-displayed label for this device admin. 293 * 294 * @param pm Supply a PackageManager used to load the device admin's 295 * resources. 296 */ 297 public CharSequence loadLabel(PackageManager pm) { 298 return mReceiver.loadLabel(pm); 299 } 300 301 /** 302 * Load user-visible description associated with this device admin. 303 * 304 * @param pm Supply a PackageManager used to load the device admin's 305 * resources. 306 */ 307 public CharSequence loadDescription(PackageManager pm) throws NotFoundException { 308 if (mReceiver.activityInfo.descriptionRes != 0) { 309 String packageName = mReceiver.resolvePackageName; 310 ApplicationInfo applicationInfo = null; 311 if (packageName == null) { 312 packageName = mReceiver.activityInfo.packageName; 313 applicationInfo = mReceiver.activityInfo.applicationInfo; 314 } 315 return pm.getText(packageName, 316 mReceiver.activityInfo.descriptionRes, applicationInfo); 317 } 318 throw new NotFoundException(); 319 } 320 321 /** 322 * Load the user-displayed icon for this device admin. 323 * 324 * @param pm Supply a PackageManager used to load the device admin's 325 * resources. 326 */ 327 public Drawable loadIcon(PackageManager pm) { 328 return mReceiver.loadIcon(pm); 329 } 330 331 /** 332 * Returns whether this device admin would like to be visible to the 333 * user, even when it is not enabled. 334 */ 335 public boolean isVisible() { 336 return mVisible; 337 } 338 339 /** 340 * Return true if the device admin has requested that it be able to use 341 * the given policy control. The possible policy identifier inputs are: 342 * {@link #USES_POLICY_LIMIT_PASSWORD}, {@link #USES_POLICY_WATCH_LOGIN}, 343 * {@link #USES_POLICY_RESET_PASSWORD}, {@link #USES_POLICY_FORCE_LOCK}, 344 * {@link #USES_POLICY_WIPE_DATA}, {@link #USES_POLICY_SETS_GLOBAL_PROXY}. 345 */ 346 public boolean usesPolicy(int policyIdent) { 347 return (mUsesPolicies & (1<<policyIdent)) != 0; 348 } 349 350 /** 351 * Return the XML tag name for the given policy identifier. Valid identifiers 352 * are as per {@link #usesPolicy(int)}. If the given identifier is not 353 * known, null is returned. 354 */ 355 public String getTagForPolicy(int policyIdent) { 356 return sRevKnownPolicies.get(policyIdent).tag; 357 } 358 359 /** @hide */ 360 public ArrayList<PolicyInfo> getUsedPolicies() { 361 ArrayList<PolicyInfo> res = new ArrayList<PolicyInfo>(); 362 for (int i=0; i<sPoliciesDisplayOrder.size(); i++) { 363 PolicyInfo pi = sPoliciesDisplayOrder.get(i); 364 if (usesPolicy(pi.ident)) { 365 res.add(pi); 366 } 367 } 368 return res; 369 } 370 371 /** @hide */ 372 public void writePoliciesToXml(XmlSerializer out) 373 throws IllegalArgumentException, IllegalStateException, IOException { 374 out.attribute(null, "flags", Integer.toString(mUsesPolicies)); 375 } 376 377 /** @hide */ 378 public void readPoliciesFromXml(XmlPullParser parser) 379 throws XmlPullParserException, IOException { 380 mUsesPolicies = Integer.parseInt( 381 parser.getAttributeValue(null, "flags")); 382 } 383 384 public void dump(Printer pw, String prefix) { 385 pw.println(prefix + "Receiver:"); 386 mReceiver.dump(pw, prefix + " "); 387 } 388 389 @Override 390 public String toString() { 391 return "DeviceAdminInfo{" + mReceiver.activityInfo.name + "}"; 392 } 393 394 /** 395 * Used to package this object into a {@link Parcel}. 396 * 397 * @param dest The {@link Parcel} to be written. 398 * @param flags The flags used for parceling. 399 */ 400 public void writeToParcel(Parcel dest, int flags) { 401 mReceiver.writeToParcel(dest, flags); 402 dest.writeInt(mUsesPolicies); 403 } 404 405 /** 406 * Used to make this class parcelable. 407 */ 408 public static final Parcelable.Creator<DeviceAdminInfo> CREATOR = 409 new Parcelable.Creator<DeviceAdminInfo>() { 410 public DeviceAdminInfo createFromParcel(Parcel source) { 411 return new DeviceAdminInfo(source); 412 } 413 414 public DeviceAdminInfo[] newArray(int size) { 415 return new DeviceAdminInfo[size]; 416 } 417 }; 418 419 public int describeContents() { 420 return 0; 421 } 422} 423