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.R; 20 21 import android.app.Fragment; 22 import android.app.Activity; 23 import android.os.Bundle; 24 25 import com.android.internal.widget.SubtitleView; 26 27 import android.view.accessibility.CaptioningManager; 28 import android.view.accessibility.CaptioningManager.CaptionStyle; 29 import android.view.ViewGroup; 30 import android.view.View; 31 import android.view.LayoutInflater; 32 33 import android.content.Context; 34 import android.content.res.Resources; 35 import android.content.res.Configuration; 36 import android.graphics.Typeface; 37 import android.util.Log; 38 39 import java.util.Locale; 40 import android.text.TextUtils; 41 42 43 /** 44 * Fragment that shows caption preview image with text overlay. 45 */ 46 public class CaptionPreviewFragment extends Fragment { 47 48 private static final String TAG = "CaptionPreviewFragment"; 49 private static final boolean DEBUG = false; 50 51 private int mDefaultFontSize; 52 53 private SubtitleView mPreviewText; 54 private View mPreviewWindow; 55 private CaptioningManager mCaptioningManager; 56 private CaptioningManager.CaptioningChangeListener mCaptionChangeListener; 57 58 private float mFontScale; 59 private int mStyleId; 60 private int mTextColor; 61 private int mBackgroundColor; 62 private int mWindowColor; 63 private Locale mLocale; 64 private boolean mShowingLivePreview; 65 66 public static CaptionPreviewFragment newInstance() { 67 CaptionPreviewFragment fragment = new CaptionPreviewFragment(); 68 return fragment; 69 } 70 71 @Override 72 public void onCreate(Bundle savedInstanceState) { 73 if(DEBUG) Log.d(TAG, "onCreate"); 74 super.onCreate(savedInstanceState); 75 76 mCaptioningManager = (CaptioningManager) getActivity() 77 .getSystemService(Context.CAPTIONING_SERVICE); 78 79 mCaptionChangeListener = 80 new CaptioningManager.CaptioningChangeListener() { 81 82 @Override 83 public void onEnabledChanged(boolean enabled) { 84 if(DEBUG) Log.d(TAG, "onEnableChanged"); 85 refreshPreviewText(); 86 } 87 88 @Override 89 public void onUserStyleChanged(CaptionStyle userStyle) { 90 if(DEBUG) Log.d(TAG, "onUserStyleChanged"); 91 loadCaptionSettings(); 92 refreshPreviewText(); 93 } 94 95 @Override 96 public void onLocaleChanged(Locale locale) { 97 if(DEBUG) Log.d(TAG, "onLocaleChanged"); 98 loadCaptionSettings(); 99 refreshPreviewText(); 100 } 101 102 @Override 103 public void onFontScaleChanged(float fontScale) { 104 if(DEBUG) Log.d(TAG, "onFontScaleChanged " + fontScale); 105 loadCaptionSettings(); 106 refreshPreviewText(); 107 } 108 }; 109 110 mDefaultFontSize = 111 getResources().getInteger(R.integer.captioning_preview_default_font_size); 112 loadCaptionSettings(); 113 } 114 115 @Override 116 public void onStart() { 117 super.onStart(); 118 mCaptioningManager.addCaptioningChangeListener (mCaptionChangeListener); 119 } 120 121 @Override 122 public void onStop() { 123 mCaptioningManager.removeCaptioningChangeListener (mCaptionChangeListener); 124 super.onStop(); 125 } 126 127 private void loadCaptionSettings() { 128 mFontScale = mCaptioningManager.getFontScale(); 129 mStyleId = mCaptioningManager.getRawUserStyle(); 130 mLocale = mCaptioningManager.getLocale(); 131 132 CaptioningManager.CaptionStyle cs = mCaptioningManager.getUserStyle(); 133 mTextColor = cs.foregroundColor; 134 mBackgroundColor = cs.backgroundColor; 135 mWindowColor = cs.windowColor; 136 137 mShowingLivePreview = false; 138 } 139 140 @Override 141 public View onCreateView( 142 LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) { 143 if(DEBUG) Log.d(TAG, "onCreateView"); 144 final View rootView = inflater.inflate(R.layout.captioning_preview, container, false); 145 return rootView; 146 } 147 148 @Override 149 public void onViewCreated(View view, Bundle savedInstanceState) { 150 if(DEBUG) Log.d(TAG, "onViewCreated"); 151 super.onViewCreated(view, savedInstanceState); 152 mPreviewText = (SubtitleView) view.findViewById(R.id.preview_text); 153 mPreviewWindow = view.findViewById(R.id.preview_window); 154 refreshPreviewText(); 155 } 156 157 static CharSequence getTextForLocale(Context context, Locale locale, int resId) { 158 final Resources res = context.getResources(); 159 final Configuration config = res.getConfiguration(); 160 final Locale prevLocale = config.locale; 161 try { 162 config.locale = locale; 163 res.updateConfiguration(config, null); 164 return res.getText(resId); 165 } finally { 166 config.locale = prevLocale; 167 res.updateConfiguration(config, null); 168 } 169 } 170 171 public void livePreviewLanguage(String language) { 172 mLocale = null; 173 if (!TextUtils.isEmpty(language)) { 174 final String[] splitLocale = language.split("_"); 175 switch (splitLocale.length) { 176 case 3: 177 mLocale = new Locale(splitLocale[0], splitLocale[1], splitLocale[2]); 178 break; 179 case 2: 180 mLocale = new Locale(splitLocale[0], splitLocale[1]); 181 break; 182 case 1: 183 mLocale = new Locale(splitLocale[0]); 184 break; 185 } 186 } 187 mShowingLivePreview = true; 188 refreshPreviewText(); 189 } 190 191 public void livePreviewFontScale(float fontScale) { 192 mFontScale = fontScale; 193 mShowingLivePreview = true; 194 refreshPreviewText(); 195 } 196 197 public void livePreviewCaptionStyle(int styleId) { 198 mStyleId = styleId; 199 mShowingLivePreview = true; 200 refreshPreviewText(); 201 } 202 203 public void livePreviewFontFamily(String fontFamily) { 204 Typeface typeface = Typeface.create (fontFamily, Typeface.NORMAL); 205 mPreviewText.setTypeface(typeface); 206 mShowingLivePreview = true; 207 } 208 209 public void livePreviewTextColor(int textColor) { 210 int color = mTextColor & 0xff000000 | textColor & 0xffffff; 211 mPreviewText.setForegroundColor(color); 212 mShowingLivePreview = true; 213 } 214 215 public void livePreviewTextOpacity(String textOpacity) { 216 int opacity = Integer.parseInt(textOpacity); 217 int color = mTextColor & 0xffffff | opacity & 0xff000000; 218 mPreviewText.setForegroundColor(color); 219 mShowingLivePreview = true; 220 } 221 222 public void livePreviewBackgroundColor(int bgColor) { 223 int color = mBackgroundColor & 0xff000000 | bgColor & 0xffffff; 224 mPreviewText.setBackgroundColor(color); 225 mShowingLivePreview = true; 226 } 227 228 public void livePreviewBackgroundOpacity(String bgOpacity) { 229 int opacity = Integer.parseInt(bgOpacity); 230 int color = mBackgroundColor & 0xffffff | opacity & 0xff000000; 231 mPreviewText.setBackgroundColor(color); 232 mShowingLivePreview = true; 233 } 234 235 public void livePreviewEdgeColor(int edgeColor) { 236 edgeColor |= 0xff000000; 237 mPreviewText.setEdgeColor(edgeColor); 238 mShowingLivePreview = true; 239 } 240 241 public void livePreviewEdgeType(int edgeType) { 242 mPreviewText.setEdgeType(edgeType); 243 mShowingLivePreview = true; 244 } 245 246 public void livePreviewWindowColorNone() { 247 final CaptionStyle defStyle = CaptionStyle.DEFAULT; 248 mPreviewWindow.setBackgroundColor(defStyle.windowColor); 249 } 250 251 public void livePreviewWindowColor(int windowColor) { 252 int opacity = mWindowColor & 0xff000000; 253 if (opacity == 0) 254 opacity = 0xff000000; 255 int color = opacity | windowColor & 0xffffff; 256 mPreviewWindow.setBackgroundColor(color); 257 mShowingLivePreview = true; 258 } 259 260 public void livePreviewWindowOpacity(String windowOpacity) { 261 int opacity = Integer.parseInt(windowOpacity); 262 int color = mWindowColor & 0xffffff | opacity & 0xff000000; 263 mPreviewWindow.setBackgroundColor(color); 264 mShowingLivePreview = true; 265 } 266 267 public void resetLivePreview() { 268 if (mShowingLivePreview) { 269 loadCaptionSettings(); 270 refreshPreviewText(); 271 } 272 } 273 274 public void refreshPreviewText() { 275 if(DEBUG) Log.d(TAG, "refreshPreviewText"); 276 if (mPreviewText != null) { 277 boolean enabled = mCaptioningManager.isEnabled(); 278 if (enabled) { 279 mPreviewText.setVisibility(View.VISIBLE); 280 Activity activity = getActivity(); 281 mPreviewText.setStyle(mStyleId); 282 mPreviewText.setTextSize(mFontScale * mDefaultFontSize); 283 if (mLocale != null) { 284 CharSequence localizedText = getTextForLocale( 285 activity, mLocale, R.string.captioning_preview_text); 286 mPreviewText.setText(localizedText); 287 } else { 288 mPreviewText.setText(getResources() 289 .getString(R.string.captioning_preview_text)); 290 } 291 292 final CaptionStyle style = mCaptioningManager.getUserStyle(); 293 if (style.hasWindowColor()) { 294 mPreviewWindow.setBackgroundColor(mWindowColor); 295 } else { 296 final CaptionStyle defStyle = CaptionStyle.DEFAULT; 297 mPreviewWindow.setBackgroundColor(defStyle.windowColor); 298 } 299 300 mPreviewText.invalidate(); 301 } else { 302 mPreviewText.setVisibility(View.INVISIBLE); 303 } 304 } 305 } 306 } 307