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