diff options
| author | Fyodor Kupolov <fkupolov@google.com> | 2015-03-23 18:55:11 -0700 |
|---|---|---|
| committer | Fyodor Kupolov <fkupolov@google.com> | 2015-03-30 17:59:07 -0700 |
| commit | 262f9952e6e78e00a6d42bab97d73dccfb9607f4 (patch) | |
| tree | 6509c3b8d0a43086080794c4d1238a62aab18158 /core/java/android/content/RestrictionsManager.java | |
| parent | 607f1f09c3da3a52557394d2e764326a29151173 (diff) | |
| download | frameworks_base-262f9952e6e78e00a6d42bab97d73dccfb9607f4.zip frameworks_base-262f9952e6e78e00a6d42bab97d73dccfb9607f4.tar.gz frameworks_base-262f9952e6e78e00a6d42bab97d73dccfb9607f4.tar.bz2 | |
Support for nested bundles in setApplicationRestrictions
Added new restriction types - bundle and bundle-array.
Modified RestrictionsManager.getManifestRestrictions to support new
hierarchical restrictions.
Added RestrictionsManager.convertRestrictionsToBundle, which enables
programmatic conversion from a list of RestrictionEntries to a Bundle.
Modified read/write methods for application restrictions in UserManagerService.
Added unit tests.
Bug: 19540606
Change-Id: I32b264e04d5d177ea5b4c39a8ace5ee0ce907970
Diffstat (limited to 'core/java/android/content/RestrictionsManager.java')
| -rw-r--r-- | core/java/android/content/RestrictionsManager.java | 130 |
1 files changed, 112 insertions, 18 deletions
diff --git a/core/java/android/content/RestrictionsManager.java b/core/java/android/content/RestrictionsManager.java index 21a6a0d..1fac06e 100644 --- a/core/java/android/content/RestrictionsManager.java +++ b/core/java/android/content/RestrictionsManager.java @@ -32,12 +32,14 @@ import android.util.Log; import android.util.Xml; import com.android.internal.R; +import com.android.internal.util.XmlUtils; import org.xmlpull.v1.XmlPullParser; import org.xmlpull.v1.XmlPullParserException; import java.io.IOException; import java.util.ArrayList; +import java.util.Arrays; import java.util.List; /** @@ -71,12 +73,15 @@ import java.util.List; * android:key="string" * android:title="string resource" * android:restrictionType=["bool" | "string" | "integer" - * | "choice" | "multi-select" | "hidden"] + * | "choice" | "multi-select" | "hidden" + * | "bundle" | "bundle_array"] * android:description="string resource" * android:entries="string-array resource" * android:entryValues="string-array resource" - * android:defaultValue="reference" - * /> + * android:defaultValue="reference" > + * <restriction ... /> + * ... + * </restriction> * <restriction ... /> * ... * </restrictions> @@ -97,6 +102,9 @@ import java.util.List; * administrator controlling the values, if the title is not sufficient.</li> * </ul> * <p> + * Only restrictions of type {@code bundle} and {@code bundle_array} can have one or multiple nested + * restriction elements. + * <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> @@ -537,9 +545,7 @@ public class RestrictionsManager { XmlResourceParser xml = appInfo.loadXmlMetaData(mContext.getPackageManager(), META_DATA_APP_RESTRICTIONS); - List<RestrictionEntry> restrictions = loadManifestRestrictions(packageName, xml); - - return restrictions; + return loadManifestRestrictions(packageName, xml); } private List<RestrictionEntry> loadManifestRestrictions(String packageName, @@ -550,23 +556,16 @@ public class RestrictionsManager { } catch (NameNotFoundException nnfe) { return null; } - ArrayList<RestrictionEntry> restrictions = new ArrayList<RestrictionEntry>(); + ArrayList<RestrictionEntry> restrictions = new ArrayList<>(); 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); - } - } + restriction = loadRestrictionElement(appContext, xml); + if (restriction != null) { + restrictions.add(restriction); } } tagType = xml.next(); @@ -582,7 +581,21 @@ public class RestrictionsManager { return restrictions; } - private RestrictionEntry loadRestriction(Context appContext, TypedArray a) { + private RestrictionEntry loadRestrictionElement(Context appContext, XmlResourceParser xml) + throws IOException, XmlPullParserException { + 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); + return loadRestriction(appContext, a, xml); + } + } + return null; + } + + private RestrictionEntry loadRestriction(Context appContext, TypedArray a, XmlResourceParser xml) + throws IOException, XmlPullParserException { String key = a.getString(R.styleable.RestrictionEntry_key); int restrictionType = a.getInt( R.styleable.RestrictionEntry_restrictionType, -1); @@ -633,9 +646,90 @@ public class RestrictionsManager { restriction.setSelectedState( a.getBoolean(R.styleable.RestrictionEntry_defaultValue, false)); break; + case RestrictionEntry.TYPE_BUNDLE: + case RestrictionEntry.TYPE_BUNDLE_ARRAY: + final int outerDepth = xml.getDepth(); + List<RestrictionEntry> restrictionEntries = new ArrayList<>(); + while (XmlUtils.nextElementWithin(xml, outerDepth)) { + RestrictionEntry childEntry = loadRestrictionElement(appContext, xml); + if (childEntry == null) { + Log.w(TAG, "Child entry cannot be loaded for bundle restriction " + key); + } else { + restrictionEntries.add(childEntry); + if (restrictionType == RestrictionEntry.TYPE_BUNDLE_ARRAY + && childEntry.getType() != RestrictionEntry.TYPE_BUNDLE) { + Log.w(TAG, "bundle_array " + key + + " can only contain entries of type bundle"); + } + } + } + restriction.setRestrictions(restrictionEntries.toArray(new RestrictionEntry[ + restrictionEntries.size()])); + break; default: Log.w(TAG, "Unknown restriction type " + restrictionType); } return restriction; } + + /** + * Converts a list of restrictions to the corresponding bundle, using the following mapping: + * <table> + * <tr><th>RestrictionEntry</th><th>Bundle</th></tr> + * <tr><td>{@link RestrictionEntry#TYPE_BOOLEAN}</td><td>{@link Bundle#putBoolean}</td></tr> + * <tr><td>{@link RestrictionEntry#TYPE_CHOICE}, {@link RestrictionEntry#TYPE_CHOICE}</td> + * <td>{@link Bundle#putStringArray}</td></tr> + * <tr><td>{@link RestrictionEntry#TYPE_INTEGER}</td><td>{@link Bundle#putInt}</td></tr> + * <tr><td>{@link RestrictionEntry#TYPE_STRING}</td><td>{@link Bundle#putString}</td></tr> + * <tr><td>{@link RestrictionEntry#TYPE_BUNDLE}</td><td>{@link Bundle#putBundle}</td></tr> + * <tr><td>{@link RestrictionEntry#TYPE_BUNDLE_ARRAY}</td> + * <td>{@link Bundle#putParcelableArray}</td></tr> + * </table> + * @param entries list of restrictions + */ + public static Bundle convertRestrictionsToBundle(List<RestrictionEntry> entries) { + final Bundle bundle = new Bundle(); + for (RestrictionEntry entry : entries) { + addRestrictionToBundle(bundle, entry); + } + return bundle; + } + + private static Bundle addRestrictionToBundle(Bundle bundle, RestrictionEntry entry) { + switch (entry.getType()) { + case RestrictionEntry.TYPE_BOOLEAN: + bundle.putBoolean(entry.getKey(), entry.getSelectedState()); + break; + case RestrictionEntry.TYPE_CHOICE: + case RestrictionEntry.TYPE_CHOICE_LEVEL: + case RestrictionEntry.TYPE_MULTI_SELECT: + bundle.putStringArray(entry.getKey(), entry.getAllSelectedStrings()); + break; + case RestrictionEntry.TYPE_INTEGER: + bundle.putInt(entry.getKey(), entry.getIntValue()); + break; + case RestrictionEntry.TYPE_STRING: + case RestrictionEntry.TYPE_NULL: + bundle.putString(entry.getKey(), entry.getSelectedString()); + break; + case RestrictionEntry.TYPE_BUNDLE: + RestrictionEntry[] restrictions = entry.getRestrictions(); + Bundle childBundle = convertRestrictionsToBundle(Arrays.asList(restrictions)); + bundle.putBundle(entry.getKey(), childBundle); + break; + case RestrictionEntry.TYPE_BUNDLE_ARRAY: + restrictions = entry.getRestrictions(); + Bundle[] bundleArray = new Bundle[restrictions.length]; + for (int i = 0; i < restrictions.length; i++) { + bundleArray[i] = addRestrictionToBundle(new Bundle(), restrictions[i]); + } + bundle.putParcelableArray(entry.getKey(), bundleArray); + break; + default: + throw new IllegalArgumentException( + "Unsupported restrictionEntry type: " + entry.getType()); + } + return bundle; + } + } |
