• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (C) 2014 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.settings.system;
18 
19 import com.android.tv.settings.dialog.old.Action;
20 import com.android.tv.settings.dialog.old.ActionFragment;
21 import com.android.tv.settings.dialog.old.ActionAdapter;
22 
23 import com.android.tv.settings.BaseSettingsActivity;
24 import com.android.tv.settings.ActionBehavior;
25 import com.android.tv.settings.ActionKey;
26 import com.android.tv.settings.R;
27 import com.android.tv.settings.util.SettingsHelper;
28 
29 import android.view.accessibility.CaptioningManager;
30 
31 import android.provider.Settings;
32 
33 import android.os.Bundle;
34 import android.content.ContentResolver;
35 import android.content.Context;
36 import android.content.res.Resources;
37 import android.content.res.TypedArray;
38 import android.text.TextUtils;
39 import android.util.Log;
40 
41 import java.util.ArrayList;
42 import java.util.Arrays;
43 import java.util.Locale;
44 import java.text.Collator;
45 
46 public class CaptionSetupActivity extends BaseSettingsActivity implements ActionAdapter.Listener,
47                                   ActionAdapter.OnFocusListener {
48 
49     private static final String TAG = "CaptionSetupActivity";
50     private static final boolean DEBUG = false;
51 
52     private Resources mResources;
53     private SettingsHelper mHelper;
54     private boolean mDisplayEnabled;
55     private String mNone;
56 
57     private String mLanguage;
58     private String mLanguageName;
59     private String[] mLanguageLocales;
60     private String[] mLanguageNames;
61 
62     private String mTextSize;
63     private String mTextSizeName;
64     private String[] mTextSizes;
65     private String[] mTextSizeNames;
66 
67     private String mStyle;
68     private String mStyleName;
69     private String[] mStyles;
70     private String[] mStyleNames;
71 
72     private String mFontFamily;
73     private String mFontFamilyName;
74     private String[] mFontFamilies;
75     private String[] mFontFamilyNames;
76 
77     private int[] mColorResIds;
78     private int[] mColorRGBs;
79     private String[] mColorNames;
80 
81     private int mTextColor;
82     private String mTextColorName;
83 
84     private String mEdgeType;
85     private String mEdgeTypeName;
86     private String[] mEdgeTypes;
87     private String[] mEdgeTypeNames;
88 
89     private int mEdgeColor;
90     private String mEdgeColorName;
91 
92     private int mBackgroundColor;
93     private String mBackgroundColorName;
94 
95     private String mBackgroundOpacity;
96     private String mBackgroundOpacityName;
97     private String[] mOpacities;
98     private String[] mOpacityNames;
99 
100     private String mTextOpacity;
101     private String mTextOpacityName;
102 
103     private boolean mWindowEnabled;
104     private int mWindowColor;
105     private String mWindowColorName;
106 
107     private String mWindowOpacity;
108     private String mWindowOpacityName;
109 
110     private CaptioningManager mCaptioningManager;
111 
112     @Override
onCreate(Bundle savedInstanceState)113     protected void onCreate(Bundle savedInstanceState) {
114         mResources = getResources();
115         mHelper = new SettingsHelper(this);
116         mActions = new ArrayList<Action>();
117         mCaptioningManager = (CaptioningManager) getSystemService(Context.CAPTIONING_SERVICE);
118 
119         mStyles = getIntArrayAsStringArray(R.array.captioning_preset_selector_values);
120 
121         mStyleNames = mResources.getStringArray(R.array.captioning_preset_selector_titles);
122 
123         mTextSizes = mResources.getStringArray(R.array.captioning_font_size_selector_values);
124         mTextSizeNames = mResources.getStringArray(R.array.captioning_font_size_selector_titles);
125 
126         getLanguages();
127 
128         mFontFamilies = mResources.getStringArray(R.array.captioning_typeface_selector_values);
129         mFontFamilyNames = mResources.getStringArray(R.array.captioning_typeface_selector_titles);
130 
131         getColorSelection();
132 
133         mEdgeTypes = getIntArrayAsStringArray (R.array.captioning_edge_type_selector_values);
134         mEdgeTypeNames = mResources.getStringArray(R.array.captioning_edge_type_selector_titles);
135 
136         mOpacities = getIntArrayAsStringArray(R.array.captioning_opacity_selector_values);
137         mOpacityNames = mResources.getStringArray(R.array.captioning_opacity_selector_titles);
138 
139         mNone = mResources.getString(R.string.accessibility_none);
140 
141         getCaptionSettings ();
142 
143         super.onCreate(savedInstanceState);
144 
145         mContentFragment = CaptionPreviewFragment.newInstance();
146         setContentFragment (mContentFragment);
147     }
148 
getIntArrayAsStringArray(int resourceId)149     private String[] getIntArrayAsStringArray(int resourceId) {
150         int[] a = mResources.getIntArray(resourceId);
151         String[] s = new String[a.length];
152         for (int i = 0; i < a.length; ++i)
153             s[i] = String.valueOf(a[i]);
154         return s;
155     }
156 
getColorSelection()157     private void getColorSelection() {
158         // Load the resource ids of the selectable colors.
159         TypedArray ar =
160             getApplicationContext().getResources().obtainTypedArray
161                 (R.array.captioning_color_selector_ids);
162         int len = ar.length();
163         mColorResIds = new int [len];
164         for (int i = 0; i < len; ++i)
165             mColorResIds [i] = ar.getResourceId(i, 0);
166         ar.recycle();
167         // Load the RGB values of the colors.
168         mColorRGBs = new int[len];
169         for (int i = 0; i < len; ++i)
170             mColorRGBs[i] = mResources.getColor(mColorResIds[i]) & 0xffffff;
171         // Initialize the color names that will be displayed to the user.
172         String[] colorNames = mResources.getStringArray(R.array.captioning_color_selector_titles);
173         mColorNames = new String[len];
174         for (int i = 0; i < colorNames.length; ++i) {
175             mColorNames[i] = colorNames[i];
176         }
177         for (int i = colorNames.length; i < len; ++i) {
178             mColorNames[i] = String.format("#%06X", mColorRGBs[i]);
179         }
180     }
181 
getColorName(int color)182     private String getColorName(int color) {
183         for (int x = 0; x < mColorRGBs.length; ++x)
184             if (mColorRGBs[x] == color)
185                 return mColorNames[x];
186         return "";
187     }
188 
getCaptionSettings()189     private void getCaptionSettings() {
190 
191         mDisplayEnabled = mCaptioningManager.isEnabled();
192 
193         mLanguage = mCaptioningManager.getRawLocale();
194         if (mLanguage != null)
195             mLanguageName = getLanguageName(mLanguage);
196 
197         mTextSize = getClosestValue(mCaptioningManager.getFontScale(), mTextSizes);
198         mTextSizeName = getTextSizeName(mTextSize);
199 
200         int style = mCaptioningManager.getRawUserStyle();
201         mStyle = String.valueOf (style);
202         mStyleName = getStyleName(mStyle);
203 
204         if (style == CaptioningManager.CaptionStyle.PRESET_CUSTOM) {
205             getCustomCaptionStyle();
206         }
207     }
208 
getClosestValue(float value, String[] values)209     private String getClosestValue(float value, String[] values) {
210         int ndx = -1;
211         float delta = 0;
212         for (int i = 0; i < values.length; ++i) {
213             float d = Math.abs(value - Float.parseFloat(values [i]));
214             if (ndx == -1 || d < delta) {
215                 ndx = i;
216                 delta = d;
217             }
218         }
219         if (ndx == -1) {
220             return "";
221         } else {
222             return values [ndx];
223         }
224     }
225 
getCustomCaptionStyle()226     private void getCustomCaptionStyle() {
227         CaptioningManager.CaptionStyle cs = mCaptioningManager.getUserStyle();
228 
229         mFontFamily = cs.mRawTypeface;
230         mFontFamilyName = getFontFamilyName(mFontFamily);
231 
232         mTextColor = cs.foregroundColor & 0xffffff;
233         mTextColorName = getColorName(mTextColor);
234 
235         mTextOpacity = getClosestValue(cs.foregroundColor | 0xffffff, mOpacities);
236         mTextOpacityName = getOpacityName(mTextOpacity);
237 
238         mEdgeType = Integer.toString (cs.edgeType);
239         mEdgeTypeName = getEdgeTypeName(mEdgeType);
240 
241         mEdgeColor = cs.edgeColor & 0xffffff;
242         mEdgeColorName = getColorName(mEdgeColor);
243 
244         mBackgroundColor = cs.backgroundColor & 0xffffff;
245         mBackgroundColorName = getColorName(mBackgroundColor);
246 
247         mBackgroundOpacity = getClosestValue(cs.backgroundColor | 0xffffff, mOpacities);
248         mBackgroundOpacityName = getOpacityName(mBackgroundOpacity);
249 
250         mWindowEnabled = cs.hasWindowColor() && (cs.windowColor & 0xff000000) != 0;
251         mWindowColor = cs.windowColor & 0xffffff;
252         if (mWindowEnabled) {
253             mWindowColorName = getColorName(mWindowColor);
254         } else {
255             mWindowColorName = mNone;
256         }
257         mWindowOpacity = getClosestValue(cs.windowColor | 0xffffff, mOpacities);
258         if (mWindowEnabled) {
259             mWindowOpacityName = getOpacityName(mWindowOpacity);
260         } else {
261             mWindowOpacityName = mNone;
262         }
263     }
264 
colorsToActions(int selectedColor)265     private void colorsToActions(int selectedColor) {
266         mActions.clear();
267         for (int i = 0; i < mColorResIds.length; ++i) {
268             mActions.add(
269                 new Action.Builder().key(Integer.toString(mColorRGBs[i]))
270                                     .drawableResource(mColorResIds[i])
271                                     .title(mColorNames[i])
272                                     .checked(selectedColor == mColorRGBs[i]).build());
273         }
274     }
275 
276     @Override
refreshActionList()277     protected void refreshActionList() {
278         if(mContentFragment instanceof CaptionPreviewFragment) {
279             ((CaptionPreviewFragment)mContentFragment).resetLivePreview();
280         }
281         mActions.clear();
282         switch ((ActionType) mState) {
283             case CAPTIONS_OVERVIEW:
284                 int statusResource = mDisplayEnabled ?
285                         R.string.captions_display_on : R.string.captions_display_off;
286                 mActions.add(ActionType.CAPTIONS_DISPLAY.toAction(
287                              mResources, mResources.getString(statusResource)));
288                 mActions.add(ActionType.CAPTIONS_CONFIGURE.toAction(mResources,
289                              mResources.getString(R.string.display_options)));
290                 break;
291             case CAPTIONS_DISPLAY:
292                 mActions.add(ActionBehavior.ON.toAction(ActionBehavior.getOnKey(
293                              ActionType.CAPTIONS_DISPLAY.name()), mResources, mDisplayEnabled));
294                 mActions.add(ActionBehavior.OFF.toAction(ActionBehavior.getOffKey(
295                              ActionType.CAPTIONS_DISPLAY.name()), mResources, ! mDisplayEnabled));
296                 break;
297             case CAPTIONS_CONFIGURE:
298                 mActions.add(ActionType.CAPTIONS_LANGUAGE.toAction(mResources, mLanguageName));
299                 mActions.add(ActionType.CAPTIONS_TEXTSIZE.toAction(mResources, mTextSizeName));
300                 mActions.add(ActionType.CAPTIONS_CAPTIONSTYLE.toAction(mResources, mStyleName));
301                 break;
302             case CAPTIONS_TEXTSIZE:
303                 mActions = Action.createActionsFromArrays(mTextSizes, mTextSizeNames);
304                 for (Action action : mActions) {
305                     action.setChecked(action.getKey().equals(mTextSize));
306                 }
307                 break;
308             case CAPTIONS_CAPTIONSTYLE:
309                 mActions = Action.createActionsFromArrays(mStyles, mStyleNames);
310                 for (Action action : mActions) {
311                     action.setChecked(action.getKey().equals(mStyle));
312                 }
313                 break;
314             case CAPTIONS_CUSTOMOPTIONS:
315                 mActions.add(ActionType.CAPTIONS_FONTFAMILY.toAction(mResources, mFontFamilyName));
316                 mActions.add(ActionType.CAPTIONS_TEXTCOLOR.toAction(mResources, mTextColorName));
317                 mActions.add(ActionType.CAPTIONS_TEXTOPACITY.toAction(mResources,
318                         mTextOpacityName));
319                 mActions.add(ActionType.CAPTIONS_EDGETYPE.toAction(mResources, mEdgeTypeName));
320                 mActions.add(ActionType.CAPTIONS_EDGECOLOR.toAction(mResources, mEdgeColorName));
321                 mActions.add(ActionType.CAPTIONS_BACKGROUNDCOLOR.toAction(mResources,
322                                mBackgroundColorName));
323                 mActions.add(ActionType.CAPTIONS_BACKGROUNDOPACITY.toAction(mResources,
324                                mBackgroundOpacityName));
325                 mActions.add(ActionType.CAPTIONS_WINDOWCOLOR.toAction(mResources,
326                         mWindowColorName));
327                 mActions.add(ActionType.CAPTIONS_WINDOWOPACITY.toAction(mResources,
328                         mWindowOpacityName, mWindowEnabled));
329                 break;
330             case CAPTIONS_LANGUAGE:
331                 mActions = Action.createActionsFromArrays(mLanguageLocales, mLanguageNames);
332                 for (Action action : mActions) {
333                     action.setChecked(action.getKey().equals(mLanguage));
334                 }
335                 break;
336             case CAPTIONS_FONTFAMILY:
337                 mActions = Action.createActionsFromArrays(mFontFamilies, mFontFamilyNames);
338                 for (Action action : mActions) {
339                     action.setChecked(action.getKey().equals(mFontFamily));
340                 }
341                 break;
342             case CAPTIONS_TEXTCOLOR:
343                 colorsToActions(mTextColor);
344                 break;
345             case CAPTIONS_TEXTOPACITY:
346                 mActions = Action.createActionsFromArrays(mOpacities, mOpacityNames);
347                 for (Action action : mActions) {
348                     action.setChecked(action.getKey().equals(mTextOpacity));
349                 }
350                 break;
351             case CAPTIONS_EDGETYPE:
352                 mActions = Action.createActionsFromArrays(mEdgeTypes, mEdgeTypeNames);
353                for (Action action : mActions) {
354                     action.setChecked(action.getKey().equals(mEdgeType));
355                 }
356                 break;
357             case CAPTIONS_EDGECOLOR:
358                 colorsToActions(mEdgeColor);
359                 break;
360             case CAPTIONS_BACKGROUNDCOLOR:
361                 colorsToActions(mBackgroundColor);
362                 break;
363             case CAPTIONS_BACKGROUNDOPACITY:
364                 mActions = Action.createActionsFromArrays(mOpacities, mOpacityNames);
365                 for (Action action : mActions) {
366                     action.setChecked(action.getKey().equals(mBackgroundOpacity));
367                 }
368                 break;
369             case CAPTIONS_WINDOWCOLOR:
370                 mActions.clear();
371                 mActions.add(
372                     new Action.Builder().key(mNone)
373                                         .drawableResource(mColorResIds[1])
374                                         .title(mNone)
375                                         .checked(!mWindowEnabled).build());
376                 for (int i = 0; i < mColorResIds.length; ++i) {
377                     mActions.add(
378                         new Action.Builder().key(Integer.toString(mColorRGBs[i]))
379                                             .drawableResource(mColorResIds[i])
380                                             .title(mColorNames[i])
381                                             .checked(mWindowEnabled && mWindowColor ==
382                                                     mColorRGBs[i]).build());
383                 }
384                 break;
385             case CAPTIONS_WINDOWOPACITY:
386                 mActions = Action.createActionsFromArrays(mOpacities, mOpacityNames);
387                 for (Action action : mActions) {
388                     action.setChecked(action.getKey().equals(mWindowOpacity));
389                 }
390                 break;
391         }
392     }
393 
394     @Override
updateView()395     protected void updateView() {
396         refreshActionList();
397         mActionFragment = ActionFragment.newInstance(mActions);
398         setActionFragment (mActionFragment);
399     }
400 
401     @Override
onActionFocused(Action action)402     public void onActionFocused(Action action) {
403         final String key = action.getKey();
404         switch ((ActionType) mState) {
405             case CAPTIONS_LANGUAGE:
406                 if(mContentFragment instanceof CaptionPreviewFragment) {
407                     ((CaptionPreviewFragment)mContentFragment).
408                         livePreviewLanguage(key);
409                 }
410                 break;
411             case CAPTIONS_TEXTSIZE:
412                 if(mContentFragment instanceof CaptionPreviewFragment) {
413                     ((CaptionPreviewFragment)mContentFragment).
414                         livePreviewFontScale(Float.parseFloat(key));
415                 }
416                 break;
417             case CAPTIONS_CAPTIONSTYLE:
418                 if(mContentFragment instanceof CaptionPreviewFragment) {
419                     ((CaptionPreviewFragment)mContentFragment).
420                         livePreviewCaptionStyle(Integer.parseInt(key));
421                 }
422                 break;
423             case CAPTIONS_FONTFAMILY:
424                 if(mContentFragment instanceof CaptionPreviewFragment) {
425                     ((CaptionPreviewFragment)mContentFragment).
426                         livePreviewFontFamily(key);
427                 }
428                 break;
429             case CAPTIONS_TEXTCOLOR:
430                 if(mContentFragment instanceof CaptionPreviewFragment) {
431                     ((CaptionPreviewFragment)mContentFragment).
432                         livePreviewTextColor(Integer.parseInt(key));
433                 }
434                 break;
435             case CAPTIONS_TEXTOPACITY:
436                 if(mContentFragment instanceof CaptionPreviewFragment) {
437                     ((CaptionPreviewFragment)mContentFragment).
438                         livePreviewTextOpacity(key);
439                 }
440                 break;
441             case CAPTIONS_EDGETYPE:
442                 if(mContentFragment instanceof CaptionPreviewFragment) {
443                     ((CaptionPreviewFragment)mContentFragment).
444                         livePreviewEdgeType(Integer.parseInt(key));
445                 }
446                 break;
447             case CAPTIONS_EDGECOLOR:
448                 if(mContentFragment instanceof CaptionPreviewFragment) {
449                     ((CaptionPreviewFragment)mContentFragment).
450                         livePreviewEdgeColor(Integer.parseInt(key));
451                 }
452                 break;
453             case CAPTIONS_BACKGROUNDCOLOR:
454                 if(mContentFragment instanceof CaptionPreviewFragment) {
455                     ((CaptionPreviewFragment)mContentFragment).
456                         livePreviewBackgroundColor(Integer.parseInt(key));
457                 }
458                 break;
459             case CAPTIONS_BACKGROUNDOPACITY:
460                 if(mContentFragment instanceof CaptionPreviewFragment) {
461                     ((CaptionPreviewFragment)mContentFragment).
462                         livePreviewBackgroundOpacity(key);
463                 }
464                 break;
465             case CAPTIONS_WINDOWCOLOR:
466                 if(mContentFragment instanceof CaptionPreviewFragment) {
467                     if (TextUtils.equals(key, mNone)) {
468                         ((CaptionPreviewFragment)mContentFragment).
469                             livePreviewWindowColorNone();
470                     } else {
471                         ((CaptionPreviewFragment)mContentFragment).
472                             livePreviewWindowColor(Integer.parseInt(key));
473                     }
474                 }
475                 break;
476             case CAPTIONS_WINDOWOPACITY:
477                 if(mContentFragment instanceof CaptionPreviewFragment) {
478                     ((CaptionPreviewFragment)mContentFragment).
479                         livePreviewWindowOpacity(key);
480                 }
481                 break;
482         }
483     }
484 
485     @Override
onActionClicked(Action action)486     public void onActionClicked(Action action) {
487         final String key = action.getKey();
488         switch ((ActionType) mState) {
489             case CAPTIONS_LANGUAGE:
490                 setLanguage(key);
491                 goBack();
492                 break;
493             case CAPTIONS_TEXTSIZE:
494                 setTextSize(key);
495                 goBack();
496                 break;
497             case CAPTIONS_CAPTIONSTYLE:
498                 setStyle(key);
499                 if (Integer.parseInt(key) == CaptioningManager.CaptionStyle.PRESET_CUSTOM) {
500                     setState(ActionType.CAPTIONS_CUSTOMOPTIONS, true);
501                 } else {
502                     goBack();
503                 }
504                 break;
505             case CAPTIONS_FONTFAMILY:
506                 setFontFamily(key);
507                 goBack();
508                 break;
509             case CAPTIONS_TEXTCOLOR:
510                 setTextColor(key);
511                 goBack();
512                 break;
513             case CAPTIONS_TEXTOPACITY:
514                 setTextOpacity(key);
515                 goBack();
516                 break;
517             case CAPTIONS_EDGETYPE:
518                 setEdgeType(key);
519                 goBack();
520                 break;
521             case CAPTIONS_EDGECOLOR:
522                 setEdgeColor(key);
523                 goBack();
524                 break;
525             case CAPTIONS_BACKGROUNDCOLOR:
526                 setBackgroundColor(key);
527                 goBack();
528                 break;
529             case CAPTIONS_BACKGROUNDOPACITY:
530                 setBackgroundOpacity(key);
531                 goBack();
532                 break;
533             case CAPTIONS_WINDOWCOLOR:
534                 setWindowColor(key);
535                 goBack();
536                 break;
537             case CAPTIONS_WINDOWOPACITY:
538                 setWindowOpacity(key);
539                 goBack();
540                 break;
541             default:
542                 ActionKey<ActionType, ActionBehavior> actionKey =
543                     new ActionKey<ActionType, ActionBehavior>(
544                         ActionType.class, ActionBehavior.class, action.getKey());
545                 final ActionType type = actionKey.getType();
546                 final ActionBehavior behavior = actionKey.getBehavior();
547                 if (behavior == null) {
548                     return;
549                 }
550                 switch (behavior) {
551                     case ON:
552                         setProperty(true);
553                         break;
554                     case OFF:
555                         setProperty(false);
556                         break;
557                     case INIT:
558                         setState(type, true);
559                         break;
560                 }
561                 break;
562         }
563     }
564 
565     @Override
getInitialState()566     protected Object getInitialState() {
567         return ActionType.CAPTIONS_OVERVIEW;
568     }
569 
570     @Override
setProperty(boolean enable)571     protected void setProperty(boolean enable) {
572         switch ((ActionType) mState) {
573             case CAPTIONS_DISPLAY:
574                 setEnabled(enable);
575                 break;
576         }
577         goBack();
578     }
579 
getTextSizeName(String textSize)580     private String getTextSizeName(String textSize) {
581         for (int i = 0; i < mTextSizes.length; ++i) {
582             if (mTextSizes [i] == textSize) {
583                 return mTextSizeNames [i];
584             }
585         }
586         return "";
587     }
588 
getStyleName(String style)589     private String getStyleName(String style) {
590         for (int i = 0; i < mStyles.length; ++i) {
591             if (mStyles [i] == style) {
592                 return mStyleNames [i];
593             }
594         }
595         return "";
596     }
597 
setEnabled(boolean enabled)598     private void setEnabled(boolean enabled) {
599         mDisplayEnabled = enabled;
600         final ContentResolver cr = getContentResolver();
601         Settings.Secure.putInt(cr, Settings.Secure.ACCESSIBILITY_CAPTIONING_ENABLED,
602                                enabled ? 1 : 0);
603     }
604 
setStyle(String style)605     private void setStyle(String style) {
606         mStyle = style;
607         mStyleName = getStyleName(style);
608         final ContentResolver cr = getContentResolver();
609         int s = Integer.parseInt(style);
610         Settings.Secure.putInt(cr, Settings.Secure.ACCESSIBILITY_CAPTIONING_PRESET, s);
611         if (s == CaptioningManager.CaptionStyle.PRESET_CUSTOM) {
612             getCustomCaptionStyle();
613         }
614         if(mContentFragment instanceof CaptionPreviewFragment) {
615             ((CaptionPreviewFragment)mContentFragment).refreshPreviewText();
616         }
617     }
618 
setTextSize(String textSize)619     private void setTextSize(String textSize) {
620         mTextSize = textSize;
621         mTextSizeName = getTextSizeName(textSize);
622         final ContentResolver cr = getContentResolver();
623         Settings.Secure.putFloat(cr, Settings.Secure.ACCESSIBILITY_CAPTIONING_FONT_SCALE,
624                                  Float.parseFloat(textSize));
625     }
626 
setLanguage(String language)627     private void setLanguage(String language) {
628         mLanguage = language;
629         mLanguageName = getLanguageName(language);
630         final ContentResolver cr = getContentResolver();
631         Settings.Secure.putString(cr, Settings.Secure.ACCESSIBILITY_CAPTIONING_LOCALE, language);
632     }
633 
setFontFamily(String fontFamily)634     private void setFontFamily(String fontFamily) {
635         mFontFamily = fontFamily;
636         mFontFamilyName = getFontFamilyName(fontFamily);
637         final ContentResolver cr = getContentResolver();
638         Settings.Secure.putString(cr, Settings.Secure.ACCESSIBILITY_CAPTIONING_TYPEFACE,
639                                   fontFamily);
640     }
641 
setTextColor(String textColor)642     private void setTextColor(String textColor) {
643         mTextColor = Integer.parseInt(textColor);
644         mTextColorName = getColorName(mTextColor);
645         updateCaptioningTextColor();
646     }
647 
setTextOpacity(String textOpacity)648     private void setTextOpacity(String textOpacity) {
649         mTextOpacity = textOpacity;
650         mTextOpacityName = getOpacityName(textOpacity);
651         updateCaptioningTextColor();
652     }
653 
updateCaptioningTextColor()654     private void updateCaptioningTextColor() {
655         int opacity = Integer.parseInt(mTextOpacity) & 0xff000000;
656         final ContentResolver cr = getContentResolver();
657         Settings.Secure.putInt(cr, Settings.Secure.ACCESSIBILITY_CAPTIONING_FOREGROUND_COLOR,
658                                 opacity | mTextColor);
659     }
660 
setWindowColor(String windowColor)661     private void setWindowColor(String windowColor) {
662         if (TextUtils.equals(windowColor, mNone)) {
663             mWindowEnabled = false;
664             mWindowColorName = mNone;
665             mWindowOpacityName = mNone;
666         } else {
667             mWindowEnabled = true;
668             mWindowColor = Integer.parseInt(windowColor);
669             mWindowColorName = getColorName(mWindowColor);
670             mWindowOpacityName = getOpacityName(mWindowOpacity);
671         }
672         updateCaptioningWindowColor();
673     }
674 
setWindowOpacity(String windowOpacity)675     private void setWindowOpacity(String windowOpacity) {
676         mWindowOpacity = windowOpacity;
677         mWindowOpacityName = getOpacityName(windowOpacity);
678         updateCaptioningWindowColor();
679     }
680 
updateCaptioningWindowColor()681     private void updateCaptioningWindowColor() {
682         int opacity = mWindowEnabled ? Integer.parseInt(mWindowOpacity) & 0xff000000 : 0;
683         final ContentResolver cr = getContentResolver();
684         Settings.Secure.putInt(cr, Settings.Secure.ACCESSIBILITY_CAPTIONING_WINDOW_COLOR,
685                                 opacity | mWindowColor);
686     }
687 
setEdgeType(String edgeType)688     private void setEdgeType(String edgeType) {
689         mEdgeType = edgeType;
690         mEdgeTypeName = getEdgeTypeName(edgeType);
691         final ContentResolver cr = getContentResolver();
692         Settings.Secure.putInt(cr, Settings.Secure.ACCESSIBILITY_CAPTIONING_EDGE_TYPE,
693                                 Integer.parseInt(edgeType));
694     }
695 
setEdgeColor(String edgeColor)696     private void setEdgeColor(String edgeColor) {
697         mEdgeColor = Integer.parseInt(edgeColor);
698         mEdgeColorName = getColorName(mEdgeColor);
699         final ContentResolver cr = getContentResolver();
700         Settings.Secure.putInt(cr, Settings.Secure.ACCESSIBILITY_CAPTIONING_EDGE_COLOR,
701                                 0xff000000 | mEdgeColor);
702     }
703 
updateCaptioningBackgroundColor()704     private void updateCaptioningBackgroundColor() {
705         int opacity = Integer.parseInt(mBackgroundOpacity) & 0xff000000;
706         final ContentResolver cr = getContentResolver();
707         Settings.Secure.putInt(cr, Settings.Secure.ACCESSIBILITY_CAPTIONING_BACKGROUND_COLOR,
708                                 opacity | mBackgroundColor);
709     }
710 
setBackgroundColor(String backgroundColor)711     private void setBackgroundColor(String backgroundColor) {
712         mBackgroundColor = Integer.parseInt(backgroundColor);
713         mBackgroundColorName = getColorName(mBackgroundColor);
714         updateCaptioningBackgroundColor();
715     }
716 
setBackgroundOpacity(String backgroundOpacity)717     private void setBackgroundOpacity(String backgroundOpacity) {
718         mBackgroundOpacity = backgroundOpacity;
719         mBackgroundOpacityName = getOpacityName(backgroundOpacity);
720         updateCaptioningBackgroundColor();
721     }
722 
getLanguageName(String mLanaguage)723     private String getLanguageName(String mLanaguage) {
724         for (int i = 0; i < mLanguageLocales.length; ++i) {
725             if (mLanguage.equals(mLanguageLocales [i])) {
726                 return mLanguageNames [i];
727             }
728         }
729         return "";
730     }
731 
getDisplayName( Locale l, String[] specialLocaleCodes, String[] specialLocaleNames)732     private static String getDisplayName(
733             Locale l, String[] specialLocaleCodes, String[] specialLocaleNames) {
734         String code = l.toString();
735         for (int i = 0; i < specialLocaleCodes.length; i++) {
736             if (specialLocaleCodes[i].equals(code)) {
737                 return specialLocaleNames[i];
738             }
739         }
740         return l.getDisplayName(l);
741     }
742 
getFontFamilyName(String fontFamily)743     private String getFontFamilyName(String fontFamily) {
744         int x = indexOf(mFontFamilies, fontFamily);
745         if (x == -1) {
746             return "";
747         } else {
748             return mFontFamilyNames [x];
749         }
750     }
751 
getOpacityName(String opacity)752     private String getOpacityName(String opacity) {
753         int x = indexOf(mOpacities, opacity);
754         if (x == -1) {
755             return "";
756         } else {
757             return mOpacityNames [x];
758         }
759     }
760 
indexOf(String[] a, String s)761     private int indexOf(String[] a, String s) {
762         if (s != null) {
763             for (int i = 0; i < a.length; ++i) {
764                 if (s.equals(a [i])) {
765                     return i;
766                 }
767             }
768         }
769         return -1;
770     }
771 
getEdgeTypeName(String edgeType)772     private String getEdgeTypeName(String edgeType) {
773         int x = indexOf(mEdgeTypes, edgeType);
774         if (x == -1) {
775             return "";
776         } else {
777             return mEdgeTypeNames [x];
778         }
779     }
780 
781     private static class LocaleInfo implements Comparable<LocaleInfo> {
782         private static final Collator sCollator = Collator.getInstance();
783 
784         public String label;
785         public Locale locale;
786 
LocaleInfo(String label, Locale locale)787         public LocaleInfo(String label, Locale locale) {
788             this.label = label;
789             this.locale = locale;
790         }
791 
792         @Override
toString()793         public String toString() {
794             return label;
795         }
796 
797         @Override
compareTo(LocaleInfo another)798         public int compareTo(LocaleInfo another) {
799             return sCollator.compare(this.label, another.label);
800         }
801     }
802 
getLanguages()803     private void getLanguages() {
804         final String[] systemLocales = Resources.getSystem().getAssets().getLocales();
805         Arrays.sort(systemLocales);
806 
807         final Context context = getApplicationContext();
808         final Resources resources = context.getResources();
809         final String[] specialLocaleCodes = resources.getStringArray(
810                 com.android.internal.R.array.special_locale_codes);
811         final String[] specialLocaleNames = resources.getStringArray(
812                 com.android.internal.R.array.special_locale_names);
813 
814         int finalSize = 0;
815 
816         final int origSize = systemLocales.length;
817         final LocaleInfo[] localeInfos = new LocaleInfo[origSize];
818         for (int i = 0; i < origSize; i++) {
819             final String localeStr = systemLocales[i];
820             final Locale locale = Locale.forLanguageTag(localeStr.replace('_', '-'));
821             // "und" means undefined.
822             if ("und".equals(locale.getLanguage()) || locale.getLanguage().isEmpty() ||
823                     locale.getCountry().isEmpty()) {
824                 continue;
825             }
826 
827             if (finalSize == 0) {
828                 localeInfos[finalSize++] =
829                        new LocaleInfo(locale.getDisplayLanguage(locale), locale);
830             } else {
831                 // check previous entry:
832                 // same lang and a country -> upgrade to full name and
833                 // insert ours with full name
834                 // diff lang -> insert ours with lang-only name
835                 final LocaleInfo previous = localeInfos[finalSize - 1];
836                 if (previous.locale.getLanguage().equals(locale.getLanguage())
837                         && !previous.locale.getLanguage().equals("zz")) {
838                     previous.label = getDisplayName(
839                             localeInfos[finalSize - 1].locale, specialLocaleCodes,
840                             specialLocaleNames);
841                     localeInfos[finalSize++] = new LocaleInfo(getDisplayName(locale,
842                             specialLocaleCodes, specialLocaleNames), locale);
843                 } else {
844                     final String displayName;
845                     if (localeStr.equals("zz_ZZ")) {
846                         displayName = "[Developer] Accented English";
847                     } else if (localeStr.equals("zz_ZY")) {
848                         displayName = "[Developer] Fake Bi-Directional";
849                     } else {
850                         displayName = locale.getDisplayLanguage(locale);
851                     }
852                     localeInfos[finalSize++] = new LocaleInfo(displayName, locale);
853                 }
854             }
855         }
856 
857         mLanguageLocales = new String [finalSize];
858         mLanguageNames = new String [finalSize];
859 
860         Arrays.sort(localeInfos, 0, finalSize);
861         for (int i = 0; i < finalSize; i++) {
862             final LocaleInfo info = localeInfos[i];
863             mLanguageLocales[i] = info.locale.toString();
864             mLanguageNames[i] = info.toString();
865         }
866     }
867 }
868 
869