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