1 /* 2 * Copyright (C) 2016 The Android Open Source Project 3 * 4 * Licensed under the Apache License, Version 2.0 (the "License"); 5 * you may not use this file except in compliance with the License. 6 * You may obtain a copy of the License at 7 * 8 * http://www.apache.org/licenses/LICENSE-2.0 9 * 10 * Unless required by applicable law or agreed to in writing, software 11 * distributed under the License is distributed on an "AS IS" BASIS, 12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 * See the License for the specific language governing permissions and 14 * limitations under the License 15 */ 16 17 package com.android.tv.settings.system; 18 19 import static com.android.tv.settings.util.InstrumentationUtils.logEntrySelected; 20 import static com.android.tv.settings.util.InstrumentationUtils.logToggleInteracted; 21 22 import android.app.tvsettings.TvSettingsEnums; 23 import android.content.Intent; 24 import android.os.Bundle; 25 import android.provider.Settings; 26 import android.text.TextUtils; 27 28 import androidx.localbroadcastmanager.content.LocalBroadcastManager; 29 import androidx.preference.ListPreference; 30 import androidx.preference.Preference; 31 import androidx.preference.PreferenceGroup; 32 import androidx.preference.TwoStatePreference; 33 34 import com.android.internal.app.LocalePicker; 35 import com.android.tv.settings.R; 36 import com.android.tv.settings.RadioPreference; 37 import com.android.tv.settings.SettingsPreferenceFragment; 38 39 import java.util.List; 40 41 /** 42 * The "Captions" screen in TV settings. 43 */ 44 public class CaptionFragment extends SettingsPreferenceFragment implements 45 Preference.OnPreferenceChangeListener { 46 47 private static final String KEY_CAPTIONS_DISPLAY = "captions_display"; 48 private static final String KEY_CAPTIONS_LANGUAGE = "captions_language"; 49 private static final String KEY_CAPTIONS_TEXT_SIZE = "captions_text_size"; 50 private static final String KEY_CAPTIONS_STYLE_GROUP = "captions_style"; 51 private static final String KEY_CAPTIONS_STYLE_0 = "captions_style_0"; 52 private static final String KEY_CAPTIONS_STYLE_1 = "captions_style_1"; 53 private static final String KEY_CAPTIONS_STYLE_2 = "captions_style_2"; 54 private static final String KEY_CAPTIONS_STYLE_3 = "captions_style_3"; 55 private static final String KEY_CAPTIONS_STYLE_CUSTOM = "captions_style_custom"; 56 57 private TwoStatePreference mCaptionsDisplayPref; 58 private ListPreference mCaptionsLanguagePref; 59 private ListPreference mCaptionsTextSizePref; 60 private PreferenceGroup mCaptionsStyleGroup; 61 private RadioPreference mCaptionsStyle0Pref; 62 private RadioPreference mCaptionsStyle1Pref; 63 private RadioPreference mCaptionsStyle2Pref; 64 private RadioPreference mCaptionsStyle3Pref; 65 private RadioPreference mCaptionsStyleCustomPref; 66 newInstance()67 public static CaptionFragment newInstance() { 68 return new CaptionFragment(); 69 } 70 71 @Override onResume()72 public void onResume() { 73 super.onResume(); 74 refresh(); 75 } 76 77 @Override onCreatePreferences(Bundle savedInstanceState, String rootKey)78 public void onCreatePreferences(Bundle savedInstanceState, String rootKey) { 79 setPreferencesFromResource(R.xml.caption, null); 80 81 mCaptionsDisplayPref = (TwoStatePreference) findPreference(KEY_CAPTIONS_DISPLAY); 82 83 final List<LocalePicker.LocaleInfo> localeInfoList = 84 LocalePicker.getAllAssetLocales(getContext(), false); 85 final String[] langNames = new String[localeInfoList.size() + 1]; 86 final String[] langLocales = new String[localeInfoList.size() + 1]; 87 langNames[0] = getString(R.string.captions_language_default); 88 langLocales[0] = ""; 89 int i = 1; 90 for (final LocalePicker.LocaleInfo info : localeInfoList) { 91 langNames[i] = info.toString(); 92 langLocales[i] = info.getLocale().toString(); 93 i++; 94 } 95 mCaptionsLanguagePref = (ListPreference) findPreference(KEY_CAPTIONS_LANGUAGE); 96 mCaptionsLanguagePref.setEntries(langNames); 97 mCaptionsLanguagePref.setEntryValues(langLocales); 98 mCaptionsLanguagePref.setOnPreferenceChangeListener(this); 99 100 mCaptionsTextSizePref = (ListPreference) findPreference(KEY_CAPTIONS_TEXT_SIZE); 101 mCaptionsTextSizePref.setOnPreferenceChangeListener(this); 102 103 mCaptionsStyleGroup = (PreferenceGroup) findPreference(KEY_CAPTIONS_STYLE_GROUP); 104 105 mCaptionsStyle0Pref = (RadioPreference) findPreference(KEY_CAPTIONS_STYLE_0); 106 mCaptionsStyle1Pref = (RadioPreference) findPreference(KEY_CAPTIONS_STYLE_1); 107 mCaptionsStyle2Pref = (RadioPreference) findPreference(KEY_CAPTIONS_STYLE_2); 108 mCaptionsStyle3Pref = (RadioPreference) findPreference(KEY_CAPTIONS_STYLE_3); 109 mCaptionsStyleCustomPref = (RadioPreference) findPreference(KEY_CAPTIONS_STYLE_CUSTOM); 110 } 111 112 @Override onPreferenceTreeClick(Preference preference)113 public boolean onPreferenceTreeClick(Preference preference) { 114 final String key = preference.getKey(); 115 if (TextUtils.isEmpty(key)) { 116 return super.onPreferenceTreeClick(preference); 117 } 118 switch (key) { 119 case KEY_CAPTIONS_DISPLAY: 120 logToggleInteracted( 121 TvSettingsEnums.SYSTEM_A11Y_CAPTIONS_DISPLAY_ON_OFF, 122 ((TwoStatePreference) preference).isChecked()); 123 setCaptionsEnabled(((TwoStatePreference) preference).isChecked()); 124 return true; 125 case KEY_CAPTIONS_LANGUAGE: 126 logEntrySelected(TvSettingsEnums.SYSTEM_A11Y_CAPTIONS_LANGUAGE); 127 return super.onPreferenceTreeClick(preference); 128 case KEY_CAPTIONS_TEXT_SIZE: 129 logEntrySelected(TvSettingsEnums.SYSTEM_A11Y_CAPTIONS_TEXT_SIZE); 130 return super.onPreferenceTreeClick(preference); 131 case KEY_CAPTIONS_STYLE_0: 132 logEntrySelected(TvSettingsEnums.SYSTEM_A11Y_CAPTIONS_WHITE_ON_BLACK); 133 setCaptionsStyle(0); 134 mCaptionsStyle0Pref.setChecked(true); 135 mCaptionsStyle0Pref.clearOtherRadioPreferences(mCaptionsStyleGroup); 136 return true; 137 case KEY_CAPTIONS_STYLE_1: 138 logEntrySelected(TvSettingsEnums.SYSTEM_A11Y_CAPTIONS_BLACK_ON_WHITE); 139 setCaptionsStyle(1); 140 mCaptionsStyle1Pref.setChecked(true); 141 mCaptionsStyle1Pref.clearOtherRadioPreferences(mCaptionsStyleGroup); 142 return true; 143 case KEY_CAPTIONS_STYLE_2: 144 logEntrySelected(TvSettingsEnums.SYSTEM_A11Y_CAPTIONS_YELLOW_ON_BLACK); 145 setCaptionsStyle(2); 146 mCaptionsStyle2Pref.setChecked(true); 147 mCaptionsStyle2Pref.clearOtherRadioPreferences(mCaptionsStyleGroup); 148 return true; 149 case KEY_CAPTIONS_STYLE_3: 150 logEntrySelected(TvSettingsEnums.SYSTEM_A11Y_CAPTIONS_YELLOW_ON_BLUE); 151 setCaptionsStyle(3); 152 mCaptionsStyle3Pref.setChecked(true); 153 mCaptionsStyle3Pref.clearOtherRadioPreferences(mCaptionsStyleGroup); 154 return true; 155 case KEY_CAPTIONS_STYLE_CUSTOM: 156 logEntrySelected(TvSettingsEnums.SYSTEM_A11Y_CAPTIONS_CUSTOM); 157 setCaptionsStyle(-1); 158 mCaptionsStyleCustomPref.setChecked(true); 159 mCaptionsStyleCustomPref.clearOtherRadioPreferences(mCaptionsStyleGroup); 160 // Call to super to show custom configuration screen 161 return super.onPreferenceTreeClick(preference); 162 } 163 return super.onPreferenceTreeClick(preference); 164 } 165 166 @Override onPreferenceChange(Preference preference, Object newValue)167 public boolean onPreferenceChange(Preference preference, Object newValue) { 168 final String key = preference.getKey(); 169 if (TextUtils.isEmpty(key)) { 170 throw new IllegalStateException("Unknown preference change"); 171 } 172 switch (key) { 173 case KEY_CAPTIONS_LANGUAGE: 174 setCaptionsLocale((String) newValue); 175 break; 176 case KEY_CAPTIONS_TEXT_SIZE: 177 setCaptionsTextSize((String) newValue); 178 break; 179 default: 180 throw new IllegalStateException("Preference change with unknown key " + key); 181 } 182 return true; 183 } 184 refresh()185 private void refresh() { 186 mCaptionsDisplayPref.setChecked(getCaptionsEnabled()); 187 mCaptionsLanguagePref.setValue(getCaptionsLocale()); 188 mCaptionsTextSizePref.setValue(getCaptionsTextSize()); 189 switch (getCaptionsStyle()) { 190 default: 191 case 0: 192 mCaptionsStyle0Pref.setChecked(true); 193 mCaptionsStyle0Pref.clearOtherRadioPreferences(mCaptionsStyleGroup); 194 break; 195 case 1: 196 mCaptionsStyle1Pref.setChecked(true); 197 mCaptionsStyle1Pref.clearOtherRadioPreferences(mCaptionsStyleGroup); 198 break; 199 case 2: 200 mCaptionsStyle2Pref.setChecked(true); 201 mCaptionsStyle2Pref.clearOtherRadioPreferences(mCaptionsStyleGroup); 202 break; 203 case 3: 204 mCaptionsStyle3Pref.setChecked(true); 205 mCaptionsStyle3Pref.clearOtherRadioPreferences(mCaptionsStyleGroup); 206 break; 207 case -1: 208 mCaptionsStyleCustomPref.setChecked(true); 209 mCaptionsStyleCustomPref.clearOtherRadioPreferences(mCaptionsStyleGroup); 210 break; 211 } 212 } 213 getCaptionsEnabled()214 private boolean getCaptionsEnabled() { 215 return Settings.Secure.getInt(getContext().getContentResolver(), 216 Settings.Secure.ACCESSIBILITY_CAPTIONING_ENABLED, 0) != 0; 217 } 218 setCaptionsEnabled(boolean enabled)219 private void setCaptionsEnabled(boolean enabled) { 220 Settings.Secure.putInt(getContext().getContentResolver(), 221 Settings.Secure.ACCESSIBILITY_CAPTIONING_ENABLED, enabled ? 1 : 0); 222 } 223 getCaptionsStyle()224 private int getCaptionsStyle() { 225 return Settings.Secure.getInt(getContext().getContentResolver(), 226 Settings.Secure.ACCESSIBILITY_CAPTIONING_PRESET, 0); 227 } 228 setCaptionsStyle(int style)229 private void setCaptionsStyle(int style) { 230 Settings.Secure.putInt(getContext().getContentResolver(), 231 Settings.Secure.ACCESSIBILITY_CAPTIONING_PRESET, style); 232 LocalBroadcastManager.getInstance(getContext()) 233 .sendBroadcast(new Intent(CaptionSettingsFragment.ACTION_REFRESH_CAPTIONS_PREVIEW)); 234 } 235 getCaptionsLocale()236 private String getCaptionsLocale() { 237 final String captionLocale = Settings.Secure.getString(getContext().getContentResolver(), 238 Settings.Secure.ACCESSIBILITY_CAPTIONING_LOCALE); 239 return captionLocale == null ? "" : captionLocale; 240 } 241 setCaptionsLocale(String locale)242 private void setCaptionsLocale(String locale) { 243 Settings.Secure.putString(getContext().getContentResolver(), 244 Settings.Secure.ACCESSIBILITY_CAPTIONING_LOCALE, locale); 245 } 246 getCaptionsTextSize()247 private String getCaptionsTextSize() { 248 final float textSize = Settings.Secure.getFloat(getContext().getContentResolver(), 249 Settings.Secure.ACCESSIBILITY_CAPTIONING_FONT_SCALE, 1); 250 251 if (0 <= textSize && textSize < .375) { 252 return "0.25"; 253 } else if (textSize < .75) { 254 return "0.5"; 255 } else if (textSize < 1.25) { 256 return "1.0"; 257 } else if (textSize < 1.75) { 258 return "1.5"; 259 } else if (textSize < 2.5) { 260 return "2.0"; 261 } 262 263 return "1.0"; 264 } 265 setCaptionsTextSize(String textSize)266 private void setCaptionsTextSize(String textSize) { 267 Settings.Secure.putFloat(getContext().getContentResolver(), 268 Settings.Secure.ACCESSIBILITY_CAPTIONING_FONT_SCALE, Float.parseFloat(textSize)); 269 } 270 271 @Override getPageId()272 protected int getPageId() { 273 return TvSettingsEnums.SYSTEM_A11Y_CAPTIONS; 274 } 275 } 276