RestrictionEntry.java revision f20d640fa2b155a971ddfe0965fc803a73b5e53c
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
17package android.content;
18
19import android.os.Parcel;
20import 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 */
32public 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    /** The type of restriction. */
83    private int mType;
84
85    /** The unique key that identifies the restriction. */
86    private String mKey;
87
88    /** The user-visible title of the restriction. */
89    private String mTitle;
90
91    /** The user-visible secondary description of the restriction. */
92    private String mDescription;
93
94    /** The user-visible set of choices used for single-select and multi-select lists. */
95    private String [] mChoiceEntries;
96
97    /** The values corresponding to the user-visible choices. The value(s) of this entry will
98     * one or more of these, returned by {@link #getAllSelectedStrings()} and
99     * {@link #getSelectedString()}.
100     */
101    private String [] mChoiceValues;
102
103    /* The chosen value, whose content depends on the type of the restriction. */
104    private String mCurrentValue;
105
106    /* List of selected choices in the multi-select case. */
107    private String[] mCurrentValues;
108
109    /**
110     * Constructor for {@link #TYPE_CHOICE} type.
111     * @param key the unique key for this restriction
112     * @param selectedString the current value
113     */
114    public RestrictionEntry(String key, String selectedString) {
115        this.mKey = key;
116        this.mType = TYPE_CHOICE;
117        this.mCurrentValue = selectedString;
118    }
119
120    /**
121     * Constructor for {@link #TYPE_BOOLEAN} type.
122     * @param key the unique key for this restriction
123     * @param selectedState whether this restriction is selected or not
124     */
125    public RestrictionEntry(String key, boolean selectedState) {
126        this.mKey = key;
127        this.mType = TYPE_BOOLEAN;
128        setSelectedState(selectedState);
129    }
130
131    /**
132     * Constructor for {@link #TYPE_MULTI_SELECT} type.
133     * @param key the unique key for this restriction
134     * @param selectedStrings the list of values that are currently selected
135     */
136    public RestrictionEntry(String key, String[] selectedStrings) {
137        this.mKey = key;
138        this.mType = TYPE_MULTI_SELECT;
139        this.mCurrentValues = selectedStrings;
140    }
141
142    /**
143     * Constructor for {@link #TYPE_INTEGER} type.
144     * @param key the unique key for this restriction
145     * @param selectedInt the integer value of the restriction
146     */
147    public RestrictionEntry(String key, int selectedInt) {
148        mKey = key;
149        mType = TYPE_INTEGER;
150        setIntValue(selectedInt);
151    }
152
153    /**
154     * Sets the type for this restriction.
155     * @param type the type for this restriction.
156     */
157    public void setType(int type) {
158        this.mType = type;
159    }
160
161    /**
162     * Returns the type for this restriction.
163     * @return the type for this restriction
164     */
165    public int getType() {
166        return mType;
167    }
168
169    /**
170     * Returns the currently selected string value.
171     * @return the currently selected value, which can be null for types that aren't for holding
172     * single string values.
173     */
174    public String getSelectedString() {
175        return mCurrentValue;
176    }
177
178    /**
179     * Returns the list of currently selected values.
180     * @return the list of current selections, if type is {@link #TYPE_MULTI_SELECT},
181     *  null otherwise.
182     */
183    public String[] getAllSelectedStrings() {
184        return mCurrentValues;
185    }
186
187    /**
188     * Returns the current selected state for an entry of type {@link #TYPE_BOOLEAN}.
189     * @return the current selected state of the entry.
190     */
191    public boolean getSelectedState() {
192        return Boolean.parseBoolean(mCurrentValue);
193    }
194
195    /**
196     * Returns the value of the entry as an integer when the type is {@link #TYPE_INTEGER}.
197     * @return the integer value of the entry.
198     */
199    public int getIntValue() {
200        return Integer.parseInt(mCurrentValue);
201    }
202
203    /**
204     * Sets the integer value of the entry when the type is {@link #TYPE_INTEGER}.
205     * @param value the integer value to set.
206     */
207    public void setIntValue(int value) {
208        mCurrentValue = Integer.toString(value);
209    }
210
211    /**
212     * Sets the string value to use as the selected value for this restriction. This value will
213     * be persisted by the system for later use by the application.
214     * @param selectedString the string value to select.
215     */
216    public void setSelectedString(String selectedString) {
217        mCurrentValue = selectedString;
218    }
219
220    /**
221     * Sets the current selected state for an entry of type {@link #TYPE_BOOLEAN}. This value will
222     * be persisted by the system for later use by the application.
223     * @param state the current selected state
224     */
225    public void setSelectedState(boolean state) {
226        mCurrentValue = Boolean.toString(state);
227    }
228
229    /**
230     * Sets the current list of selected values for an entry of type {@link #TYPE_MULTI_SELECT}.
231     * These values will be persisted by the system for later use by the application.
232     * @param allSelectedStrings the current list of selected values.
233     */
234    public void setAllSelectedStrings(String[] allSelectedStrings) {
235        mCurrentValues = allSelectedStrings;
236    }
237
238    /**
239     * Sets a list of string values that can be selected by the user. If no user-visible entries
240     * are set by a call to {@link #setChoiceEntries(String[])}, these values will be the ones
241     * shown to the user. Values will be chosen from this list as the user's selection and the
242     * selected values can be retrieved by a call to {@link #getAllSelectedStrings()}, or
243     * {@link #getSelectedString()}, depending on whether it is a multi-select type or choice type.
244     * This method is not relevant for types other than
245     * {@link #TYPE_CHOICE}, and {@link #TYPE_MULTI_SELECT}.
246     * @param choiceValues an array of Strings which will be the selected values for the user's
247     * selections.
248     * @see #getChoiceValues()
249     * @see #getAllSelectedStrings()
250     */
251    public void setChoiceValues(String[] choiceValues) {
252        mChoiceValues = choiceValues;
253    }
254
255    /**
256     * Sets a list of string values that can be selected by the user, similar to
257     * {@link #setChoiceValues(String[])}.
258     * @param context the application context for retrieving the resources.
259     * @param stringArrayResId the resource id for a string array containing the possible values.
260     * @see #setChoiceValues(String[])
261     */
262    public void setChoiceValues(Context context, int stringArrayResId) {
263        mChoiceValues = context.getResources().getStringArray(stringArrayResId);
264    }
265
266    /**
267     * Returns the list of possible string values set earlier.
268     * @return the list of possible values.
269     */
270    public String[] getChoiceValues() {
271        return mChoiceValues;
272    }
273
274    /**
275     * Sets a list of strings that will be presented as choices to the user. When the
276     * user selects one or more of these choices, the corresponding value from the possible values
277     * are stored as the selected strings. The size of this array must match the size of the array
278     * set in {@link #setChoiceValues(String[])}. This method is not relevant for types other
279     * than {@link #TYPE_CHOICE}, and {@link #TYPE_MULTI_SELECT}.
280     * @param choiceEntries the list of user-visible choices.
281     * @see #setChoiceValues(String[])
282     */
283    public void setChoiceEntries(String[] choiceEntries) {
284        mChoiceEntries = choiceEntries;
285    }
286
287    /** Sets a list of strings that will be presented as choices to the user. This is similar to
288     * {@link #setChoiceEntries(String[])}.
289     * @param context the application context, used for retrieving the resources.
290     * @param stringArrayResId the resource id of a string array containing the possible entries.
291     */
292    public void setChoiceEntries(Context context, int stringArrayResId) {
293        mChoiceEntries = context.getResources().getStringArray(stringArrayResId);
294    }
295
296    /**
297     * Returns the list of strings, set earlier, that will be presented as choices to the user.
298     * @return the list of choices presented to the user.
299     */
300    public String[] getChoiceEntries() {
301        return mChoiceEntries;
302    }
303
304    /**
305     * Returns the provided user-visible description of the entry, if any.
306     * @return the user-visible description, null if none was set earlier.
307     */
308    public String getDescription() {
309        return mDescription;
310    }
311
312    /**
313     * Sets the user-visible description of the entry, as a possible sub-text for the title.
314     * You can use this to describe the entry in more detail or to display the current state of
315     * the restriction.
316     * @param description the user-visible description string.
317     */
318    public void setDescription(String description) {
319        this.mDescription = description;
320    }
321
322    /**
323     * This is the unique key for the restriction entry.
324     * @return the key for the restriction.
325     */
326    public String getKey() {
327        return mKey;
328    }
329
330    /**
331     * Returns the user-visible title for the entry, if any.
332     * @return the user-visible title for the entry, null if none was set earlier.
333     */
334    public String getTitle() {
335        return mTitle;
336    }
337
338    /**
339     * Sets the user-visible title for the entry.
340     * @param title the user-visible title for the entry.
341     */
342    public void setTitle(String title) {
343        this.mTitle = title;
344    }
345
346    private boolean equalArrays(String[] one, String[] other) {
347        if (one.length != other.length) return false;
348        for (int i = 0; i < one.length; i++) {
349            if (!one[i].equals(other[i])) return false;
350        }
351        return true;
352    }
353
354    @Override
355    public boolean equals(Object o) {
356        if (o == this) return true;
357        if (!(o instanceof RestrictionEntry)) return false;
358        final RestrictionEntry other = (RestrictionEntry) o;
359        // Make sure that either currentValue matches or currentValues matches.
360        return mType == other.mType && mKey.equals(other.mKey)
361                &&
362                ((mCurrentValues == null && other.mCurrentValues == null
363                  && mCurrentValue != null && mCurrentValue.equals(other.mCurrentValue))
364                 ||
365                 (mCurrentValue == null && other.mCurrentValue == null
366                  && mCurrentValues != null && equalArrays(mCurrentValues, other.mCurrentValues)));
367    }
368
369    @Override
370    public int hashCode() {
371        int result = 17;
372        result = 31 * result + mKey.hashCode();
373        if (mCurrentValue != null) {
374            result = 31 * result + mCurrentValue.hashCode();
375        } else if (mCurrentValues != null) {
376            for (String value : mCurrentValues) {
377                if (value != null) {
378                    result = 31 * result + value.hashCode();
379                }
380            }
381        }
382        return result;
383    }
384
385    private String[] readArray(Parcel in) {
386        int count = in.readInt();
387        String[] values = new String[count];
388        for (int i = 0; i < count; i++) {
389            values[i] = in.readString();
390        }
391        return values;
392    }
393
394    public RestrictionEntry(Parcel in) {
395        mType = in.readInt();
396        mKey = in.readString();
397        mTitle = in.readString();
398        mDescription = in.readString();
399        mChoiceEntries = readArray(in);
400        mChoiceValues = readArray(in);
401        mCurrentValue = in.readString();
402        mCurrentValues = readArray(in);
403    }
404
405    @Override
406    public int describeContents() {
407        return 0;
408    }
409
410    private void writeArray(Parcel dest, String[] values) {
411        if (values == null) {
412            dest.writeInt(0);
413        } else {
414            dest.writeInt(values.length);
415            for (int i = 0; i < values.length; i++) {
416                dest.writeString(values[i]);
417            }
418        }
419    }
420
421    @Override
422    public void writeToParcel(Parcel dest, int flags) {
423        dest.writeInt(mType);
424        dest.writeString(mKey);
425        dest.writeString(mTitle);
426        dest.writeString(mDescription);
427        writeArray(dest, mChoiceEntries);
428        writeArray(dest, mChoiceValues);
429        dest.writeString(mCurrentValue);
430        writeArray(dest, mCurrentValues);
431    }
432
433    public static final Creator<RestrictionEntry> CREATOR = new Creator<RestrictionEntry>() {
434        public RestrictionEntry createFromParcel(Parcel source) {
435            return new RestrictionEntry(source);
436        }
437
438        public RestrictionEntry[] newArray(int size) {
439            return new RestrictionEntry[size];
440        }
441    };
442
443    @Override
444    public String toString() {
445        return "RestrictionsEntry {type=" + mType + ", key=" + mKey + ", value=" + mCurrentValue + "}";
446    }
447}
448