1/*
2 * Copyright (C) 2016 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 com.android.tv.settings.system.development;
18
19import android.content.res.TypedArray;
20import android.os.Bundle;
21import android.provider.Settings;
22import android.support.annotation.Keep;
23import android.support.v17.preference.LeanbackPreferenceFragment;
24import android.support.v7.preference.ListPreference;
25import android.support.v7.preference.Preference;
26import android.support.v7.preference.TwoStatePreference;
27import android.text.TextUtils;
28
29import com.android.tv.settings.R;
30
31@Keep
32public class CaptionCustomFragment extends LeanbackPreferenceFragment implements
33        Preference.OnPreferenceChangeListener {
34
35    private static final String KEY_FONT_FAMILY = "font_family";
36    private static final String KEY_TEXT_COLOR = "text_color";
37    private static final String KEY_TEXT_OPACITY = "text_opacity";
38    private static final String KEY_EDGE_TYPE = "edge_type";
39    private static final String KEY_EDGE_COLOR = "edge_color";
40    private static final String KEY_BACKGROUND_SHOW = "background_show";
41    private static final String KEY_BACKGROUND_COLOR = "background_color";
42    private static final String KEY_BACKGROUND_OPACITY = "background_opacity";
43    private static final String KEY_WINDOW_SHOW = "window_show";
44    private static final String KEY_WINDOW_COLOR = "window_color";
45    private static final String KEY_WINDOW_OPACITY = "window_opacity";
46
47    private ListPreference mFontFamilyPref;
48    private ListPreference mTextColorPref;
49    private ListPreference mTextOpacityPref;
50    private ListPreference mEdgeTypePref;
51    private ListPreference mEdgeColorPref;
52    private TwoStatePreference mBackgroundShowPref;
53    private ListPreference mBackgroundColorPref;
54    private ListPreference mBackgroundOpacityPref;
55    private TwoStatePreference mWindowShowPref;
56    private ListPreference mWindowColorPref;
57    private ListPreference mWindowOpacityPref;
58
59    @Override
60    public void onResume() {
61        super.onResume();
62        refresh();
63    }
64
65    @Override
66    public void onCreatePreferences(Bundle savedInstanceState, String rootKey) {
67        setPreferencesFromResource(R.xml.caption_custom, null);
68
69        final TypedArray ta =
70                getResources().obtainTypedArray(R.array.captioning_color_selector_ids);
71        final int colorLen = ta.length();
72        final String[] namedColors =
73                getResources().getStringArray(R.array.captioning_color_selector_titles);
74        final String[] colorNames = new String[colorLen];
75        final String[] colorValues = new String[colorLen];
76        for (int i = 0; i < colorLen; i++) {
77            final int color = ta.getColor(i, 0);
78            colorValues[i] = Integer.toHexString(color & 0x00ffffff);
79            if (i < namedColors.length) {
80                colorNames[i] = namedColors[i];
81            } else {
82                colorNames[i] = String.format("#%06X", color & 0x00ffffff);
83            }
84        }
85        ta.recycle();
86
87        mFontFamilyPref = (ListPreference) findPreference(KEY_FONT_FAMILY);
88        mFontFamilyPref.setOnPreferenceChangeListener(this);
89
90        mTextColorPref = (ListPreference) findPreference(KEY_TEXT_COLOR);
91        mTextColorPref.setEntries(colorNames);
92        mTextColorPref.setEntryValues(colorValues);
93        mTextColorPref.setOnPreferenceChangeListener(this);
94
95        mTextOpacityPref = (ListPreference) findPreference(KEY_TEXT_OPACITY);
96        mTextOpacityPref.setOnPreferenceChangeListener(this);
97        mEdgeTypePref = (ListPreference) findPreference(KEY_EDGE_TYPE);
98        mEdgeTypePref.setOnPreferenceChangeListener(this);
99
100        mEdgeColorPref = (ListPreference) findPreference(KEY_EDGE_COLOR);
101        mEdgeColorPref.setEntries(colorNames);
102        mEdgeColorPref.setEntryValues(colorValues);
103        mEdgeColorPref.setOnPreferenceChangeListener(this);
104
105        mBackgroundShowPref = (TwoStatePreference) findPreference(KEY_BACKGROUND_SHOW);
106
107        mBackgroundColorPref = (ListPreference) findPreference(KEY_BACKGROUND_COLOR);
108        mBackgroundColorPref.setEntries(colorNames);
109        mBackgroundColorPref.setEntryValues(colorValues);
110        mBackgroundColorPref.setOnPreferenceChangeListener(this);
111
112        mBackgroundOpacityPref = (ListPreference) findPreference(KEY_BACKGROUND_OPACITY);
113        mBackgroundOpacityPref.setOnPreferenceChangeListener(this);
114
115        mWindowShowPref = (TwoStatePreference) findPreference(KEY_WINDOW_SHOW);
116
117        mWindowColorPref = (ListPreference) findPreference(KEY_WINDOW_COLOR);
118        mWindowColorPref.setEntries(colorNames);
119        mWindowColorPref.setEntryValues(colorValues);
120        mWindowColorPref.setOnPreferenceChangeListener(this);
121
122        mWindowOpacityPref = (ListPreference) findPreference(KEY_WINDOW_OPACITY);
123        mWindowOpacityPref.setOnPreferenceChangeListener(this);
124    }
125
126    @Override
127    public boolean onPreferenceTreeClick(Preference preference) {
128        final String key = preference.getKey();
129        if (TextUtils.isEmpty(key)) {
130            return super.onPreferenceTreeClick(preference);
131        }
132        switch (key) {
133            case KEY_BACKGROUND_SHOW:
134                setCaptionsBackgroundVisible(((TwoStatePreference) preference).isChecked());
135                return true;
136            case KEY_WINDOW_SHOW:
137                setCaptionsWindowVisible(((TwoStatePreference) preference).isChecked());
138                return true;
139        }
140        return super.onPreferenceTreeClick(preference);
141    }
142
143    @Override
144    public boolean onPreferenceChange(Preference preference, Object newValue) {
145        final String key = preference.getKey();
146        if (TextUtils.isEmpty(key)) {
147            throw new IllegalStateException("Unknown preference change");
148        }
149        switch (key) {
150            case KEY_FONT_FAMILY:
151                setCaptionsFontFamily((String) newValue);
152                break;
153            case KEY_TEXT_COLOR:
154                setCaptionsTextColor((String) newValue);
155                break;
156            case KEY_TEXT_OPACITY:
157                setCaptionsTextOpacity((String) newValue);
158                break;
159            case KEY_EDGE_TYPE:
160                setCaptionsEdgeType((String) newValue);
161                break;
162            case KEY_EDGE_COLOR:
163                setCaptionsEdgeColor((String) newValue);
164                break;
165            case KEY_BACKGROUND_COLOR:
166                setCaptionsBackgroundColor((String) newValue);
167                break;
168            case KEY_BACKGROUND_OPACITY:
169                setCaptionsBackgroundOpacity((String) newValue);
170                break;
171            case KEY_WINDOW_COLOR:
172                setCaptionsWindowColor((String) newValue);
173                break;
174            case KEY_WINDOW_OPACITY:
175                setCaptionsWindowOpacity((String) newValue);
176                break;
177            default:
178                throw new IllegalStateException("Preference change with unknown key " + key);
179        }
180        return true;
181    }
182
183    private void refresh() {
184        mFontFamilyPref.setValue(getCaptionsFontFamily());
185        mTextColorPref.setValue(getCaptionsTextColor());
186        mTextOpacityPref.setValue(getCaptionsTextOpacity());
187        mEdgeTypePref.setValue(getCaptionsEdgeType());
188        mEdgeColorPref.setValue(getCaptionsEdgeColor());
189        mBackgroundShowPref.setChecked(isCaptionsBackgroundVisible());
190        mBackgroundColorPref.setValue(getCaptionsBackgroundColor());
191        mBackgroundOpacityPref.setValue(getCaptionsBackgroundOpacity());
192        mWindowShowPref.setChecked(isCaptionsWindowVisible());
193        mWindowColorPref.setValue(getCaptionsWindowColor());
194        mWindowOpacityPref.setValue(getCaptionsWindowOpacity());
195
196    }
197
198    private String getCaptionsFontFamily() {
199        final String typeface = Settings.Secure.getString(getContext().getContentResolver(),
200                Settings.Secure.ACCESSIBILITY_CAPTIONING_TYPEFACE);
201        return TextUtils.isEmpty(typeface) ? "default" : typeface;
202    }
203
204    private void setCaptionsFontFamily(String fontFamily) {
205        if (TextUtils.equals(fontFamily, "default")) {
206            Settings.Secure.putString(getContext().getContentResolver(),
207                    Settings.Secure.ACCESSIBILITY_CAPTIONING_TYPEFACE, null);
208        } else {
209            Settings.Secure.putString(getContext().getContentResolver(),
210                    Settings.Secure.ACCESSIBILITY_CAPTIONING_TYPEFACE, fontFamily);
211        }
212    }
213
214    private String getCaptionsTextColor() {
215        return Integer.toHexString(Settings.Secure.getInt(getContext().getContentResolver(),
216                Settings.Secure.ACCESSIBILITY_CAPTIONING_FOREGROUND_COLOR, 0) & 0x00ffffff);
217    }
218
219    private void setCaptionsTextColor(String textColor) {
220        final int color = (int) Long.parseLong(textColor, 16) & 0x00ffffff;
221        final int alpha = Settings.Secure.getInt(getContext().getContentResolver(),
222                Settings.Secure.ACCESSIBILITY_CAPTIONING_FOREGROUND_COLOR, 0xff000000) & 0xff000000;
223        Settings.Secure.putInt(getContext().getContentResolver(),
224                Settings.Secure.ACCESSIBILITY_CAPTIONING_FOREGROUND_COLOR, color | alpha);
225    }
226
227    private String getCaptionsTextOpacity() {
228        return opacityToString(Settings.Secure.getInt(getContext().getContentResolver(),
229                Settings.Secure.ACCESSIBILITY_CAPTIONING_FOREGROUND_COLOR, 0) & 0xff000000);
230    }
231
232    private void setCaptionsTextOpacity(String textOpacity) {
233        final int color = Settings.Secure.getInt(getContext().getContentResolver(),
234                Settings.Secure.ACCESSIBILITY_CAPTIONING_FOREGROUND_COLOR, 0) & 0x00ffffff;
235        final int alpha = (int) Long.parseLong(textOpacity, 16) & 0xff000000;
236        Settings.Secure.putInt(getContext().getContentResolver(),
237                Settings.Secure.ACCESSIBILITY_CAPTIONING_FOREGROUND_COLOR, color | alpha);
238    }
239
240    private String getCaptionsEdgeType() {
241        return Integer.toString(Settings.Secure.getInt(getContext().getContentResolver(),
242                Settings.Secure.ACCESSIBILITY_CAPTIONING_EDGE_TYPE, 0));
243    }
244
245    private void setCaptionsEdgeType(String edgeType) {
246        Settings.Secure.putInt(getContext().getContentResolver(),
247                Settings.Secure.ACCESSIBILITY_CAPTIONING_EDGE_TYPE, Integer.parseInt(edgeType));
248    }
249
250    private String getCaptionsEdgeColor() {
251        return Integer.toHexString(Settings.Secure.getInt(getContext().getContentResolver(),
252                Settings.Secure.ACCESSIBILITY_CAPTIONING_EDGE_COLOR, 0) & 0x00ffffff);
253    }
254
255    private void setCaptionsEdgeColor(String edgeColor) {
256        Settings.Secure.putInt(getContext().getContentResolver(),
257                Settings.Secure.ACCESSIBILITY_CAPTIONING_EDGE_COLOR,
258                0xff000000 | (int) Long.parseLong(edgeColor, 16));
259    }
260
261    private boolean isCaptionsBackgroundVisible() {
262        return (Settings.Secure.getInt(getContext().getContentResolver(),
263                Settings.Secure.ACCESSIBILITY_CAPTIONING_BACKGROUND_COLOR, 0) & 0xff000000) != 0;
264    }
265
266    private void setCaptionsBackgroundVisible(boolean visible) {
267        Settings.Secure.putInt(getContext().getContentResolver(),
268                Settings.Secure.ACCESSIBILITY_CAPTIONING_BACKGROUND_COLOR,
269                visible ? 0xff000000 : 0);
270        if (!visible) {
271            mBackgroundColorPref.setValue(Integer.toHexString(0));
272            mBackgroundOpacityPref.setValue(opacityToString(0));
273        }
274    }
275
276    private String getCaptionsBackgroundColor() {
277        return Integer.toHexString(Settings.Secure.getInt(getContext().getContentResolver(),
278                Settings.Secure.ACCESSIBILITY_CAPTIONING_BACKGROUND_COLOR, 0) & 0x00ffffff);
279    }
280
281    private void setCaptionsBackgroundColor(String backgroundColor) {
282        final int color = (int) Long.parseLong(backgroundColor, 16) & 0x00ffffff;
283        final int alpha = Settings.Secure.getInt(getContext().getContentResolver(),
284                Settings.Secure.ACCESSIBILITY_CAPTIONING_BACKGROUND_COLOR, 0xff000000) & 0xff000000;
285        Settings.Secure.putInt(getContext().getContentResolver(),
286                Settings.Secure.ACCESSIBILITY_CAPTIONING_BACKGROUND_COLOR, color | alpha);
287    }
288
289    private String getCaptionsBackgroundOpacity() {
290        return opacityToString (Settings.Secure.getInt(getContext().getContentResolver(),
291                Settings.Secure.ACCESSIBILITY_CAPTIONING_BACKGROUND_COLOR, 0) & 0xff000000);
292    }
293
294    private void setCaptionsBackgroundOpacity(String backgroundOpacity) {
295        final int color = Settings.Secure.getInt(getContext().getContentResolver(),
296                Settings.Secure.ACCESSIBILITY_CAPTIONING_BACKGROUND_COLOR, 0) & 0x00ffffff;
297        final int alpha = (int) Long.parseLong(backgroundOpacity, 16) & 0xff000000;
298        Settings.Secure.putInt(getContext().getContentResolver(),
299                Settings.Secure.ACCESSIBILITY_CAPTIONING_BACKGROUND_COLOR, color | alpha);
300    }
301
302    private boolean isCaptionsWindowVisible() {
303        return (Settings.Secure.getInt(getContext().getContentResolver(),
304                Settings.Secure.ACCESSIBILITY_CAPTIONING_WINDOW_COLOR, 0) & 0xff000000) != 0;
305    }
306
307    private void setCaptionsWindowVisible(boolean visible) {
308        Settings.Secure.putInt(getContext().getContentResolver(),
309                Settings.Secure.ACCESSIBILITY_CAPTIONING_WINDOW_COLOR, visible ? 0xff000000 : 0);
310        if (!visible) {
311            mWindowColorPref.setValue(Integer.toHexString(0));
312            mWindowOpacityPref.setValue(opacityToString(0));
313        }
314    }
315
316    private String getCaptionsWindowColor() {
317        return Integer.toHexString(Settings.Secure.getInt(getContext().getContentResolver(),
318                Settings.Secure.ACCESSIBILITY_CAPTIONING_WINDOW_COLOR, 0) & 0x00ffffff);
319    }
320
321    private void setCaptionsWindowColor(String windowColor) {
322        final int color = (int) Long.parseLong(windowColor, 16) & 0x00ffffff;
323        final int alpha = Settings.Secure.getInt(getContext().getContentResolver(),
324                Settings.Secure.ACCESSIBILITY_CAPTIONING_WINDOW_COLOR, 0xff000000) & 0xff000000;
325        Settings.Secure.putInt(getContext().getContentResolver(),
326                Settings.Secure.ACCESSIBILITY_CAPTIONING_WINDOW_COLOR, color | alpha);
327    }
328
329    private String getCaptionsWindowOpacity() {
330        return opacityToString(Settings.Secure.getInt(getContext().getContentResolver(),
331                Settings.Secure.ACCESSIBILITY_CAPTIONING_WINDOW_COLOR, 0) & 0xff000000);
332    }
333
334    private void setCaptionsWindowOpacity(String windowOpacity) {
335        final int color = Settings.Secure.getInt(getContext().getContentResolver(),
336                Settings.Secure.ACCESSIBILITY_CAPTIONING_WINDOW_COLOR, 0) & 0x00ffffff;
337        final int alpha = (int) Long.parseLong(windowOpacity, 16) & 0xff000000;
338        Settings.Secure.putInt(getContext().getContentResolver(),
339                Settings.Secure.ACCESSIBILITY_CAPTIONING_WINDOW_COLOR, color | alpha);
340    }
341
342    private String opacityToString(int opacity) {
343        switch (opacity & 0xff000000) {
344            case 0x40000000:
345                return "40FFFFFF";
346            case 0x80000000:
347                return "80FFFFFF";
348            case 0xc0000000:
349                return "C0FFFFFF";
350            case 0xff000000:
351            default:
352                return "FFFFFFFF";
353        }
354    }
355}
356