Home | History | Annotate | Download | only in content
      1 /*
      2  * Copyright (C) 2013 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.content;
     18 
     19 import android.annotation.ArrayRes;
     20 import android.os.Parcel;
     21 import android.os.Parcelable;
     22 
     23 import java.util.Arrays;
     24 import java.util.Objects;
     25 
     26 /**
     27  * Applications can expose restrictions for a restricted user on a
     28  * multiuser device. The administrator can configure these restrictions that will then be
     29  * applied to the restricted user. Each RestrictionsEntry is one configurable restriction.
     30  * <p/>
     31  * Any application that chooses to expose such restrictions does so by implementing a
     32  * receiver that handles the {@link Intent#ACTION_GET_RESTRICTION_ENTRIES} action.
     33  * The receiver then returns a result bundle that contains an entry called "restrictions", whose
     34  * value is an ArrayList<RestrictionsEntry>.
     35  */
     36 public class RestrictionEntry implements Parcelable {
     37 
     38     /**
     39      * Hidden restriction type. Use this type for information that needs to be transferred
     40      * across but shouldn't be presented to the user in the UI. Stores a single String value.
     41      */
     42     public static final int TYPE_NULL         = 0;
     43 
     44     /**
     45      * Restriction of type "bool". Use this for storing a boolean value, typically presented as
     46      * a checkbox in the UI.
     47      */
     48     public static final int TYPE_BOOLEAN      = 1;
     49 
     50     /**
     51      * Restriction of type "choice". Use this for storing a string value, typically presented as
     52      * a single-select list. Call {@link #setChoiceEntries(String[])} and
     53      * {@link #setChoiceValues(String[])} to set the localized list entries to present to the user
     54      * and the corresponding values, respectively.
     55      */
     56     public static final int TYPE_CHOICE       = 2;
     57 
     58     /**
     59      * Internal restriction type. Use this for storing a string value, typically presented as
     60      * a single-select list. Call {@link #setChoiceEntries(String[])} and
     61      * {@link #setChoiceValues(String[])} to set the localized list entries to present to the user
     62      * and the corresponding values, respectively.
     63      * The presentation could imply that values in lower array indices are included when a
     64      * particular value is chosen.
     65      * @hide
     66      */
     67     public static final int TYPE_CHOICE_LEVEL = 3;
     68 
     69     /**
     70      * Restriction of type "multi-select". Use this for presenting a multi-select list where more
     71      * than one entry can be selected, such as for choosing specific titles to white-list.
     72      * Call {@link #setChoiceEntries(String[])} and
     73      * {@link #setChoiceValues(String[])} to set the localized list entries to present to the user
     74      * and the corresponding values, respectively.
     75      * Use {@link #getAllSelectedStrings()} and {@link #setAllSelectedStrings(String[])} to
     76      * manipulate the selections.
     77      */
     78     public static final int TYPE_MULTI_SELECT = 4;
     79 
     80     /**
     81      * Restriction of type "integer". Use this for storing an integer value. The range of values
     82      * is from {@link Integer#MIN_VALUE} to {@link Integer#MAX_VALUE}.
     83      */
     84     public static final int TYPE_INTEGER = 5;
     85 
     86     /**
     87      * Restriction of type "string". Use this for storing a string value.
     88      * @see #setSelectedString
     89      * @see #getSelectedString
     90      */
     91     public static final int TYPE_STRING = 6;
     92 
     93     /**
     94      * Restriction of type "bundle". Use this for storing {@link android.os.Bundle bundles} of
     95      * restrictions
     96      */
     97     public static final int TYPE_BUNDLE = 7;
     98 
     99     /**
    100      * Restriction of type "bundle_array". Use this for storing arrays of
    101      * {@link android.os.Bundle bundles} of restrictions
    102      */
    103     public static final int TYPE_BUNDLE_ARRAY = 8;
    104 
    105     /** The type of restriction. */
    106     private int mType;
    107 
    108     /** The unique key that identifies the restriction. */
    109     private String mKey;
    110 
    111     /** The user-visible title of the restriction. */
    112     private String mTitle;
    113 
    114     /** The user-visible secondary description of the restriction. */
    115     private String mDescription;
    116 
    117     /** The user-visible set of choices used for single-select and multi-select lists. */
    118     private String[] mChoiceEntries;
    119 
    120     /** The values corresponding to the user-visible choices. The value(s) of this entry will
    121      * one or more of these, returned by {@link #getAllSelectedStrings()} and
    122      * {@link #getSelectedString()}.
    123      */
    124     private String[] mChoiceValues;
    125 
    126     /* The chosen value, whose content depends on the type of the restriction. */
    127     private String mCurrentValue;
    128 
    129     /* List of selected choices in the multi-select case. */
    130     private String[] mCurrentValues;
    131 
    132     /**
    133      * List of nested restrictions. Used by {@link #TYPE_BUNDLE bundle} and
    134      * {@link #TYPE_BUNDLE_ARRAY bundle_array} restrictions.
    135      */
    136     private RestrictionEntry[] mRestrictions;
    137 
    138     /**
    139      * Constructor for specifying the type and key, with no initial value;
    140      *
    141      * @param type the restriction type.
    142      * @param key the unique key for this restriction
    143      */
    144     public RestrictionEntry(int type, String key) {
    145         mType = type;
    146         mKey = key;
    147     }
    148 
    149     /**
    150      * Constructor for {@link #TYPE_CHOICE} type.
    151      * @param key the unique key for this restriction
    152      * @param selectedString the current value
    153      */
    154     public RestrictionEntry(String key, String selectedString) {
    155         this.mKey = key;
    156         this.mType = TYPE_CHOICE;
    157         this.mCurrentValue = selectedString;
    158     }
    159 
    160     /**
    161      * Constructor for {@link #TYPE_BOOLEAN} type.
    162      * @param key the unique key for this restriction
    163      * @param selectedState whether this restriction is selected or not
    164      */
    165     public RestrictionEntry(String key, boolean selectedState) {
    166         this.mKey = key;
    167         this.mType = TYPE_BOOLEAN;
    168         setSelectedState(selectedState);
    169     }
    170 
    171     /**
    172      * Constructor for {@link #TYPE_MULTI_SELECT} type.
    173      * @param key the unique key for this restriction
    174      * @param selectedStrings the list of values that are currently selected
    175      */
    176     public RestrictionEntry(String key, String[] selectedStrings) {
    177         this.mKey = key;
    178         this.mType = TYPE_MULTI_SELECT;
    179         this.mCurrentValues = selectedStrings;
    180     }
    181 
    182     /**
    183      * Constructor for {@link #TYPE_INTEGER} type.
    184      * @param key the unique key for this restriction
    185      * @param selectedInt the integer value of the restriction
    186      */
    187     public RestrictionEntry(String key, int selectedInt) {
    188         mKey = key;
    189         mType = TYPE_INTEGER;
    190         setIntValue(selectedInt);
    191     }
    192 
    193     /**
    194      * Constructor for {@link #TYPE_BUNDLE}/{@link #TYPE_BUNDLE_ARRAY} type.
    195      * @param key the unique key for this restriction
    196      * @param restrictionEntries array of nested restriction entries. If the entry, being created
    197      * represents a {@link #TYPE_BUNDLE_ARRAY bundle-array}, {@code restrictionEntries} array may
    198      * only contain elements of type {@link #TYPE_BUNDLE bundle}.
    199      * @param isBundleArray true if this restriction represents
    200      * {@link #TYPE_BUNDLE_ARRAY bundle-array} type, otherwise the type will be set to
    201      * {@link #TYPE_BUNDLE bundle}.
    202      */
    203     private RestrictionEntry(String key, RestrictionEntry[] restrictionEntries,
    204             boolean isBundleArray) {
    205         mKey = key;
    206         if (isBundleArray) {
    207             mType = TYPE_BUNDLE_ARRAY;
    208             if (restrictionEntries != null) {
    209                 for (RestrictionEntry restriction : restrictionEntries) {
    210                     if (restriction.getType() != TYPE_BUNDLE) {
    211                         throw new IllegalArgumentException("bundle_array restriction can only have "
    212                                 + "nested restriction entries of type bundle");
    213                     }
    214                 }
    215             }
    216         } else {
    217             mType = TYPE_BUNDLE;
    218         }
    219         setRestrictions(restrictionEntries);
    220     }
    221 
    222     /**
    223      * Creates an entry of type {@link #TYPE_BUNDLE}.
    224      * @param key the unique key for this restriction
    225      * @param restrictionEntries array of nested restriction entries.
    226      * @return the newly created restriction
    227      */
    228     public static RestrictionEntry createBundleEntry(String key,
    229             RestrictionEntry[] restrictionEntries) {
    230         return new RestrictionEntry(key, restrictionEntries, false);
    231     }
    232 
    233     /**
    234      * Creates an entry of type {@link #TYPE_BUNDLE_ARRAY}.
    235      * @param key the unique key for this restriction
    236      * @param restrictionEntries array of nested restriction entries. The array may only contain
    237      * elements of type {@link #TYPE_BUNDLE bundle}.
    238      * @return the newly created restriction
    239      */
    240     public static RestrictionEntry createBundleArrayEntry(String key,
    241             RestrictionEntry[] restrictionEntries) {
    242         return new RestrictionEntry(key, restrictionEntries, true);
    243     }
    244 
    245     /**
    246      * Sets the type for this restriction.
    247      * @param type the type for this restriction.
    248      */
    249     public void setType(int type) {
    250         this.mType = type;
    251     }
    252 
    253     /**
    254      * Returns the type for this restriction.
    255      * @return the type for this restriction
    256      */
    257     public int getType() {
    258         return mType;
    259     }
    260 
    261     /**
    262      * Returns the currently selected string value.
    263      * @return the currently selected value, which can be null for types that aren't for holding
    264      * single string values.
    265      */
    266     public String getSelectedString() {
    267         return mCurrentValue;
    268     }
    269 
    270     /**
    271      * Returns the list of currently selected values.
    272      * @return the list of current selections, if type is {@link #TYPE_MULTI_SELECT},
    273      *  null otherwise.
    274      */
    275     public String[] getAllSelectedStrings() {
    276         return mCurrentValues;
    277     }
    278 
    279     /**
    280      * Returns the current selected state for an entry of type {@link #TYPE_BOOLEAN}.
    281      * @return the current selected state of the entry.
    282      */
    283     public boolean getSelectedState() {
    284         return Boolean.parseBoolean(mCurrentValue);
    285     }
    286 
    287     /**
    288      * Returns the value of the entry as an integer when the type is {@link #TYPE_INTEGER}.
    289      * @return the integer value of the entry.
    290      */
    291     public int getIntValue() {
    292         return Integer.parseInt(mCurrentValue);
    293     }
    294 
    295     /**
    296      * Sets the integer value of the entry when the type is {@link #TYPE_INTEGER}.
    297      * @param value the integer value to set.
    298      */
    299     public void setIntValue(int value) {
    300         mCurrentValue = Integer.toString(value);
    301     }
    302 
    303     /**
    304      * Sets the string value to use as the selected value for this restriction. This value will
    305      * be persisted by the system for later use by the application.
    306      * @param selectedString the string value to select.
    307      */
    308     public void setSelectedString(String selectedString) {
    309         mCurrentValue = selectedString;
    310     }
    311 
    312     /**
    313      * Sets the current selected state for an entry of type {@link #TYPE_BOOLEAN}. This value will
    314      * be persisted by the system for later use by the application.
    315      * @param state the current selected state
    316      */
    317     public void setSelectedState(boolean state) {
    318         mCurrentValue = Boolean.toString(state);
    319     }
    320 
    321     /**
    322      * Sets the current list of selected values for an entry of type {@link #TYPE_MULTI_SELECT}.
    323      * These values will be persisted by the system for later use by the application.
    324      * @param allSelectedStrings the current list of selected values.
    325      */
    326     public void setAllSelectedStrings(String[] allSelectedStrings) {
    327         mCurrentValues = allSelectedStrings;
    328     }
    329 
    330     /**
    331      * Sets a list of string values that can be selected by the user. If no user-visible entries
    332      * are set by a call to {@link #setChoiceEntries(String[])}, these values will be the ones
    333      * shown to the user. Values will be chosen from this list as the user's selection and the
    334      * selected values can be retrieved by a call to {@link #getAllSelectedStrings()}, or
    335      * {@link #getSelectedString()}, depending on whether it is a multi-select type or choice type.
    336      * This method is not relevant for types other than
    337      * {@link #TYPE_CHOICE}, and {@link #TYPE_MULTI_SELECT}.
    338      * @param choiceValues an array of Strings which will be the selected values for the user's
    339      * selections.
    340      * @see #getChoiceValues()
    341      * @see #getAllSelectedStrings()
    342      */
    343     public void setChoiceValues(String[] choiceValues) {
    344         mChoiceValues = choiceValues;
    345     }
    346 
    347     /**
    348      * Sets a list of string values that can be selected by the user, similar to
    349      * {@link #setChoiceValues(String[])}.
    350      * @param context the application context for retrieving the resources.
    351      * @param stringArrayResId the resource id for a string array containing the possible values.
    352      * @see #setChoiceValues(String[])
    353      */
    354     public void setChoiceValues(Context context, @ArrayRes int stringArrayResId) {
    355         mChoiceValues = context.getResources().getStringArray(stringArrayResId);
    356     }
    357 
    358     /**
    359      * Returns array of possible restriction entries that this entry may contain.
    360      */
    361     public RestrictionEntry[] getRestrictions() {
    362         return mRestrictions;
    363     }
    364 
    365    /**
    366     * Sets an array of possible restriction entries, that this entry may contain.
    367     * <p>This method is only relevant for types {@link #TYPE_BUNDLE} and
    368     * {@link #TYPE_BUNDLE_ARRAY}
    369     */
    370     public void setRestrictions(RestrictionEntry[] restrictions) {
    371         mRestrictions = restrictions;
    372     }
    373 
    374     /**
    375      * Returns the list of possible string values set earlier.
    376      * @return the list of possible values.
    377      */
    378     public String[] getChoiceValues() {
    379         return mChoiceValues;
    380     }
    381 
    382     /**
    383      * Sets a list of strings that will be presented as choices to the user. When the
    384      * user selects one or more of these choices, the corresponding value from the possible values
    385      * are stored as the selected strings. The size of this array must match the size of the array
    386      * set in {@link #setChoiceValues(String[])}. This method is not relevant for types other
    387      * than {@link #TYPE_CHOICE}, and {@link #TYPE_MULTI_SELECT}.
    388      * @param choiceEntries the list of user-visible choices.
    389      * @see #setChoiceValues(String[])
    390      */
    391     public void setChoiceEntries(String[] choiceEntries) {
    392         mChoiceEntries = choiceEntries;
    393     }
    394 
    395     /** Sets a list of strings that will be presented as choices to the user. This is similar to
    396      * {@link #setChoiceEntries(String[])}.
    397      * @param context the application context, used for retrieving the resources.
    398      * @param stringArrayResId the resource id of a string array containing the possible entries.
    399      */
    400     public void setChoiceEntries(Context context, @ArrayRes int stringArrayResId) {
    401         mChoiceEntries = context.getResources().getStringArray(stringArrayResId);
    402     }
    403 
    404     /**
    405      * Returns the list of strings, set earlier, that will be presented as choices to the user.
    406      * @return the list of choices presented to the user.
    407      */
    408     public String[] getChoiceEntries() {
    409         return mChoiceEntries;
    410     }
    411 
    412     /**
    413      * Returns the provided user-visible description of the entry, if any.
    414      * @return the user-visible description, null if none was set earlier.
    415      */
    416     public String getDescription() {
    417         return mDescription;
    418     }
    419 
    420     /**
    421      * Sets the user-visible description of the entry, as a possible sub-text for the title.
    422      * You can use this to describe the entry in more detail or to display the current state of
    423      * the restriction.
    424      * @param description the user-visible description string.
    425      */
    426     public void setDescription(String description) {
    427         this.mDescription = description;
    428     }
    429 
    430     /**
    431      * This is the unique key for the restriction entry.
    432      * @return the key for the restriction.
    433      */
    434     public String getKey() {
    435         return mKey;
    436     }
    437 
    438     /**
    439      * Returns the user-visible title for the entry, if any.
    440      * @return the user-visible title for the entry, null if none was set earlier.
    441      */
    442     public String getTitle() {
    443         return mTitle;
    444     }
    445 
    446     /**
    447      * Sets the user-visible title for the entry.
    448      * @param title the user-visible title for the entry.
    449      */
    450     public void setTitle(String title) {
    451         this.mTitle = title;
    452     }
    453 
    454     @Override
    455     public boolean equals(Object o) {
    456         if (o == this) return true;
    457         if (!(o instanceof RestrictionEntry)) return false;
    458         final RestrictionEntry other = (RestrictionEntry) o;
    459         if (mType != other.mType || !mKey.equals(other.mKey)) {
    460             return false;
    461         }
    462         if (mCurrentValues == null && other.mCurrentValues == null
    463                 && mRestrictions == null && other.mRestrictions == null
    464                 && Objects.equals(mCurrentValue, other.mCurrentValue)) {
    465             return true;
    466         }
    467         if (mCurrentValue == null && other.mCurrentValue == null
    468                 && mRestrictions == null && other.mRestrictions == null
    469                 && Arrays.equals(mCurrentValues, other.mCurrentValues)) {
    470             return true;
    471         }
    472         if (mCurrentValue == null && other.mCurrentValue == null
    473                 && mCurrentValue == null && other.mCurrentValue == null
    474                 && Arrays.equals(mRestrictions, other.mRestrictions)) {
    475             return true;
    476         }
    477         return false;
    478     }
    479 
    480     @Override
    481     public int hashCode() {
    482         int result = 17;
    483         result = 31 * result + mKey.hashCode();
    484         if (mCurrentValue != null) {
    485             result = 31 * result + mCurrentValue.hashCode();
    486         } else if (mCurrentValues != null) {
    487             for (String value : mCurrentValues) {
    488                 if (value != null) {
    489                     result = 31 * result + value.hashCode();
    490                 }
    491             }
    492         } else if (mRestrictions != null) {
    493             result = 31 * result + Arrays.hashCode(mRestrictions);
    494         }
    495         return result;
    496     }
    497 
    498     public RestrictionEntry(Parcel in) {
    499         mType = in.readInt();
    500         mKey = in.readString();
    501         mTitle = in.readString();
    502         mDescription = in.readString();
    503         mChoiceEntries = in.readStringArray();
    504         mChoiceValues = in.readStringArray();
    505         mCurrentValue = in.readString();
    506         mCurrentValues = in.readStringArray();
    507         Parcelable[] parcelables = in.readParcelableArray(null);
    508         if (parcelables != null) {
    509             mRestrictions = new RestrictionEntry[parcelables.length];
    510             for (int i = 0; i < parcelables.length; i++) {
    511                 mRestrictions[i] = (RestrictionEntry) parcelables[i];
    512             }
    513         }
    514     }
    515 
    516     @Override
    517     public int describeContents() {
    518         return 0;
    519     }
    520 
    521     @Override
    522     public void writeToParcel(Parcel dest, int flags) {
    523         dest.writeInt(mType);
    524         dest.writeString(mKey);
    525         dest.writeString(mTitle);
    526         dest.writeString(mDescription);
    527         dest.writeStringArray(mChoiceEntries);
    528         dest.writeStringArray(mChoiceValues);
    529         dest.writeString(mCurrentValue);
    530         dest.writeStringArray(mCurrentValues);
    531         dest.writeParcelableArray(mRestrictions, 0);
    532     }
    533 
    534     public static final Creator<RestrictionEntry> CREATOR = new Creator<RestrictionEntry>() {
    535         public RestrictionEntry createFromParcel(Parcel source) {
    536             return new RestrictionEntry(source);
    537         }
    538 
    539         public RestrictionEntry[] newArray(int size) {
    540             return new RestrictionEntry[size];
    541         }
    542     };
    543 
    544     @Override
    545     public String toString() {
    546         return "RestrictionEntry{" +
    547                 "mType=" + mType +
    548                 ", mKey='" + mKey + '\'' +
    549                 ", mTitle='" + mTitle + '\'' +
    550                 ", mDescription='" + mDescription + '\'' +
    551                 ", mChoiceEntries=" + Arrays.toString(mChoiceEntries) +
    552                 ", mChoiceValues=" + Arrays.toString(mChoiceValues) +
    553                 ", mCurrentValue='" + mCurrentValue + '\'' +
    554                 ", mCurrentValues=" + Arrays.toString(mCurrentValues) +
    555                 ", mRestrictions=" + Arrays.toString(mRestrictions) +
    556                 '}';
    557     }
    558 }
    559