Loading api/current.txt +14 −10 Original line number Diff line number Diff line Loading @@ -359,7 +359,7 @@ package android { field public static final int buttonTint = 16843889; // 0x1010471 field public static final int buttonTintMode = 16843890; // 0x1010472 field public static final int cacheColorHint = 16843009; // 0x1010101 field public static final int calendarTextColor = 16843933; // 0x101049d field public static final int calendarTextColor = 16843934; // 0x101049e field public static final int calendarViewShown = 16843596; // 0x101034c field public static final int calendarViewStyle = 16843613; // 0x101035d field public static final int canRequestEnhancedWebAccessibility = 16843736; // 0x10103d8 Loading Loading @@ -448,14 +448,14 @@ package android { field public static final int dashWidth = 16843174; // 0x10101a6 field public static final int data = 16842798; // 0x101002e field public static final int datePickerStyle = 16843612; // 0x101035c field public static final int dateSelectorBackgroundColor = 16843927; // 0x1010497 field public static final int dateSelectorDayOfMonthTextAppearance = 16843929; // 0x1010499 field public static final int dateSelectorDayOfWeekBackgroundColor = 16843925; // 0x1010495 field public static final int dateSelectorDayOfWeekTextAppearance = 16843926; // 0x1010496 field public static final int dateSelectorMonthTextAppearance = 16843928; // 0x1010498 field public static final int dateSelectorYearListItemTextAppearance = 16843931; // 0x101049b field public static final int dateSelectorYearListSelectedCircleColor = 16843932; // 0x101049c field public static final int dateSelectorYearTextAppearance = 16843930; // 0x101049a field public static final int dateSelectorBackgroundColor = 16843928; // 0x1010498 field public static final int dateSelectorDayOfMonthTextAppearance = 16843930; // 0x101049a field public static final int dateSelectorDayOfWeekBackgroundColor = 16843926; // 0x1010496 field public static final int dateSelectorDayOfWeekTextAppearance = 16843927; // 0x1010497 field public static final int dateSelectorMonthTextAppearance = 16843929; // 0x1010499 field public static final int dateSelectorYearListItemTextAppearance = 16843932; // 0x101049c field public static final int dateSelectorYearListSelectedCircleColor = 16843933; // 0x101049d field public static final int dateSelectorYearTextAppearance = 16843931; // 0x101049b field public static final int dateTextAppearance = 16843593; // 0x1010349 field public static final int debuggable = 16842767; // 0x101000f field public static final int defaultValue = 16843245; // 0x10101ed Loading Loading @@ -1007,6 +1007,7 @@ package android { field public static final int restoreAnyVersion = 16843450; // 0x10102ba field public static final deprecated int restoreNeedsApplication = 16843421; // 0x101029d field public static final int restrictedAccountType = 16843733; // 0x10103d5 field public static final int restrictionType = 16843925; // 0x1010495 field public static final int reversible = 16843853; // 0x101044d field public static final int right = 16843183; // 0x10101af field public static final int ringtonePreferenceStyle = 16842899; // 0x1010093 Loading Loading @@ -7934,6 +7935,7 @@ package android.content { } public class RestrictionEntry implements android.os.Parcelable { ctor public RestrictionEntry(int, java.lang.String); ctor public RestrictionEntry(java.lang.String, java.lang.String); ctor public RestrictionEntry(java.lang.String, boolean); ctor public RestrictionEntry(java.lang.String, java.lang.String[]); Loading Loading @@ -7968,6 +7970,7 @@ package android.content { field public static final int TYPE_INTEGER = 5; // 0x5 field public static final int TYPE_MULTI_SELECT = 4; // 0x4 field public static final int TYPE_NULL = 0; // 0x0 field public static final int TYPE_STRING = 6; // 0x6 } public class RestrictionsManager { Loading @@ -7982,6 +7985,7 @@ package android.content { field public static final java.lang.String EXTRA_REQUEST_BUNDLE = "android.content.extra.REQUEST_BUNDLE"; field public static final java.lang.String EXTRA_REQUEST_TYPE = "android.content.extra.REQUEST_TYPE"; field public static final java.lang.String EXTRA_RESPONSE_BUNDLE = "android.content.extra.RESPONSE_BUNDLE"; field public static final java.lang.String META_DATA_APP_RESTRICTIONS = "android.content.APP_RESTRICTIONS"; field public static final java.lang.String REQUEST_KEY_APPROVE_LABEL = "android.request.approve_label"; field public static final java.lang.String REQUEST_KEY_DATA = "android.request.data"; field public static final java.lang.String REQUEST_KEY_DENY_LABEL = "android.request.deny_label"; Loading @@ -7993,7 +7997,7 @@ package android.content { field public static final java.lang.String REQUEST_TYPE_APPROVAL = "android.request.type.approval"; field public static final java.lang.String REQUEST_TYPE_LOCAL_APPROVAL = "android.request.type.local_approval"; field public static final java.lang.String RESPONSE_KEY_ERROR_CODE = "android.response.errorcode"; field public static final java.lang.String RESPONSE_KEY_ERROR_MESSAGE = "android.response.errormsg"; field public static final java.lang.String RESPONSE_KEY_MESSAGE = "android.response.msg"; field public static final java.lang.String RESPONSE_KEY_RESPONSE_TIMESTAMP = "android.response.timestamp"; field public static final java.lang.String RESPONSE_KEY_RESULT = "android.response.result"; field public static final int RESULT_APPROVED = 1; // 0x1 core/java/android/app/admin/DevicePolicyManager.java +1 −1 Original line number Diff line number Diff line Loading @@ -2243,7 +2243,7 @@ public class DevicePolicyManager { * application running in the managed profile. * * <p>The provided {@link Bundle} consists of key-value pairs, where the types of values may be * {@link Boolean}, {@link String}, or {@link String}[]. The recommended format for key strings * boolean, int, String, or String[]. The recommended format for keys * is "com.example.packagename/example-setting" to avoid naming conflicts with library * components such as {@link android.webkit.WebView}. * Loading core/java/android/content/RestrictionEntry.java +18 −0 Original line number Diff line number Diff line Loading @@ -79,6 +79,13 @@ public class RestrictionEntry implements Parcelable { */ public static final int TYPE_INTEGER = 5; /** * A type of restriction. Use this for storing a string value. * @see #setSelectedString * @see #getSelectedString */ public static final int TYPE_STRING = 6; /** The type of restriction. */ private int mType; Loading Loading @@ -106,6 +113,17 @@ public class RestrictionEntry implements Parcelable { /* List of selected choices in the multi-select case. */ private String[] mCurrentValues; /** * Constructor for specifying the type and key, with no initial value; * * @param type the restriction type. * @param key the unique key for this restriction */ public RestrictionEntry(int type, String key) { mType = type; mKey = key; } /** * Constructor for {@link #TYPE_CHOICE} type. * @param key the unique key for this restriction Loading core/java/android/content/RestrictionsManager.java +179 −12 Original line number Diff line number Diff line Loading @@ -17,11 +17,24 @@ package android.content; import android.app.admin.DevicePolicyManager; import android.content.pm.ApplicationInfo; import android.content.pm.PackageManager; import android.content.pm.PackageManager.NameNotFoundException; import android.content.res.TypedArray; import android.content.res.XmlResourceParser; import android.os.Bundle; import android.os.RemoteException; import android.util.AttributeSet; import android.util.Log; import android.util.Xml; import java.util.Collections; import com.android.internal.R; import org.xmlpull.v1.XmlPullParser; import org.xmlpull.v1.XmlPullParserException; import java.io.IOException; import java.util.ArrayList; import java.util.List; /** Loading Loading @@ -49,19 +62,52 @@ import java.util.List; * <p> * The syntax of the XML format is as follows: * <pre> * <restrictions> * <?xml version="1.0" encoding="utf-8"?> * <restrictions xmlns:android="http://schemas.android.com/apk/res/android" > * <restriction * android:key="<key>" * android:restrictionType="boolean|string|integer|multi-select|null" * ... /> * android:key="string" * android:title="string resource" * android:restrictionType=["bool" | "string" | "integer" * | "choice" | "multi-select" | "hidden"] * android:description="string resource" * android:entries="string-array resource" * android:entryValues="string-array resource" * android:defaultValue="reference" * /> * <restriction ... /> * ... * </restrictions> * </pre> * <p> * The attributes for each restriction depend on the restriction type. * <p> * <ul> * <li><code>key</code>, <code>title</code> and <code>restrictionType</code> are mandatory.</li> * <li><code>entries</code> and <code>entryValues</code> are required if <code>restrictionType * </code> is <code>choice</code> or <code>multi-select</code>.</li> * <li><code>defaultValue</code> is optional and its type depends on the * <code>restrictionType</code></li> * <li><code>hidden</code> type must have a <code>defaultValue</code> and will * not be shown to the administrator. It can be used to pass along data that cannot be modified, * such as a version code.</li> * <li><code>description</code> is meant to describe the restriction in more detail to the * administrator controlling the values, if the title is not sufficient.</li> * </ul> * <p> * In your manifest's <code>application</code> section, add the meta-data tag to point to * the restrictions XML file as shown below: * <pre> * <application ... > * <meta-data android:name="android.content.APP_RESTRICTIONS" * android:resource="@xml/app_restrictions" /> * ... * </application> * </pre> * * @see RestrictionEntry * @see AbstractRestrictionsProvider * @see DevicePolicyManager#setRestrictionsProvider(ComponentName, ComponentName) * @see DevicePolicyManager#setApplicationRestrictions(ComponentName, String, Bundle) */ public class RestrictionsManager { Loading Loading @@ -231,8 +277,9 @@ public class RestrictionsManager { public static final String REQUEST_KEY_NEW_REQUEST = "android.request.new_request"; /** * Key for the response in the response bundle sent to the application, for a permission * request. * Key for the response result in the response bundle sent to the application, for a permission * request. It indicates the status of the request. In some cases an additional message might * be available in {@link #RESPONSE_KEY_MESSAGE}, to be displayed to the user. * <p> * Type: int * <p> Loading Loading @@ -267,7 +314,7 @@ public class RestrictionsManager { * Response result value indicating an error condition. Additional error code might be available * in the response bundle, for the key {@link #RESPONSE_KEY_ERROR_CODE}. There might also be * an associated error message in the response bundle, for the key * {@link #RESPONSE_KEY_ERROR_MESSAGE}. * {@link #RESPONSE_KEY_MESSAGE}. */ public static final int RESULT_ERROR = 5; Loading Loading @@ -303,11 +350,11 @@ public class RestrictionsManager { public static final String RESPONSE_KEY_ERROR_CODE = "android.response.errorcode"; /** * Key for the optional error message in the response bundle sent to the application. * Key for the optional message in the response bundle sent to the application. * <p> * Type: String */ public static final String RESPONSE_KEY_ERROR_MESSAGE = "android.response.errormsg"; public static final String RESPONSE_KEY_MESSAGE = "android.response.msg"; /** * Key for the optional timestamp of when the administrator responded to the permission Loading @@ -317,6 +364,15 @@ public class RestrictionsManager { */ public static final String RESPONSE_KEY_RESPONSE_TIMESTAMP = "android.response.timestamp"; /** * Name of the meta-data entry in the manifest that points to the XML file containing the * application's available restrictions. * @see #getManifestRestrictions(String) */ public static final String META_DATA_APP_RESTRICTIONS = "android.content.APP_RESTRICTIONS"; private static final String TAG_RESTRICTION = "restriction"; private final Context mContext; private final IRestrictionsManager mService; Loading Loading @@ -436,7 +492,118 @@ public class RestrictionsManager { * in the manifest, or null if none was specified. */ public List<RestrictionEntry> getManifestRestrictions(String packageName) { // TODO: ApplicationInfo appInfo = null; try { appInfo = mContext.getPackageManager().getApplicationInfo(packageName, PackageManager.GET_META_DATA); } catch (NameNotFoundException pnfe) { throw new IllegalArgumentException("No such package " + packageName); } if (appInfo == null || !appInfo.metaData.containsKey(META_DATA_APP_RESTRICTIONS)) { return null; } XmlResourceParser xml = appInfo.loadXmlMetaData(mContext.getPackageManager(), META_DATA_APP_RESTRICTIONS); List<RestrictionEntry> restrictions = loadManifestRestrictions(packageName, xml); return restrictions; } private List<RestrictionEntry> loadManifestRestrictions(String packageName, XmlResourceParser xml) { Context appContext; try { appContext = mContext.createPackageContext(packageName, 0 /* flags */); } catch (NameNotFoundException nnfe) { return null; } ArrayList<RestrictionEntry> restrictions = new ArrayList<RestrictionEntry>(); RestrictionEntry restriction; try { int tagType = xml.next(); while (tagType != XmlPullParser.END_DOCUMENT) { if (tagType == XmlPullParser.START_TAG) { if (xml.getName().equals(TAG_RESTRICTION)) { AttributeSet attrSet = Xml.asAttributeSet(xml); if (attrSet != null) { TypedArray a = appContext.obtainStyledAttributes(attrSet, com.android.internal.R.styleable.RestrictionEntry); restriction = loadRestriction(appContext, a); if (restriction != null) { restrictions.add(restriction); } } } } tagType = xml.next(); } } catch (XmlPullParserException e) { Log.w(TAG, "Reading restriction metadata for " + packageName, e); return null; } catch (IOException e) { Log.w(TAG, "Reading restriction metadata for " + packageName, e); return null; } return restrictions; } private RestrictionEntry loadRestriction(Context appContext, TypedArray a) { String key = a.getString(R.styleable.RestrictionEntry_key); int restrictionType = a.getInt( R.styleable.RestrictionEntry_restrictionType, -1); String title = a.getString(R.styleable.RestrictionEntry_title); String description = a.getString(R.styleable.RestrictionEntry_description); int entries = a.getResourceId(R.styleable.RestrictionEntry_entries, 0); int entryValues = a.getResourceId(R.styleable.RestrictionEntry_entryValues, 0); if (restrictionType == -1) { Log.w(TAG, "restrictionType cannot be omitted"); return null; } if (key == null) { Log.w(TAG, "key cannot be omitted"); return null; } RestrictionEntry restriction = new RestrictionEntry(restrictionType, key); restriction.setTitle(title); restriction.setDescription(description); if (entries != 0) { restriction.setChoiceEntries(appContext, entries); } if (entryValues != 0) { restriction.setChoiceValues(appContext, entryValues); } // Extract the default value based on the type switch (restrictionType) { case RestrictionEntry.TYPE_NULL: // hidden case RestrictionEntry.TYPE_STRING: case RestrictionEntry.TYPE_CHOICE: restriction.setSelectedString( a.getString(R.styleable.RestrictionEntry_defaultValue)); break; case RestrictionEntry.TYPE_INTEGER: restriction.setIntValue( a.getInt(R.styleable.RestrictionEntry_defaultValue, 0)); break; case RestrictionEntry.TYPE_MULTI_SELECT: int resId = a.getResourceId(R.styleable.RestrictionEntry_defaultValue, 0); if (resId != 0) { restriction.setAllSelectedStrings( appContext.getResources().getStringArray(resId)); } break; case RestrictionEntry.TYPE_BOOLEAN: restriction.setSelectedState( a.getBoolean(R.styleable.RestrictionEntry_defaultValue, false)); break; default: Log.w(TAG, "Unknown restriction type " + restrictionType); } return restriction; } } core/res/res/values/attrs.xml +17 −0 Original line number Diff line number Diff line Loading @@ -7218,4 +7218,21 @@ <attr name="ambientShadowAlpha" format="float" /> <attr name="spotShadowAlpha" format="float" /> </declare-styleable> <declare-styleable name="RestrictionEntry"> <attr name="key" /> <attr name="restrictionType"> <enum name="hidden" value="0" /> <enum name="bool" value="1" /> <enum name="choice" value="2" /> <enum name="multi-select" value="4" /> <enum name="integer" value="5" /> <enum name="string" value="6" /> </attr> <attr name="title" /> <attr name="description" /> <attr name="defaultValue" /> <attr name="entries" /> <attr name="entryValues" /> </declare-styleable> </resources> Loading
api/current.txt +14 −10 Original line number Diff line number Diff line Loading @@ -359,7 +359,7 @@ package android { field public static final int buttonTint = 16843889; // 0x1010471 field public static final int buttonTintMode = 16843890; // 0x1010472 field public static final int cacheColorHint = 16843009; // 0x1010101 field public static final int calendarTextColor = 16843933; // 0x101049d field public static final int calendarTextColor = 16843934; // 0x101049e field public static final int calendarViewShown = 16843596; // 0x101034c field public static final int calendarViewStyle = 16843613; // 0x101035d field public static final int canRequestEnhancedWebAccessibility = 16843736; // 0x10103d8 Loading Loading @@ -448,14 +448,14 @@ package android { field public static final int dashWidth = 16843174; // 0x10101a6 field public static final int data = 16842798; // 0x101002e field public static final int datePickerStyle = 16843612; // 0x101035c field public static final int dateSelectorBackgroundColor = 16843927; // 0x1010497 field public static final int dateSelectorDayOfMonthTextAppearance = 16843929; // 0x1010499 field public static final int dateSelectorDayOfWeekBackgroundColor = 16843925; // 0x1010495 field public static final int dateSelectorDayOfWeekTextAppearance = 16843926; // 0x1010496 field public static final int dateSelectorMonthTextAppearance = 16843928; // 0x1010498 field public static final int dateSelectorYearListItemTextAppearance = 16843931; // 0x101049b field public static final int dateSelectorYearListSelectedCircleColor = 16843932; // 0x101049c field public static final int dateSelectorYearTextAppearance = 16843930; // 0x101049a field public static final int dateSelectorBackgroundColor = 16843928; // 0x1010498 field public static final int dateSelectorDayOfMonthTextAppearance = 16843930; // 0x101049a field public static final int dateSelectorDayOfWeekBackgroundColor = 16843926; // 0x1010496 field public static final int dateSelectorDayOfWeekTextAppearance = 16843927; // 0x1010497 field public static final int dateSelectorMonthTextAppearance = 16843929; // 0x1010499 field public static final int dateSelectorYearListItemTextAppearance = 16843932; // 0x101049c field public static final int dateSelectorYearListSelectedCircleColor = 16843933; // 0x101049d field public static final int dateSelectorYearTextAppearance = 16843931; // 0x101049b field public static final int dateTextAppearance = 16843593; // 0x1010349 field public static final int debuggable = 16842767; // 0x101000f field public static final int defaultValue = 16843245; // 0x10101ed Loading Loading @@ -1007,6 +1007,7 @@ package android { field public static final int restoreAnyVersion = 16843450; // 0x10102ba field public static final deprecated int restoreNeedsApplication = 16843421; // 0x101029d field public static final int restrictedAccountType = 16843733; // 0x10103d5 field public static final int restrictionType = 16843925; // 0x1010495 field public static final int reversible = 16843853; // 0x101044d field public static final int right = 16843183; // 0x10101af field public static final int ringtonePreferenceStyle = 16842899; // 0x1010093 Loading Loading @@ -7934,6 +7935,7 @@ package android.content { } public class RestrictionEntry implements android.os.Parcelable { ctor public RestrictionEntry(int, java.lang.String); ctor public RestrictionEntry(java.lang.String, java.lang.String); ctor public RestrictionEntry(java.lang.String, boolean); ctor public RestrictionEntry(java.lang.String, java.lang.String[]); Loading Loading @@ -7968,6 +7970,7 @@ package android.content { field public static final int TYPE_INTEGER = 5; // 0x5 field public static final int TYPE_MULTI_SELECT = 4; // 0x4 field public static final int TYPE_NULL = 0; // 0x0 field public static final int TYPE_STRING = 6; // 0x6 } public class RestrictionsManager { Loading @@ -7982,6 +7985,7 @@ package android.content { field public static final java.lang.String EXTRA_REQUEST_BUNDLE = "android.content.extra.REQUEST_BUNDLE"; field public static final java.lang.String EXTRA_REQUEST_TYPE = "android.content.extra.REQUEST_TYPE"; field public static final java.lang.String EXTRA_RESPONSE_BUNDLE = "android.content.extra.RESPONSE_BUNDLE"; field public static final java.lang.String META_DATA_APP_RESTRICTIONS = "android.content.APP_RESTRICTIONS"; field public static final java.lang.String REQUEST_KEY_APPROVE_LABEL = "android.request.approve_label"; field public static final java.lang.String REQUEST_KEY_DATA = "android.request.data"; field public static final java.lang.String REQUEST_KEY_DENY_LABEL = "android.request.deny_label"; Loading @@ -7993,7 +7997,7 @@ package android.content { field public static final java.lang.String REQUEST_TYPE_APPROVAL = "android.request.type.approval"; field public static final java.lang.String REQUEST_TYPE_LOCAL_APPROVAL = "android.request.type.local_approval"; field public static final java.lang.String RESPONSE_KEY_ERROR_CODE = "android.response.errorcode"; field public static final java.lang.String RESPONSE_KEY_ERROR_MESSAGE = "android.response.errormsg"; field public static final java.lang.String RESPONSE_KEY_MESSAGE = "android.response.msg"; field public static final java.lang.String RESPONSE_KEY_RESPONSE_TIMESTAMP = "android.response.timestamp"; field public static final java.lang.String RESPONSE_KEY_RESULT = "android.response.result"; field public static final int RESULT_APPROVED = 1; // 0x1
core/java/android/app/admin/DevicePolicyManager.java +1 −1 Original line number Diff line number Diff line Loading @@ -2243,7 +2243,7 @@ public class DevicePolicyManager { * application running in the managed profile. * * <p>The provided {@link Bundle} consists of key-value pairs, where the types of values may be * {@link Boolean}, {@link String}, or {@link String}[]. The recommended format for key strings * boolean, int, String, or String[]. The recommended format for keys * is "com.example.packagename/example-setting" to avoid naming conflicts with library * components such as {@link android.webkit.WebView}. * Loading
core/java/android/content/RestrictionEntry.java +18 −0 Original line number Diff line number Diff line Loading @@ -79,6 +79,13 @@ public class RestrictionEntry implements Parcelable { */ public static final int TYPE_INTEGER = 5; /** * A type of restriction. Use this for storing a string value. * @see #setSelectedString * @see #getSelectedString */ public static final int TYPE_STRING = 6; /** The type of restriction. */ private int mType; Loading Loading @@ -106,6 +113,17 @@ public class RestrictionEntry implements Parcelable { /* List of selected choices in the multi-select case. */ private String[] mCurrentValues; /** * Constructor for specifying the type and key, with no initial value; * * @param type the restriction type. * @param key the unique key for this restriction */ public RestrictionEntry(int type, String key) { mType = type; mKey = key; } /** * Constructor for {@link #TYPE_CHOICE} type. * @param key the unique key for this restriction Loading
core/java/android/content/RestrictionsManager.java +179 −12 Original line number Diff line number Diff line Loading @@ -17,11 +17,24 @@ package android.content; import android.app.admin.DevicePolicyManager; import android.content.pm.ApplicationInfo; import android.content.pm.PackageManager; import android.content.pm.PackageManager.NameNotFoundException; import android.content.res.TypedArray; import android.content.res.XmlResourceParser; import android.os.Bundle; import android.os.RemoteException; import android.util.AttributeSet; import android.util.Log; import android.util.Xml; import java.util.Collections; import com.android.internal.R; import org.xmlpull.v1.XmlPullParser; import org.xmlpull.v1.XmlPullParserException; import java.io.IOException; import java.util.ArrayList; import java.util.List; /** Loading Loading @@ -49,19 +62,52 @@ import java.util.List; * <p> * The syntax of the XML format is as follows: * <pre> * <restrictions> * <?xml version="1.0" encoding="utf-8"?> * <restrictions xmlns:android="http://schemas.android.com/apk/res/android" > * <restriction * android:key="<key>" * android:restrictionType="boolean|string|integer|multi-select|null" * ... /> * android:key="string" * android:title="string resource" * android:restrictionType=["bool" | "string" | "integer" * | "choice" | "multi-select" | "hidden"] * android:description="string resource" * android:entries="string-array resource" * android:entryValues="string-array resource" * android:defaultValue="reference" * /> * <restriction ... /> * ... * </restrictions> * </pre> * <p> * The attributes for each restriction depend on the restriction type. * <p> * <ul> * <li><code>key</code>, <code>title</code> and <code>restrictionType</code> are mandatory.</li> * <li><code>entries</code> and <code>entryValues</code> are required if <code>restrictionType * </code> is <code>choice</code> or <code>multi-select</code>.</li> * <li><code>defaultValue</code> is optional and its type depends on the * <code>restrictionType</code></li> * <li><code>hidden</code> type must have a <code>defaultValue</code> and will * not be shown to the administrator. It can be used to pass along data that cannot be modified, * such as a version code.</li> * <li><code>description</code> is meant to describe the restriction in more detail to the * administrator controlling the values, if the title is not sufficient.</li> * </ul> * <p> * In your manifest's <code>application</code> section, add the meta-data tag to point to * the restrictions XML file as shown below: * <pre> * <application ... > * <meta-data android:name="android.content.APP_RESTRICTIONS" * android:resource="@xml/app_restrictions" /> * ... * </application> * </pre> * * @see RestrictionEntry * @see AbstractRestrictionsProvider * @see DevicePolicyManager#setRestrictionsProvider(ComponentName, ComponentName) * @see DevicePolicyManager#setApplicationRestrictions(ComponentName, String, Bundle) */ public class RestrictionsManager { Loading Loading @@ -231,8 +277,9 @@ public class RestrictionsManager { public static final String REQUEST_KEY_NEW_REQUEST = "android.request.new_request"; /** * Key for the response in the response bundle sent to the application, for a permission * request. * Key for the response result in the response bundle sent to the application, for a permission * request. It indicates the status of the request. In some cases an additional message might * be available in {@link #RESPONSE_KEY_MESSAGE}, to be displayed to the user. * <p> * Type: int * <p> Loading Loading @@ -267,7 +314,7 @@ public class RestrictionsManager { * Response result value indicating an error condition. Additional error code might be available * in the response bundle, for the key {@link #RESPONSE_KEY_ERROR_CODE}. There might also be * an associated error message in the response bundle, for the key * {@link #RESPONSE_KEY_ERROR_MESSAGE}. * {@link #RESPONSE_KEY_MESSAGE}. */ public static final int RESULT_ERROR = 5; Loading Loading @@ -303,11 +350,11 @@ public class RestrictionsManager { public static final String RESPONSE_KEY_ERROR_CODE = "android.response.errorcode"; /** * Key for the optional error message in the response bundle sent to the application. * Key for the optional message in the response bundle sent to the application. * <p> * Type: String */ public static final String RESPONSE_KEY_ERROR_MESSAGE = "android.response.errormsg"; public static final String RESPONSE_KEY_MESSAGE = "android.response.msg"; /** * Key for the optional timestamp of when the administrator responded to the permission Loading @@ -317,6 +364,15 @@ public class RestrictionsManager { */ public static final String RESPONSE_KEY_RESPONSE_TIMESTAMP = "android.response.timestamp"; /** * Name of the meta-data entry in the manifest that points to the XML file containing the * application's available restrictions. * @see #getManifestRestrictions(String) */ public static final String META_DATA_APP_RESTRICTIONS = "android.content.APP_RESTRICTIONS"; private static final String TAG_RESTRICTION = "restriction"; private final Context mContext; private final IRestrictionsManager mService; Loading Loading @@ -436,7 +492,118 @@ public class RestrictionsManager { * in the manifest, or null if none was specified. */ public List<RestrictionEntry> getManifestRestrictions(String packageName) { // TODO: ApplicationInfo appInfo = null; try { appInfo = mContext.getPackageManager().getApplicationInfo(packageName, PackageManager.GET_META_DATA); } catch (NameNotFoundException pnfe) { throw new IllegalArgumentException("No such package " + packageName); } if (appInfo == null || !appInfo.metaData.containsKey(META_DATA_APP_RESTRICTIONS)) { return null; } XmlResourceParser xml = appInfo.loadXmlMetaData(mContext.getPackageManager(), META_DATA_APP_RESTRICTIONS); List<RestrictionEntry> restrictions = loadManifestRestrictions(packageName, xml); return restrictions; } private List<RestrictionEntry> loadManifestRestrictions(String packageName, XmlResourceParser xml) { Context appContext; try { appContext = mContext.createPackageContext(packageName, 0 /* flags */); } catch (NameNotFoundException nnfe) { return null; } ArrayList<RestrictionEntry> restrictions = new ArrayList<RestrictionEntry>(); RestrictionEntry restriction; try { int tagType = xml.next(); while (tagType != XmlPullParser.END_DOCUMENT) { if (tagType == XmlPullParser.START_TAG) { if (xml.getName().equals(TAG_RESTRICTION)) { AttributeSet attrSet = Xml.asAttributeSet(xml); if (attrSet != null) { TypedArray a = appContext.obtainStyledAttributes(attrSet, com.android.internal.R.styleable.RestrictionEntry); restriction = loadRestriction(appContext, a); if (restriction != null) { restrictions.add(restriction); } } } } tagType = xml.next(); } } catch (XmlPullParserException e) { Log.w(TAG, "Reading restriction metadata for " + packageName, e); return null; } catch (IOException e) { Log.w(TAG, "Reading restriction metadata for " + packageName, e); return null; } return restrictions; } private RestrictionEntry loadRestriction(Context appContext, TypedArray a) { String key = a.getString(R.styleable.RestrictionEntry_key); int restrictionType = a.getInt( R.styleable.RestrictionEntry_restrictionType, -1); String title = a.getString(R.styleable.RestrictionEntry_title); String description = a.getString(R.styleable.RestrictionEntry_description); int entries = a.getResourceId(R.styleable.RestrictionEntry_entries, 0); int entryValues = a.getResourceId(R.styleable.RestrictionEntry_entryValues, 0); if (restrictionType == -1) { Log.w(TAG, "restrictionType cannot be omitted"); return null; } if (key == null) { Log.w(TAG, "key cannot be omitted"); return null; } RestrictionEntry restriction = new RestrictionEntry(restrictionType, key); restriction.setTitle(title); restriction.setDescription(description); if (entries != 0) { restriction.setChoiceEntries(appContext, entries); } if (entryValues != 0) { restriction.setChoiceValues(appContext, entryValues); } // Extract the default value based on the type switch (restrictionType) { case RestrictionEntry.TYPE_NULL: // hidden case RestrictionEntry.TYPE_STRING: case RestrictionEntry.TYPE_CHOICE: restriction.setSelectedString( a.getString(R.styleable.RestrictionEntry_defaultValue)); break; case RestrictionEntry.TYPE_INTEGER: restriction.setIntValue( a.getInt(R.styleable.RestrictionEntry_defaultValue, 0)); break; case RestrictionEntry.TYPE_MULTI_SELECT: int resId = a.getResourceId(R.styleable.RestrictionEntry_defaultValue, 0); if (resId != 0) { restriction.setAllSelectedStrings( appContext.getResources().getStringArray(resId)); } break; case RestrictionEntry.TYPE_BOOLEAN: restriction.setSelectedState( a.getBoolean(R.styleable.RestrictionEntry_defaultValue, false)); break; default: Log.w(TAG, "Unknown restriction type " + restrictionType); } return restriction; } }
core/res/res/values/attrs.xml +17 −0 Original line number Diff line number Diff line Loading @@ -7218,4 +7218,21 @@ <attr name="ambientShadowAlpha" format="float" /> <attr name="spotShadowAlpha" format="float" /> </declare-styleable> <declare-styleable name="RestrictionEntry"> <attr name="key" /> <attr name="restrictionType"> <enum name="hidden" value="0" /> <enum name="bool" value="1" /> <enum name="choice" value="2" /> <enum name="multi-select" value="4" /> <enum name="integer" value="5" /> <enum name="string" value="6" /> </attr> <attr name="title" /> <attr name="description" /> <attr name="defaultValue" /> <attr name="entries" /> <attr name="entryValues" /> </declare-styleable> </resources>