Home | History | Annotate | Download | only in system
      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
    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 
    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 
    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 
    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 
    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 
    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 
    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 
    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
    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
    395     protected void updateView() {
    396         refreshActionList();
    397         mActionFragment = ActionFragment.newInstance(mActions);
    398         setActionFragment (mActionFragment);
    399     }
    400 
    401     @Override
    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
    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
    566     protected Object getInitialState() {
    567         return ActionType.CAPTIONS_OVERVIEW;
    568     }
    569 
    570     @Override
    571     protected void setProperty(boolean enable) {
    572         switch ((ActionType) mState) {
    573             case CAPTIONS_DISPLAY:
    574                 setEnabled(enable);
    575                 break;
    576         }
    577         goBack();
    578     }
    579 
    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 
    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 
    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 
    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 
    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 
    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 
    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 
    642     private void setTextColor(String textColor) {
    643         mTextColor = Integer.parseInt(textColor);
    644         mTextColorName = getColorName(mTextColor);
    645         updateCaptioningTextColor();
    646     }
    647 
    648     private void setTextOpacity(String textOpacity) {
    649         mTextOpacity = textOpacity;
    650         mTextOpacityName = getOpacityName(textOpacity);
    651         updateCaptioningTextColor();
    652     }
    653 
    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 
    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 
    675     private void setWindowOpacity(String windowOpacity) {
    676         mWindowOpacity = windowOpacity;
    677         mWindowOpacityName = getOpacityName(windowOpacity);
    678         updateCaptioningWindowColor();
    679     }
    680 
    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 
    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 
    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 
    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 
    711     private void setBackgroundColor(String backgroundColor) {
    712         mBackgroundColor = Integer.parseInt(backgroundColor);
    713         mBackgroundColorName = getColorName(mBackgroundColor);
    714         updateCaptioningBackgroundColor();
    715     }
    716 
    717     private void setBackgroundOpacity(String backgroundOpacity) {
    718         mBackgroundOpacity = backgroundOpacity;
    719         mBackgroundOpacityName = getOpacityName(backgroundOpacity);
    720         updateCaptioningBackgroundColor();
    721     }
    722 
    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 
    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 
    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 
    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 
    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 
    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 
    787         public LocaleInfo(String label, Locale locale) {
    788             this.label = label;
    789             this.locale = locale;
    790         }
    791 
    792         @Override
    793         public String toString() {
    794             return label;
    795         }
    796 
    797         @Override
    798         public int compareTo(LocaleInfo another) {
    799             return sCollator.compare(this.label, another.label);
    800         }
    801     }
    802 
    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