• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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.content.ComponentName;
24 import android.content.Context;
25 import android.content.pm.ActivityInfo;
26 import android.content.pm.ApplicationInfo;
27 import android.content.pm.PackageManager;
28 import android.content.pm.ResolveInfo;
29 import android.content.pm.PackageManager.NameNotFoundException;
30 import android.content.res.Resources;
31 import android.content.res.TypedArray;
32 import android.content.res.XmlResourceParser;
33 import android.content.res.Resources.NotFoundException;
34 import android.graphics.drawable.Drawable;
35 import android.os.Parcel;
36 import android.os.Parcelable;
37 import android.util.AttributeSet;
38 import android.util.Log;
39 import android.util.Printer;
40 import android.util.SparseArray;
41 import android.util.Xml;
42 
43 import java.io.IOException;
44 import java.util.ArrayList;
45 import java.util.HashMap;
46 
47 /**
48  * This class is used to specify meta information of a device administrator
49  * component.
50  */
51 public 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 
PolicyInfo(int ident, String tag, int label, int description)174         public PolicyInfo(int ident, String tag, int label, int description) {
175             this(ident, tag, label, description, label, description);
176         }
177 
PolicyInfo(int ident, String tag, int label, int description, int labelForSecondaryUsers, int descriptionForSecondaryUsers)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 {
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 ))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                 ));
sPoliciesDisplayOrder.add(new PolicyInfo(USES_POLICY_RESET_PASSWORD, "reset-password", com.android.internal.R.string.policylab_resetPassword, com.android.internal.R.string.policydesc_resetPassword))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));
sPoliciesDisplayOrder.add(new PolicyInfo(USES_POLICY_LIMIT_PASSWORD, "limit-password", com.android.internal.R.string.policylab_limitPassword, com.android.internal.R.string.policydesc_limitPassword))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));
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 ))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         ));
sPoliciesDisplayOrder.add(new PolicyInfo(USES_POLICY_FORCE_LOCK, "force-lock", com.android.internal.R.string.policylab_forceLock, com.android.internal.R.string.policydesc_forceLock))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));
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))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));
sPoliciesDisplayOrder.add(new PolicyInfo(USES_POLICY_EXPIRE_PASSWORD, "expire-password", com.android.internal.R.string.policylab_expirePassword, com.android.internal.R.string.policydesc_expirePassword))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));
sPoliciesDisplayOrder.add(new PolicyInfo(USES_ENCRYPTED_STORAGE, "encrypted-storage", com.android.internal.R.string.policylab_encryptedStorage, com.android.internal.R.string.policydesc_encryptedStorage))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));
sPoliciesDisplayOrder.add(new PolicyInfo(USES_POLICY_DISABLE_CAMERA, "disable-camera", com.android.internal.R.string.policylab_disableCamera, com.android.internal.R.string.policydesc_disableCamera))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));
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))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);
sRevKnownPolicies.put(pi.ident, pi)234             sRevKnownPolicies.put(pi.ident, pi);
sKnownPolicies.put(pi.tag, pi.ident)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      */
DeviceAdminInfo(Context context, ResolveInfo receiver)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 
DeviceAdminInfo(Parcel source)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      */
getPackageName()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      */
getReceiverName()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      */
getActivityInfo()356     public ActivityInfo getActivityInfo() {
357         return mReceiver.activityInfo;
358     }
359 
360     /**
361      * Return the component of the receiver that implements this device admin.
362      */
getComponent()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      */
loadLabel(PackageManager pm)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      */
loadDescription(PackageManager pm)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      */
loadIcon(PackageManager pm)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      */
isVisible()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      */
usesPolicy(int policyIdent)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      */
getTagForPolicy(int policyIdent)434     public String getTagForPolicy(int policyIdent) {
435         return sRevKnownPolicies.get(policyIdent).tag;
436     }
437 
438     /** @hide */
getUsedPolicies()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 */
writePoliciesToXml(XmlSerializer out)451     public void writePoliciesToXml(XmlSerializer out)
452             throws IllegalArgumentException, IllegalStateException, IOException {
453         out.attribute(null, "flags", Integer.toString(mUsesPolicies));
454     }
455 
456     /** @hide */
readPoliciesFromXml(XmlPullParser parser)457     public void readPoliciesFromXml(XmlPullParser parser)
458             throws XmlPullParserException, IOException {
459         mUsesPolicies = Integer.parseInt(
460                 parser.getAttributeValue(null, "flags"));
461     }
462 
dump(Printer pw, String prefix)463     public void dump(Printer pw, String prefix) {
464         pw.println(prefix + "Receiver:");
465         mReceiver.dump(pw, prefix + "  ");
466     }
467 
468     @Override
toString()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      */
writeToParcel(Parcel dest, int flags)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 
describeContents()498     public int describeContents() {
499         return 0;
500     }
501 }
502