docs: work - Managed configuration bundles
Update 'Set up Managed Configurations' guide to include
examples for restriction bundles and bundle_arrays.
Include table for restriction entry types and usage.
Link to EMM doc for building DPC. Formatting.
bug: 26151150
bug: 29966701
Change-Id: I89f732709fadd511b968515ab16f07dd46195f0e
diff --git a/docs/html/work/managed-configurations.jd b/docs/html/work/managed-configurations.jd
index 91c0637..6de4d8b 100644
--- a/docs/html/work/managed-configurations.jd
+++ b/docs/html/work/managed-configurations.jd
@@ -35,7 +35,10 @@
</ul>
<p>
- This guide shows how to implement these configuration settings in your app.
+ This guide shows how to implement managed configuration settings in
+ your app. If you're an EMM developer, refer to the
+ <a href="https://developers.google.com/android/work/build-dpc"
+ >Build a Device Policy Controller</a> guide.
</p>
<p class="note">
@@ -71,8 +74,8 @@
<ul>
<li>Declare the managed configurations in your app manifest. Doing
- so allows the enterprise administrator to read the app's
- configurations through Google Play APIs.
+ so allows the enterprise administrator to read the app's
+ configurations through Google Play APIs.
</li>
<li>Whenever the app resumes, use the {@link
@@ -82,11 +85,11 @@
</li>
<li>Listen for the
- {@link android.content.Intent#ACTION_APPLICATION_RESTRICTIONS_CHANGED
- ACTION_APPLICATION_RESTRICTIONS_CHANGED} intent. When you receive this
- broadcast, check the {@link android.content.RestrictionsManager} to see what
- the current managed configurations are, and make any necessary changes to your
- app's behavior.
+ {@link android.content.Intent#ACTION_APPLICATION_RESTRICTIONS_CHANGED
+ ACTION_APPLICATION_RESTRICTIONS_CHANGED} intent. When you receive this
+ broadcast, check the {@link android.content.RestrictionsManager} to see what
+ the current managed configurations are, and make any necessary changes to your
+ app's behavior.
</li>
</ul>
@@ -96,11 +99,11 @@
<p>
Your app can support any managed configuration you want to define. You declare the
- app's managed configurations in a <em>managed configurations file</em>, and declare the
- configurations file in the manifest. Creating a configurations file allows other
- apps to examine the managed configurations your app provides. Enterprise Mobility
- Management (EMM) partners can read your app's configurations by using Google
- Play APIs.
+ app's managed configurations in a <em>managed configurations file</em>, and declare
+ the configurations file in the manifest. Creating a configurations file allows
+ other apps to examine the managed configurations your app provides. Enterprise
+ Mobility Management (EMM) partners can read your app's configurations by using
+ Google Play APIs.
</p>
<p>
@@ -138,6 +141,14 @@
</p>
<p>
+ The managed configuration provider can query the app to find details
+ on the app's available configurations, including their description
+ text. The configurations provider and enterprise administrator can
+ change your app's managed configurations at any time, even when the
+ app is not running.
+</p>
+
+<p>
For example, suppose your app can be remotely configured to allow or forbid
it to download data over a cellular connection. Your app could have a
<code><restriction></code> element like this:
@@ -145,7 +156,7 @@
<pre>
<?xml version="1.0" encoding="utf-8"?>
-<restrictions xmlns:android="http://schemas.android.com/apk/res/android" >
+<restrictions xmlns:android="http://schemas.android.com/apk/res/android">
<restriction
android:key="downloadOnCellular"
@@ -158,11 +169,6 @@
</pre>
<p>
- The supported types for the <code>android:restrictionType</code> element are
- documented in the reference for {@link android.content.RestrictionsManager}.
-</p>
-
-<p>
You use each configuration's <code>android:key</code> attribute to
read its value from a managed configuration bundle. For this reason,
each configuration must have a unique key string, and the string
@@ -172,19 +178,145 @@
<p class="note">
<strong>Note:</strong> In a production app, <code>android:title</code> and
<code>android:description</code> should be drawn from a localized resource
- file, as described in <a href=
- "{@docRoot}guide/topics/resources/localization.html">Localizing with
- Resources</a>.
+ file, as described in
+ <a href="{@docRoot}guide/topics/resources/localization.html"
+ >Localizing with Resources</a>.
</p>
-<p>
- The managed configuration provider can query the app to find details
- on the app's available configurations, including their description
- text. Configurations providers and enterprise administrators can
- change your app's managed configurations at any time, even when the
- app is not running.
+<p id="nested-restrictions">
+ An app can define one or multiple nested restriction elements using
+ the restriction types
+ {@link android.content.RestrictionEntry#TYPE_BUNDLE bundle} and
+ {@link android.content.RestrictionEntry#TYPE_BUNDLE_ARRAY bundle_array}.
+ For example, an app with multiple VPN connection options could define
+ each VPN server configuration in a bundle, with multiple bundles grouped
+ together in a bundle array:
</p>
+<pre>
+<?xml version="1.0" encoding="utf-8"?>
+<restrictions xmlns:android="http://schemas.android.com/apk/res/android" >
+
+ <restriction
+ android:key="vpn_configuration_list"
+ android:restrictionType="bundle_array">
+ <restriction
+ android:key="vpn_configuration"
+ android:restrictionType="bundle">
+ <restriction
+ android:key="vpn_server"
+ android:restrictionType="string"/>
+ <restriction
+ android:key="vpn_username"
+ android:restrictionType="string"/>
+ <restriction
+ android:key="vpn_password"
+ android:restrictionType="string"/>
+ </restriction>
+ </restriction>
+
+</restrictions>
+</pre>
+
+<p>
+ The supported types for the <code>android:restrictionType</code> element
+ are listed in <a href="#restriction-types">Table 1</a> and documented in
+ the reference for {@link android.content.RestrictionsManager} and
+ {@link android.content.RestrictionEntry}.
+</p>
+
+<p class="table-caption" id="restriction-types">
+ <strong>Table 1.</strong> Restriction entry types and usage.
+</p>
+<table>
+ <tbody>
+ <tr>
+ <th>Type</th>
+ <th>android:restrictionType</th>
+ <th>Typical usage</th>
+ </tr>
+ <tr>
+ <td>
+ {@link android.content.RestrictionEntry#TYPE_BOOLEAN TYPE_BOOLEAN}
+ </td>
+ <td><code>"bool"</code></td>
+ <td>
+ A boolean value, true or false.
+ </td>
+ </tr>
+ <tr>
+ <td>
+ {@link android.content.RestrictionEntry#TYPE_STRING TYPE_STRING}
+ </td>
+ <td><code>"string"</code></td>
+ <td>
+ A string value, such as a name.
+ </td>
+ </tr>
+ <tr>
+ <td>
+ {@link android.content.RestrictionEntry#TYPE_INTEGER TYPE_INTEGER}
+ </td>
+ <td><code>"integer"</code></td>
+ <td>
+ An integer with a value from
+ {@link java.lang.Integer#MIN_VALUE MIN_VALUE} to
+ {@link java.lang.Integer#MAX_VALUE MAX_VALUE}.
+ </td>
+ </tr>
+ <tr>
+ <td>
+ {@link android.content.RestrictionEntry#TYPE_CHOICE TYPE_CHOICE}
+ </td>
+ <td><code>"choice"</code></td>
+ <td>
+ A string value, typically presented as a single-select list.
+ </td>
+ </tr>
+ <tr>
+ <td>
+ {@link android.content.RestrictionEntry#TYPE_MULTI_SELECT TYPE_MULTI_SELECT}
+ </td>
+ <td><code>"multi-select"</code></td>
+ <td>
+ Use this for presenting a multi-select list where more than
+ one entry can be selected, such as for choosing specific
+ titles to white-list.
+ </td>
+ </tr>
+ <tr>
+ <td>
+ {@link android.content.RestrictionEntry#TYPE_NULL TYPE_NULL}
+ </td>
+ <td><code>"hidden"</code></td>
+ <td>
+ Hidden restriction type. Use this type for information that
+ needs to be transferred across but shouldn't be presented to
+ the user in the UI. Stores a single string value.
+ </td>
+ </tr>
+ <tr>
+ <td>{@link android.content.RestrictionEntry#TYPE_BUNDLE TYPE_BUNDLE}</td>
+ <td><code>"bundle"</code></td>
+ <td>
+ Use this for storing {@link android.os.Bundle bundles} of
+ restrictions. Available in Android 6.0 (API level 23).
+ </td>
+ </tr>
+ <tr>
+ <td>
+ {@link android.content.RestrictionEntry#TYPE_BUNDLE_ARRAY TYPE_BUNDLE_ARRAY}
+ </td>
+ <td><code>"bundle_array"</code></td>
+ <td>
+ Use this for storing arrays of restriction
+ <a href="{@docRoot}reference/android/os/Bundle.html"
+ >bundles</a>. Available in Android 6.0 (API level 23).
+ </td>
+ </tr>
+ </tbody>
+</table>
+
<h2 id="check-configuration">
Check Managed Configurations
</h2>
@@ -292,11 +424,10 @@
<pre>
boolean appCanUseCellular;
-if appRestrictions.containsKey("downloadOnCellular") {
+if (appRestrictions.containsKey("downloadOnCellular")) {
appCanUseCellular = appRestrictions.getBoolean("downloadOnCellular");
} else {
- // here, cellularDefault is a boolean set with the restriction's
- // default value
+ // cellularDefault is a boolean using the restriction's default value
appCanUseCellular = cellularDefault;
}
@@ -305,6 +436,37 @@
// ...show appropriate notices to user
}</pre>
+<p>
+ To apply multiple <a href="#nested-restrictions">nested restrictions</a>, read
+ the {@link android.content.RestrictionEntry#TYPE_BUNDLE_ARRAY bundle_array}
+ restriction entry as a collection of {@link android.os.Parcelable} objects
+ and cast as a {@link android.os.Bundle}. In this example, each VPN's configuration
+ data is parsed and used to build a list of server connection choices:
+</p>
+
+<pre>
+// VpnConfig is a sample class used store config data, not defined
+List<VpnConfig> vpnConfigs = new ArrayList<>();
+
+Parcelable[] parcelables =
+ appRestrictions.getParcelableArray("vpn_configuration_list");
+
+if (parcelables != null && parcelables.length > 0) {
+ // iterate parcelables and cast as bundle
+ for (int i = 0; i < parcelables.length; i++) {
+ Bundle vpnConfigBundle = (Bundle) parcelables[i];
+ // parse bundle data and store in VpnConfig array
+ vpnConfigs.add(new VpnConfig()
+ .setServer(vpnConfigBundle.getString("vpn_server"))
+ .setUsername(vpnConfigBundle.getString("vpn_username"))
+ .setPassword(vpnConfigBundle.getString("vpn_password")));
+ }
+}
+
+if (!vpnConfigs.isEmpty()) {
+ // ...choose a VPN configuration or prompt user to select from list
+}</pre>
+
<h2 id="listen-configuration">
Listen for Managed Configuration Changes
</h2>