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