/*
 * Copyright (C) 2014 The Android Open Source Project
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *      http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

package android.content;

import android.annotation.SystemService;
import android.annotation.UnsupportedAppUsage;
import android.app.Activity;
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.Build;
import android.os.Bundle;
import android.os.PersistableBundle;
import android.os.RemoteException;
import android.service.restrictions.RestrictionsReceiver;
import android.util.AttributeSet;
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;

/**
 * Provides a mechanism for apps to query restrictions imposed by an entity that
 * manages the user. Apps can also send permission requests to a local or remote
 * device administrator to override default app-specific restrictions or any other
 * operation that needs explicit authorization from the administrator.
 * <p>
 * Apps can expose a set of restrictions via an XML file specified in the manifest.
 * <p>
 * If the user has an active Restrictions Provider, dynamic requests can be made in
 * addition to the statically imposed restrictions. Dynamic requests are app-specific
 * and can be expressed via a predefined set of request types.
 * <p>
 * The RestrictionsManager forwards the dynamic requests to the active
 * Restrictions Provider. The Restrictions Provider can respond back to requests by calling
 * {@link #notifyPermissionResponse(String, PersistableBundle)}, when
 * a response is received from the administrator of the device or user.
 * The response is relayed back to the application via a protected broadcast,
 * {@link #ACTION_PERMISSION_RESPONSE_RECEIVED}.
 * <p>
 * Static restrictions are specified by an XML file referenced by a meta-data attribute
 * in the manifest. This enables applications as well as any web administration consoles
 * to be able to read the list of available restrictions from the apk.
 * <p>
 * The syntax of the XML format is as follows:
 * <pre>
 * &lt;?xml version="1.0" encoding="utf-8"?&gt;
 * &lt;restrictions xmlns:android="http://schemas.android.com/apk/res/android" &gt;
 *     &lt;restriction
 *         android:key="string"
 *         android:title="string resource"
 *         android:restrictionType=["bool" | "string" | "integer"
 *                                         | "choice" | "multi-select" | "hidden"
 *                                         | "bundle" | "bundle_array"]
 *         android:description="string resource"
 *         android:entries="string-array resource"
 *         android:entryValues="string-array resource"
 *         android:defaultValue="reference" &gt;
 *             &lt;restriction ... /&gt;
 *             ...
 *     &lt;/restriction&gt;
 *     &lt;restriction ... /&gt;
 *     ...
 * &lt;/restrictions&gt;
 * </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>
 * 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>
 * &lt;application ... &gt;
 *     &lt;meta-data android:name="android.content.APP_RESTRICTIONS"
 *                   android:resource="@xml/app_restrictions" /&gt;
 *     ...
 * &lt;/application&gt;
 * </pre>
 *
 * @see RestrictionEntry
 * @see RestrictionsReceiver
 * @see DevicePolicyManager#setRestrictionsProvider(ComponentName, ComponentName)
 * @see DevicePolicyManager#setApplicationRestrictions(ComponentName, String, Bundle)
 */
@SystemService(Context.RESTRICTIONS_SERVICE)
public class RestrictionsManager {

    private static final String TAG = "RestrictionsManager";

    /**
     * Broadcast intent delivered when a response is received for a permission request. The
     * application should not interrupt the user by coming to the foreground if it isn't
     * currently in the foreground. It can either post a notification informing
     * the user of the response or wait until the next time the user launches the app.
     * <p>
     * For instance, if the user requested permission to make an in-app purchase,
     * the app can post a notification that the request had been approved or denied.
     * <p>
     * The broadcast Intent carries the following extra:
     * {@link #EXTRA_RESPONSE_BUNDLE}.
     */
    public static final String ACTION_PERMISSION_RESPONSE_RECEIVED =
            "android.content.action.PERMISSION_RESPONSE_RECEIVED";

    /**
     * Broadcast intent sent to the Restrictions Provider to handle a permission request from
     * an app. It will have the following extras: {@link #EXTRA_PACKAGE_NAME},
     * {@link #EXTRA_REQUEST_TYPE}, {@link #EXTRA_REQUEST_ID} and {@link #EXTRA_REQUEST_BUNDLE}.
     * The Restrictions Provider will handle the request and respond back to the
     * RestrictionsManager, when a response is available, by calling
     * {@link #notifyPermissionResponse}.
     * <p>
     * The BroadcastReceiver must require the {@link android.Manifest.permission#BIND_DEVICE_ADMIN}
     * permission to ensure that only the system can send the broadcast.
     */
    public static final String ACTION_REQUEST_PERMISSION =
            "android.content.action.REQUEST_PERMISSION";

    /**
     * Activity intent that is optionally implemented by the Restrictions Provider package
     * to challenge for an administrator PIN or password locally on the device. Apps will
     * call this intent using {@link Activity#startActivityForResult}. On a successful
     * response, {@link Activity#onActivityResult} will return a resultCode of
     * {@link Activity#RESULT_OK}.
     * <p>
     * The intent must contain {@link #EXTRA_REQUEST_BUNDLE} as an extra and the bundle must
     * contain at least {@link #REQUEST_KEY_MESSAGE} for the activity to display.
     * <p>
     * @see #createLocalApprovalIntent()
     */
    public static final String ACTION_REQUEST_LOCAL_APPROVAL =
            "android.content.action.REQUEST_LOCAL_APPROVAL";

    /**
     * The package name of the application making the request.
     * <p>
     * Type: String
     */
    public static final String EXTRA_PACKAGE_NAME = "android.content.extra.PACKAGE_NAME";

    /**
     * The request type passed in the {@link #ACTION_REQUEST_PERMISSION} broadcast.
     * <p>
     * Type: String
     */
    public static final String EXTRA_REQUEST_TYPE = "android.content.extra.REQUEST_TYPE";

    /**
     * The request ID passed in the {@link #ACTION_REQUEST_PERMISSION} broadcast.
     * <p>
     * Type: String
     */
    public static final String EXTRA_REQUEST_ID = "android.content.extra.REQUEST_ID";

    /**
     * The request bundle passed in the {@link #ACTION_REQUEST_PERMISSION} broadcast.
     * <p>
     * Type: {@link PersistableBundle}
     */
    public static final String EXTRA_REQUEST_BUNDLE = "android.content.extra.REQUEST_BUNDLE";

    /**
     * Contains a response from the administrator for specific request.
     * The bundle contains the following information, at least:
     * <ul>
     * <li>{@link #REQUEST_KEY_ID}: The request ID.</li>
     * <li>{@link #RESPONSE_KEY_RESULT}: The response result.</li>
     * </ul>
     * <p>
     * Type: {@link PersistableBundle}
     */
    public static final String EXTRA_RESPONSE_BUNDLE = "android.content.extra.RESPONSE_BUNDLE";

    /**
     * Request type for a simple question, with a possible title and icon.
     * <p>
     * Required keys are: {@link #REQUEST_KEY_MESSAGE}
     * <p>
     * Optional keys are
     * {@link #REQUEST_KEY_DATA}, {@link #REQUEST_KEY_ICON}, {@link #REQUEST_KEY_TITLE},
     * {@link #REQUEST_KEY_APPROVE_LABEL} and {@link #REQUEST_KEY_DENY_LABEL}.
     */
    public static final String REQUEST_TYPE_APPROVAL = "android.request.type.approval";

    /**
     * Key for request ID contained in the request bundle.
     * <p>
     * App-generated request ID to identify the specific request when receiving
     * a response. This value is returned in the {@link #EXTRA_RESPONSE_BUNDLE}.
     * <p>
     * Type: String
     */
    public static final String REQUEST_KEY_ID = "android.request.id";

    /**
     * Key for request data contained in the request bundle.
     * <p>
     * Optional, typically used to identify the specific data that is being referred to,
     * such as the unique identifier for a movie or book. This is not used for display
     * purposes and is more like a cookie. This value is returned in the
     * {@link #EXTRA_RESPONSE_BUNDLE}.
     * <p>
     * Type: String
     */
    public static final String REQUEST_KEY_DATA = "android.request.data";

    /**
     * Key for request title contained in the request bundle.
     * <p>
     * Optional, typically used as the title of any notification or dialog presented
     * to the administrator who approves the request.
     * <p>
     * Type: String
     */
    public static final String REQUEST_KEY_TITLE = "android.request.title";

    /**
     * Key for request message contained in the request bundle.
     * <p>
     * Required, shown as the actual message in a notification or dialog presented
     * to the administrator who approves the request.
     * <p>
     * Type: String
     */
    public static final String REQUEST_KEY_MESSAGE = "android.request.mesg";

    /**
     * Key for request icon contained in the request bundle.
     * <p>
     * Optional, shown alongside the request message presented to the administrator
     * who approves the request. The content must be a compressed image such as a
     * PNG or JPEG, as a byte array.
     * <p>
     * Type: byte[]
     */
    public static final String REQUEST_KEY_ICON = "android.request.icon";

    /**
     * Key for request approval button label contained in the request bundle.
     * <p>
     * Optional, may be shown as a label on the positive button in a dialog or
     * notification presented to the administrator who approves the request.
     * <p>
     * Type: String
     */
    public static final String REQUEST_KEY_APPROVE_LABEL = "android.request.approve_label";

    /**
     * Key for request rejection button label contained in the request bundle.
     * <p>
     * Optional, may be shown as a label on the negative button in a dialog or
     * notification presented to the administrator who approves the request.
     * <p>
     * Type: String
     */
    public static final String REQUEST_KEY_DENY_LABEL = "android.request.deny_label";

    /**
     * Key for issuing a new request, contained in the request bundle. If this is set to true,
     * the Restrictions Provider must make a new request. If it is false or not specified, then
     * the Restrictions Provider can return a cached response that has the same requestId, if
     * available. If there's no cached response, it will issue a new one to the administrator.
     * <p>
     * Type: boolean
     */
    public static final String REQUEST_KEY_NEW_REQUEST = "android.request.new_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>
     * Possible values: {@link #RESULT_APPROVED}, {@link #RESULT_DENIED},
     * {@link #RESULT_NO_RESPONSE}, {@link #RESULT_UNKNOWN_REQUEST} or
     * {@link #RESULT_ERROR}.
     */
    public static final String RESPONSE_KEY_RESULT = "android.response.result";

    /**
     * Response result value indicating that the request was approved.
     */
    public static final int RESULT_APPROVED = 1;

    /**
     * Response result value indicating that the request was denied.
     */
    public static final int RESULT_DENIED = 2;

    /**
     * Response result value indicating that the request has not received a response yet.
     */
    public static final int RESULT_NO_RESPONSE = 3;

    /**
     * Response result value indicating that the request is unknown, when it's not a new
     * request.
     */
    public static final int RESULT_UNKNOWN_REQUEST = 4;

    /**
     * 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_MESSAGE}.
     */
    public static final int RESULT_ERROR = 5;

    /**
     * Error code indicating that there was a problem with the request.
     * <p>
     * Stored in {@link #RESPONSE_KEY_ERROR_CODE} field in the response bundle.
     */
    public static final int RESULT_ERROR_BAD_REQUEST = 1;

    /**
     * Error code indicating that there was a problem with the network.
     * <p>
     * Stored in {@link #RESPONSE_KEY_ERROR_CODE} field in the response bundle.
     */
    public static final int RESULT_ERROR_NETWORK = 2;

    /**
     * Error code indicating that there was an internal error.
     * <p>
     * Stored in {@link #RESPONSE_KEY_ERROR_CODE} field in the response bundle.
     */
    public static final int RESULT_ERROR_INTERNAL = 3;

    /**
     * Key for the optional error code in the response bundle sent to the application.
     * <p>
     * Type: int
     * <p>
     * Possible values: {@link #RESULT_ERROR_BAD_REQUEST}, {@link #RESULT_ERROR_NETWORK} or
     * {@link #RESULT_ERROR_INTERNAL}.
     */
    public static final String RESPONSE_KEY_ERROR_CODE = "android.response.errorcode";

    /**
     * Key for the optional message in the response bundle sent to the application.
     * <p>
     * Type: String
     */
    public static final String RESPONSE_KEY_MESSAGE = "android.response.msg";

    /**
     * Key for the optional timestamp of when the administrator responded to the permission
     * request. It is an represented in milliseconds since January 1, 1970 00:00:00.0 UTC.
     * <p>
     * Type: long
     */
    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;
    @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.P, trackingBug = 115609023)
    private final IRestrictionsManager mService;

    /**
     * @hide
     */
    public RestrictionsManager(Context context, IRestrictionsManager service) {
        mContext = context;
        mService = service;
    }

    /**
     * Returns any available set of application-specific restrictions applicable
     * to this application.
     * @return the application restrictions as a Bundle. Returns null if there
     * are no restrictions.
     */
    public Bundle getApplicationRestrictions() {
        try {
            if (mService != null) {
                return mService.getApplicationRestrictions(mContext.getPackageName());
            }
        } catch (RemoteException re) {
            throw re.rethrowFromSystemServer();
        }
        return null;
    }

    /**
     * Called by an application to check if there is an active Restrictions Provider. If
     * there isn't, {@link #requestPermission(String, String, PersistableBundle)} is not available.
     *
     * @return whether there is an active Restrictions Provider.
     */
    public boolean hasRestrictionsProvider() {
        try {
            if (mService != null) {
                return mService.hasRestrictionsProvider();
            }
        } catch (RemoteException re) {
            throw re.rethrowFromSystemServer();
        }
        return false;
    }

    /**
     * Called by an application to request permission for an operation. The contents of the
     * request are passed in a Bundle that contains several pieces of data depending on the
     * chosen request type.
     *
     * @param requestType The type of request. The type could be one of the
     * predefined types specified here or a custom type that the specific
     * Restrictions Provider might understand. For custom types, the type name should be
     * namespaced to avoid collisions with predefined types and types specified by
     * other Restrictions Providers.
     * @param requestId A unique id generated by the app that contains sufficient information
     * to identify the parameters of the request when it receives the id in the response.
     * @param request A PersistableBundle containing the data corresponding to the specified request
     * type. The keys for the data in the bundle depend on the request type.
     *
     * @throws IllegalArgumentException if any of the required parameters are missing.
     */
    public void requestPermission(String requestType, String requestId, PersistableBundle request) {
        if (requestType == null) {
            throw new NullPointerException("requestType cannot be null");
        }
        if (requestId == null) {
            throw new NullPointerException("requestId cannot be null");
        }
        if (request == null) {
            throw new NullPointerException("request cannot be null");
        }
        try {
            if (mService != null) {
                mService.requestPermission(mContext.getPackageName(), requestType, requestId,
                        request);
            }
        } catch (RemoteException re) {
            throw re.rethrowFromSystemServer();
        }
    }

    public Intent createLocalApprovalIntent() {
        try {
            if (mService != null) {
                return mService.createLocalApprovalIntent();
            }
        } catch (RemoteException re) {
            throw re.rethrowFromSystemServer();
        }
        return null;
    }

    /**
     * Called by the Restrictions Provider to deliver a response to an application.
     *
     * @param packageName the application to deliver the response to. Cannot be null.
     * @param response the bundle containing the response status, request ID and other information.
     *                 Cannot be null.
     *
     * @throws IllegalArgumentException if any of the required parameters are missing.
     */
    public void notifyPermissionResponse(String packageName, PersistableBundle response) {
        if (packageName == null) {
            throw new NullPointerException("packageName cannot be null");
        }
        if (response == null) {
            throw new NullPointerException("request cannot be null");
        }
        if (!response.containsKey(REQUEST_KEY_ID)) {
            throw new IllegalArgumentException("REQUEST_KEY_ID must be specified");
        }
        if (!response.containsKey(RESPONSE_KEY_RESULT)) {
            throw new IllegalArgumentException("RESPONSE_KEY_RESULT must be specified");
        }
        try {
            if (mService != null) {
                mService.notifyPermissionResponse(packageName, response);
            }
        } catch (RemoteException re) {
            throw re.rethrowFromSystemServer();
        }
    }

    /**
     * Parse and return the list of restrictions defined in the manifest for the specified
     * package, if any.
     *
     * @param packageName The application for which to fetch the restrictions list.
     * @return The list of RestrictionEntry objects created from the XML file specified
     * in the manifest, or null if none was specified.
     */
    public List<RestrictionEntry> getManifestRestrictions(String packageName) {
        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);
        return loadManifestRestrictions(packageName, xml);
    }

    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 restriction;

        try {
            int tagType = xml.next();
            while (tagType != XmlPullParser.END_DOCUMENT) {
                if (tagType == XmlPullParser.START_TAG) {
                    restriction = loadRestrictionElement(appContext, xml);
                    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 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);
        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;
            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_MULTI_SELECT}</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:
                RestrictionEntry[] bundleRestrictionArray = entry.getRestrictions();
                Bundle[] bundleArray = new Bundle[bundleRestrictionArray.length];
                for (int i = 0; i < bundleRestrictionArray.length; i++) {
                    RestrictionEntry[] bundleRestrictions =
                            bundleRestrictionArray[i].getRestrictions();
                    if (bundleRestrictions == null) {
                        // Non-bundle entry found in bundle array.
                        Log.w(TAG, "addRestrictionToBundle: " +
                                "Non-bundle entry found in bundle array");
                        bundleArray[i] = new Bundle();
                    } else {
                        bundleArray[i] = convertRestrictionsToBundle(Arrays.asList(
                                bundleRestrictions));
                    }
                }
                bundle.putParcelableArray(entry.getKey(), bundleArray);
                break;
            default:
                throw new IllegalArgumentException(
                        "Unsupported restrictionEntry type: " + entry.getType());
        }
        return bundle;
    }

}
