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