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.internal.logging.nano.MetricsProto; 36 import com.android.tv.settings.R; 37 import com.android.tv.settings.RadioPreference; 38 import com.android.tv.settings.SettingsPreferenceFragment; 39 40 import java.util.List; 41 42 /** 43 * The "Captions" screen in TV settings. 44 */ 45 public class CaptionFragment extends SettingsPreferenceFragment implements 46 Preference.OnPreferenceChangeListener { 47 48 private static final String KEY_CAPTIONS_DISPLAY = "captions_display"; 49 private static final String KEY_CAPTIONS_LANGUAGE = "captions_language"; 50 private static final String KEY_CAPTIONS_TEXT_SIZE = "captions_text_size"; 51 private static final String KEY_CAPTIONS_STYLE_GROUP = "captions_style"; 52 private static final String KEY_CAPTIONS_STYLE_0 = "captions_style_0"; 53 private static final String KEY_CAPTIONS_STYLE_1 = "captions_style_1"; 54 private static final String KEY_CAPTIONS_STYLE_2 = "captions_style_2"; 55 private static final String KEY_CAPTIONS_STYLE_3 = "captions_style_3"; 56 private static final String KEY_CAPTIONS_STYLE_CUSTOM = "captions_style_custom"; 57 58 private TwoStatePreference mCaptionsDisplayPref; 59 private ListPreference mCaptionsLanguagePref; 60 private ListPreference mCaptionsTextSizePref; 61 private PreferenceGroup mCaptionsStyleGroup; 62 private RadioPreference mCaptionsStyle0Pref; 63 private RadioPreference mCaptionsStyle1Pref; 64 private RadioPreference mCaptionsStyle2Pref; 65 private RadioPreference mCaptionsStyle3Pref; 66 private RadioPreference mCaptionsStyleCustomPref; 67 newInstance()68 public static CaptionFragment newInstance() { 69 return new CaptionFragment(); 70 } 71 72 @Override onResume()73 public void onResume() { 74 super.onResume(); 75 refresh(); 76 } 77 78 @Override onCreatePreferences(Bundle savedInstanceState, String rootKey)79 public void onCreatePreferences(Bundle savedInstanceState, String rootKey) { 80 setPreferencesFromResource(R.xml.caption, null); 81 82 mCaptionsDisplayPref = (TwoStatePreference) findPreference(KEY_CAPTIONS_DISPLAY); 83 84 final List<LocalePicker.LocaleInfo> localeInfoList = 85 LocalePicker.getAllAssetLocales(getContext(), false); 86 final String[] langNames = new String[localeInfoList.size() + 1]; 87 final String[] langLocales = new String[localeInfoList.size() + 1]; 88 langNames[0] = getString(R.string.captions_language_default); 89 langLocales[0] = ""; 90 int i = 1; 91 for (final LocalePicker.LocaleInfo info : localeInfoList) { 92 langNames[i] = info.toString(); 93 langLocales[i] = info.getLocale().toString(); 94 i++; 95 } 96 mCaptionsLanguagePref = (ListPreference) findPreference(KEY_CAPTIONS_LANGUAGE); 97 mCaptionsLanguagePref.setEntries(langNames); 98 mCaptionsLanguagePref.setEntryValues(langLocales); 99 mCaptionsLanguagePref.setOnPreferenceChangeListener(this); 100 101 mCaptionsTextSizePref = (ListPreference) findPreference(KEY_CAPTIONS_TEXT_SIZE); 102 mCaptionsTextSizePref.setOnPreferenceChangeListener(this); 103 104 mCaptionsStyleGroup = (PreferenceGroup) findPreference(KEY_CAPTIONS_STYLE_GROUP); 105 106 mCaptionsStyle0Pref = (RadioPreference) findPreference(KEY_CAPTIONS_STYLE_0); 107 mCaptionsStyle1Pref = (RadioPreference) findPreference(KEY_CAPTIONS_STYLE_1); 108 mCaptionsStyle2Pref = (RadioPreference) findPreference(KEY_CAPTIONS_STYLE_2); 109 mCaptionsStyle3Pref = (RadioPreference) findPreference(KEY_CAPTIONS_STYLE_3); 110 mCaptionsStyleCustomPref = (RadioPreference) findPreference(KEY_CAPTIONS_STYLE_CUSTOM); 111 } 112 113 @Override onPreferenceTreeClick(Preference preference)114 public boolean onPreferenceTreeClick(Preference preference) { 115 final String key = preference.getKey(); 116 if (TextUtils.isEmpty(key)) { 117 return super.onPreferenceTreeClick(preference); 118 } 119 switch (key) { 120 case KEY_CAPTIONS_DISPLAY: 121 logToggleInteracted( 122 TvSettingsEnums.SYSTEM_A11Y_CAPTIONS_DISPLAY_ON_OFF, 123 ((TwoStatePreference) preference).isChecked()); 124 setCaptionsEnabled(((TwoStatePreference) preference).isChecked()); 125 return true; 126 case KEY_CAPTIONS_LANGUAGE: 127 logEntrySelected(TvSettingsEnums.SYSTEM_A11Y_CAPTIONS_LANGUAGE); 128 return super.onPreferenceTreeClick(preference); 129 case KEY_CAPTIONS_TEXT_SIZE: 130 logEntrySelected(TvSettingsEnums.SYSTEM_A11Y_CAPTIONS_TEXT_SIZE); 131 return super.onPreferenceTreeClick(preference); 132 case KEY_CAPTIONS_STYLE_0: 133 logEntrySelected(TvSettingsEnums.SYSTEM_A11Y_CAPTIONS_WHITE_ON_BLACK); 134 setCaptionsStyle(0); 135 mCaptionsStyle0Pref.setChecked(true); 136 mCaptionsStyle0Pref.clearOtherRadioPreferences(mCaptionsStyleGroup); 137 return true; 138 case KEY_CAPTIONS_STYLE_1: 139 logEntrySelected(TvSettingsEnums.SYSTEM_A11Y_CAPTIONS_BLACK_ON_WHITE); 140 setCaptionsStyle(1); 141 mCaptionsStyle1Pref.setChecked(true); 142 mCaptionsStyle1Pref.clearOtherRadioPreferences(mCaptionsStyleGroup); 143 return true; 144 case KEY_CAPTIONS_STYLE_2: 145 logEntrySelected(TvSettingsEnums.SYSTEM_A11Y_CAPTIONS_YELLOW_ON_BLACK); 146 setCaptionsStyle(2); 147 mCaptionsStyle2Pref.setChecked(true); 148 mCaptionsStyle2Pref.clearOtherRadioPreferences(mCaptionsStyleGroup); 149 return true; 150 case KEY_CAPTIONS_STYLE_3: 151 logEntrySelected(TvSettingsEnums.SYSTEM_A11Y_CAPTIONS_YELLOW_ON_BLUE); 152 setCaptionsStyle(3); 153 mCaptionsStyle3Pref.setChecked(true); 154 mCaptionsStyle3Pref.clearOtherRadioPreferences(mCaptionsStyleGroup); 155 return true; 156 case KEY_CAPTIONS_STYLE_CUSTOM: 157 logEntrySelected(TvSettingsEnums.SYSTEM_A11Y_CAPTIONS_CUSTOM); 158 setCaptionsStyle(-1); 159 mCaptionsStyleCustomPref.setChecked(true); 160 mCaptionsStyleCustomPref.clearOtherRadioPreferences(mCaptionsStyleGroup); 161 // Call to super to show custom configuration screen 162 return super.onPreferenceTreeClick(preference); 163 } 164 return super.onPreferenceTreeClick(preference); 165 } 166 167 @Override onPreferenceChange(Preference preference, Object newValue)168 public boolean onPreferenceChange(Preference preference, Object newValue) { 169 final String key = preference.getKey(); 170 if (TextUtils.isEmpty(key)) { 171 throw new IllegalStateException("Unknown preference change"); 172 } 173 switch (key) { 174 case KEY_CAPTIONS_LANGUAGE: 175 setCaptionsLocale((String) newValue); 176 break; 177 case KEY_CAPTIONS_TEXT_SIZE: 178 setCaptionsTextSize((String) newValue); 179 break; 180 default: 181 throw new IllegalStateException("Preference change with unknown key " + key); 182 } 183 return true; 184 } 185 refresh()186 private void refresh() { 187 mCaptionsDisplayPref.setChecked(getCaptionsEnabled()); 188 mCaptionsLanguagePref.setValue(getCaptionsLocale()); 189 mCaptionsTextSizePref.setValue(getCaptionsTextSize()); 190 switch (getCaptionsStyle()) { 191 default: 192 case 0: 193 mCaptionsStyle0Pref.setChecked(true); 194 mCaptionsStyle0Pref.clearOtherRadioPreferences(mCaptionsStyleGroup); 195 break; 196 case 1: 197 mCaptionsStyle1Pref.setChecked(true); 198 mCaptionsStyle1Pref.clearOtherRadioPreferences(mCaptionsStyleGroup); 199 break; 200 case 2: 201 mCaptionsStyle2Pref.setChecked(true); 202 mCaptionsStyle2Pref.clearOtherRadioPreferences(mCaptionsStyleGroup); 203 break; 204 case 3: 205 mCaptionsStyle3Pref.setChecked(true); 206 mCaptionsStyle3Pref.clearOtherRadioPreferences(mCaptionsStyleGroup); 207 break; 208 case -1: 209 mCaptionsStyleCustomPref.setChecked(true); 210 mCaptionsStyleCustomPref.clearOtherRadioPreferences(mCaptionsStyleGroup); 211 break; 212 } 213 } 214 getCaptionsEnabled()215 private boolean getCaptionsEnabled() { 216 return Settings.Secure.getInt(getContext().getContentResolver(), 217 Settings.Secure.ACCESSIBILITY_CAPTIONING_ENABLED, 0) != 0; 218 } 219 setCaptionsEnabled(boolean enabled)220 private void setCaptionsEnabled(boolean enabled) { 221 Settings.Secure.putInt(getContext().getContentResolver(), 222 Settings.Secure.ACCESSIBILITY_CAPTIONING_ENABLED, enabled ? 1 : 0); 223 } 224 getCaptionsStyle()225 private int getCaptionsStyle() { 226 return Settings.Secure.getInt(getContext().getContentResolver(), 227 Settings.Secure.ACCESSIBILITY_CAPTIONING_PRESET, 0); 228 } 229 setCaptionsStyle(int style)230 private void setCaptionsStyle(int style) { 231 Settings.Secure.putInt(getContext().getContentResolver(), 232 Settings.Secure.ACCESSIBILITY_CAPTIONING_PRESET, style); 233 LocalBroadcastManager.getInstance(getContext()) 234 .sendBroadcast(new Intent(CaptionSettingsFragment.ACTION_REFRESH_CAPTIONS_PREVIEW)); 235 } 236 getCaptionsLocale()237 private String getCaptionsLocale() { 238 final String captionLocale = Settings.Secure.getString(getContext().getContentResolver(), 239 Settings.Secure.ACCESSIBILITY_CAPTIONING_LOCALE); 240 return captionLocale == null ? "" : captionLocale; 241 } 242 setCaptionsLocale(String locale)243 private void setCaptionsLocale(String locale) { 244 Settings.Secure.putString(getContext().getContentResolver(), 245 Settings.Secure.ACCESSIBILITY_CAPTIONING_LOCALE, locale); 246 } 247 getCaptionsTextSize()248 private String getCaptionsTextSize() { 249 final float textSize = Settings.Secure.getFloat(getContext().getContentResolver(), 250 Settings.Secure.ACCESSIBILITY_CAPTIONING_FONT_SCALE, 1); 251 252 if (0 <= textSize && textSize < .375) { 253 return "0.25"; 254 } else if (textSize < .75) { 255 return "0.5"; 256 } else if (textSize < 1.25) { 257 return "1.0"; 258 } else if (textSize < 1.75) { 259 return "1.5"; 260 } else if (textSize < 2.5) { 261 return "2.0"; 262 } 263 264 return "1.0"; 265 } 266 setCaptionsTextSize(String textSize)267 private void setCaptionsTextSize(String textSize) { 268 Settings.Secure.putFloat(getContext().getContentResolver(), 269 Settings.Secure.ACCESSIBILITY_CAPTIONING_FONT_SCALE, Float.parseFloat(textSize)); 270 } 271 272 @Override getMetricsCategory()273 public int getMetricsCategory() { 274 return MetricsProto.MetricsEvent.ACCESSIBILITY_CAPTION_PROPERTIES; 275 } 276 277 @Override getPageId()278 protected int getPageId() { 279 return TvSettingsEnums.SYSTEM_A11Y_CAPTIONS; 280 } 281 } 282