1 /*
2  * Copyright (C) 2015 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 com.android.tv.util;
18 
19 import android.content.Context;
20 import android.preference.PreferenceManager;
21 import android.support.annotation.IntDef;
22 
23 import java.lang.annotation.Retention;
24 import java.lang.annotation.RetentionPolicy;
25 import java.util.Collections;
26 import java.util.HashSet;
27 import java.util.Set;
28 
29 
30 /**
31  * A class about the constants for TV settings.
32  * Objects that are returned from the various {@code get} methods must be treated as immutable.
33  */
34 public final class TvSettings {
TvSettings()35     private TvSettings() {}
36 
37     public static final String PREF_DISPLAY_MODE = "display_mode";  // int value
38     public static final String PREF_PIP_LAYOUT = "pip_layout"; // int value
39     public static final String PREF_PIP_SIZE = "pip_size";  // int value
40     public static final String PREF_PIN = "pin"; // 4-digit string value. Otherwise, it's not set.
41 
42     // PIP sounds
43     @Retention(RetentionPolicy.SOURCE)
44     @IntDef({
45             PIP_SOUND_MAIN, PIP_SOUND_PIP_WINDOW })
46     public @interface PipSound {}
47     public static final int PIP_SOUND_MAIN = 0;
48     public static final int PIP_SOUND_PIP_WINDOW = PIP_SOUND_MAIN + 1;
49 
50     // PIP layouts
51     @Retention(RetentionPolicy.SOURCE)
52     @IntDef({
53             PIP_LAYOUT_BOTTOM_RIGHT, PIP_LAYOUT_TOP_RIGHT, PIP_LAYOUT_TOP_LEFT,
54             PIP_LAYOUT_BOTTOM_LEFT, PIP_LAYOUT_SIDE_BY_SIDE })
55     public @interface PipLayout {}
56     public static final int PIP_LAYOUT_BOTTOM_RIGHT = 0;
57     public static final int PIP_LAYOUT_TOP_RIGHT = PIP_LAYOUT_BOTTOM_RIGHT + 1;
58     public static final int PIP_LAYOUT_TOP_LEFT = PIP_LAYOUT_TOP_RIGHT + 1;
59     public static final int PIP_LAYOUT_BOTTOM_LEFT = PIP_LAYOUT_TOP_LEFT + 1;
60     public static final int PIP_LAYOUT_SIDE_BY_SIDE = PIP_LAYOUT_BOTTOM_LEFT + 1;
61     public static final int PIP_LAYOUT_LAST = PIP_LAYOUT_SIDE_BY_SIDE;
62 
63     // PIP sizes
64     @Retention(RetentionPolicy.SOURCE)
65     @IntDef({ PIP_SIZE_SMALL, PIP_SIZE_BIG })
66     public @interface PipSize {}
67     public static final int PIP_SIZE_SMALL = 0;
68     public static final int PIP_SIZE_BIG = PIP_SIZE_SMALL + 1;
69     public static final int PIP_SIZE_LAST = PIP_SIZE_BIG;
70 
71     // Multi-track audio settings
72     private static final String PREF_MULTI_AUDIO_ID = "pref.multi_audio_id";
73     private static final String PREF_MULTI_AUDIO_LANGUAGE = "pref.multi_audio_language";
74     private static final String PREF_MULTI_AUDIO_CHANNEL_COUNT = "pref.multi_audio_channel_count";
75 
76     // Parental Control settings
77     private static final String PREF_CONTENT_RATING_SYSTEMS = "pref.content_rating_systems";
78     private static final String PREF_CONTENT_RATING_LEVEL = "pref.content_rating_level";
79     private static final String PREF_DISABLE_PIN_UNTIL = "pref.disable_pin_until";
80 
81     @Retention(RetentionPolicy.SOURCE)
82     @IntDef({
83             CONTENT_RATING_LEVEL_NONE, CONTENT_RATING_LEVEL_HIGH, CONTENT_RATING_LEVEL_MEDIUM,
84             CONTENT_RATING_LEVEL_LOW, CONTENT_RATING_LEVEL_CUSTOM })
85     public @interface ContentRatingLevel {}
86     public static final int CONTENT_RATING_LEVEL_NONE = 0;
87     public static final int CONTENT_RATING_LEVEL_HIGH = 1;
88     public static final int CONTENT_RATING_LEVEL_MEDIUM = 2;
89     public static final int CONTENT_RATING_LEVEL_LOW = 3;
90     public static final int CONTENT_RATING_LEVEL_CUSTOM = 4;
91 
92     // PIP settings
93     /**
94      * Returns the layout of the PIP window stored in the shared preferences.
95      *
96      * @return the saved layout of the PIP window. This value is one of
97      *         {@link #PIP_LAYOUT_TOP_LEFT}, {@link #PIP_LAYOUT_TOP_RIGHT},
98      *         {@link #PIP_LAYOUT_BOTTOM_LEFT}, {@link #PIP_LAYOUT_BOTTOM_RIGHT} and
99      *         {@link #PIP_LAYOUT_SIDE_BY_SIDE}. If the preference value does not exist,
100      *         {@link #PIP_LAYOUT_BOTTOM_RIGHT} is returned.
101      */
102     @SuppressWarnings("ResourceType")
103     @PipLayout
getPipLayout(Context context)104     public static int getPipLayout(Context context) {
105         return PreferenceManager.getDefaultSharedPreferences(context).getInt(
106                 PREF_PIP_LAYOUT, PIP_LAYOUT_BOTTOM_RIGHT);
107     }
108 
109     /**
110      * Stores the layout of PIP window to the shared preferences.
111      *
112      * @param pipLayout This value should be one of {@link #PIP_LAYOUT_TOP_LEFT},
113      *            {@link #PIP_LAYOUT_TOP_RIGHT}, {@link #PIP_LAYOUT_BOTTOM_LEFT},
114      *            {@link #PIP_LAYOUT_BOTTOM_RIGHT} and {@link #PIP_LAYOUT_SIDE_BY_SIDE}.
115      */
setPipLayout(Context context, @PipLayout int pipLayout)116     public static void setPipLayout(Context context, @PipLayout int pipLayout) {
117         PreferenceManager.getDefaultSharedPreferences(context).edit().putInt(
118                 PREF_PIP_LAYOUT, pipLayout).apply();
119     }
120 
121     /**
122      * Returns the size of the PIP view stored in the shared preferences.
123      *
124      * @return the saved size of the PIP view. This value is one of
125      *         {@link #PIP_SIZE_SMALL} and {@link #PIP_SIZE_BIG}. If the preference value does not
126      *         exist, {@link #PIP_SIZE_SMALL} is returned.
127      */
128     @SuppressWarnings("ResourceType")
129     @PipSize
getPipSize(Context context)130     public static int getPipSize(Context context) {
131         return PreferenceManager.getDefaultSharedPreferences(context).getInt(
132                 PREF_PIP_SIZE, PIP_SIZE_SMALL);
133     }
134 
135     /**
136      * Stores the size of PIP view to the shared preferences.
137      *
138      * @param pipSize This value should be one of {@link #PIP_SIZE_SMALL} and {@link #PIP_SIZE_BIG}.
139      */
setPipSize(Context context, @PipSize int pipSize)140     public static void setPipSize(Context context, @PipSize int pipSize) {
141         PreferenceManager.getDefaultSharedPreferences(context).edit().putInt(
142                 PREF_PIP_SIZE, pipSize).apply();
143     }
144 
145     // Multi-track audio settings
getMultiAudioId(Context context)146     public static String getMultiAudioId(Context context) {
147         return PreferenceManager.getDefaultSharedPreferences(context).getString(
148                 PREF_MULTI_AUDIO_ID, null);
149     }
150 
setMultiAudioId(Context context, String language)151     public static void setMultiAudioId(Context context, String language) {
152         PreferenceManager.getDefaultSharedPreferences(context).edit().putString(
153                 PREF_MULTI_AUDIO_ID, language).apply();
154     }
155 
getMultiAudioLanguage(Context context)156     public static String getMultiAudioLanguage(Context context) {
157         return PreferenceManager.getDefaultSharedPreferences(context).getString(
158                 PREF_MULTI_AUDIO_LANGUAGE, null);
159     }
160 
setMultiAudioLanguage(Context context, String language)161     public static void setMultiAudioLanguage(Context context, String language) {
162         PreferenceManager.getDefaultSharedPreferences(context).edit().putString(
163                 PREF_MULTI_AUDIO_LANGUAGE, language).apply();
164     }
165 
getMultiAudioChannelCount(Context context)166     public static int getMultiAudioChannelCount(Context context) {
167         return PreferenceManager.getDefaultSharedPreferences(context).getInt(
168                 PREF_MULTI_AUDIO_CHANNEL_COUNT, 0);
169     }
170 
setMultiAudioChannelCount(Context context, int channelCount)171     public static void setMultiAudioChannelCount(Context context, int channelCount) {
172         PreferenceManager.getDefaultSharedPreferences(context).edit().putInt(
173                 PREF_MULTI_AUDIO_CHANNEL_COUNT, channelCount).apply();
174     }
175 
176     // Parental Control settings
addContentRatingSystems(Context context, Set<String> ids)177     public static void addContentRatingSystems(Context context, Set<String> ids) {
178         Set<String> contentRatingSystemSet = getContentRatingSystemSet(context);
179         if (contentRatingSystemSet.addAll(ids)) {
180             PreferenceManager.getDefaultSharedPreferences(context).edit()
181                     .putStringSet(PREF_CONTENT_RATING_SYSTEMS, contentRatingSystemSet).apply();
182         }
183     }
184 
addContentRatingSystem(Context context, String id)185     public static void addContentRatingSystem(Context context, String id) {
186         Set<String> contentRatingSystemSet = getContentRatingSystemSet(context);
187         if (contentRatingSystemSet.add(id)) {
188             PreferenceManager.getDefaultSharedPreferences(context).edit()
189                     .putStringSet(PREF_CONTENT_RATING_SYSTEMS, contentRatingSystemSet).apply();
190         }
191     }
192 
removeContentRatingSystems(Context context, Set<String> ids)193     public static void removeContentRatingSystems(Context context, Set<String> ids) {
194         Set<String> contentRatingSystemSet = getContentRatingSystemSet(context);
195         if (contentRatingSystemSet.removeAll(ids)) {
196             PreferenceManager.getDefaultSharedPreferences(context).edit()
197                     .putStringSet(PREF_CONTENT_RATING_SYSTEMS, contentRatingSystemSet).apply();
198         }
199     }
200 
removeContentRatingSystem(Context context, String id)201     public static void removeContentRatingSystem(Context context, String id) {
202         Set<String> contentRatingSystemSet = getContentRatingSystemSet(context);
203         if (contentRatingSystemSet.remove(id)) {
204             PreferenceManager.getDefaultSharedPreferences(context).edit()
205                     .putStringSet(PREF_CONTENT_RATING_SYSTEMS, contentRatingSystemSet).apply();
206         }
207     }
208 
hasContentRatingSystem(Context context, String id)209     public static boolean hasContentRatingSystem(Context context, String id) {
210         return getContentRatingSystemSet(context).contains(id);
211     }
212 
213     /**
214      * Returns whether the content rating system is ever set. Returns {@code false} only when the
215      * user changes parental control settings for the first time.
216      */
isContentRatingSystemSet(Context context)217     public static boolean isContentRatingSystemSet(Context context) {
218         return PreferenceManager.getDefaultSharedPreferences(context)
219                 .getStringSet(PREF_CONTENT_RATING_SYSTEMS, null) != null;
220     }
221 
getContentRatingSystemSet(Context context)222     private static Set<String> getContentRatingSystemSet(Context context) {
223         return new HashSet<>(PreferenceManager.getDefaultSharedPreferences(context)
224                 .getStringSet(PREF_CONTENT_RATING_SYSTEMS, Collections.emptySet()));
225     }
226 
227     @ContentRatingLevel
228     @SuppressWarnings("ResourceType")
getContentRatingLevel(Context context)229     public static int getContentRatingLevel(Context context) {
230         return PreferenceManager.getDefaultSharedPreferences(context).getInt(
231                 PREF_CONTENT_RATING_LEVEL, CONTENT_RATING_LEVEL_NONE);
232     }
233 
setContentRatingLevel(Context context, @ContentRatingLevel int level)234     public static void setContentRatingLevel(Context context,
235             @ContentRatingLevel int level) {
236         PreferenceManager.getDefaultSharedPreferences(context).edit().putInt(
237                 PREF_CONTENT_RATING_LEVEL, level).apply();
238     }
239 
240     /**
241      * Returns the time until we should disable the PIN dialog (because the user input wrong PINs
242      * repeatedly).
243      */
getDisablePinUntil(Context context)244     public static long getDisablePinUntil(Context context) {
245         return PreferenceManager.getDefaultSharedPreferences(context).getLong(
246                 PREF_DISABLE_PIN_UNTIL, 0);
247     }
248 
249     /**
250      * Saves the time until we should disable the PIN dialog (because the user input wrong PINs
251      * repeatedly).
252      */
setDisablePinUntil(Context context, long timeMillis)253     public static void setDisablePinUntil(Context context, long timeMillis) {
254         PreferenceManager.getDefaultSharedPreferences(context).edit().putLong(
255                 PREF_DISABLE_PIN_UNTIL, timeMillis).apply();
256     }
257 }
258