143a1e3d319d77c251445339bcc8f82c82b097feeAlan Viverette/* 243a1e3d319d77c251445339bcc8f82c82b097feeAlan Viverette * Copyright (C) 2013 The Android Open Source Project 343a1e3d319d77c251445339bcc8f82c82b097feeAlan Viverette * 443a1e3d319d77c251445339bcc8f82c82b097feeAlan Viverette * Licensed under the Apache License, Version 2.0 (the "License"); 543a1e3d319d77c251445339bcc8f82c82b097feeAlan Viverette * you may not use this file except in compliance with the License. 643a1e3d319d77c251445339bcc8f82c82b097feeAlan Viverette * You may obtain a copy of the License at 743a1e3d319d77c251445339bcc8f82c82b097feeAlan Viverette * 843a1e3d319d77c251445339bcc8f82c82b097feeAlan Viverette * http://www.apache.org/licenses/LICENSE-2.0 943a1e3d319d77c251445339bcc8f82c82b097feeAlan Viverette * 1043a1e3d319d77c251445339bcc8f82c82b097feeAlan Viverette * Unless required by applicable law or agreed to in writing, software 1143a1e3d319d77c251445339bcc8f82c82b097feeAlan Viverette * distributed under the License is distributed on an "AS IS" BASIS, 1243a1e3d319d77c251445339bcc8f82c82b097feeAlan Viverette * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 1343a1e3d319d77c251445339bcc8f82c82b097feeAlan Viverette * See the License for the specific language governing permissions and 1443a1e3d319d77c251445339bcc8f82c82b097feeAlan Viverette * limitations under the License. 1543a1e3d319d77c251445339bcc8f82c82b097feeAlan Viverette */ 1643a1e3d319d77c251445339bcc8f82c82b097feeAlan Viverette 1743a1e3d319d77c251445339bcc8f82c82b097feeAlan Viverettepackage android.view.accessibility; 1843a1e3d319d77c251445339bcc8f82c82b097feeAlan Viverette 1943a1e3d319d77c251445339bcc8f82c82b097feeAlan Viveretteimport android.content.ContentResolver; 2069ce69b0e1500bcf0bfa87eaf0b89ae47f552f5cAlan Viveretteimport android.content.Context; 2169ce69b0e1500bcf0bfa87eaf0b89ae47f552f5cAlan Viveretteimport android.database.ContentObserver; 2243a1e3d319d77c251445339bcc8f82c82b097feeAlan Viveretteimport android.graphics.Color; 2343a1e3d319d77c251445339bcc8f82c82b097feeAlan Viveretteimport android.graphics.Typeface; 2469ce69b0e1500bcf0bfa87eaf0b89ae47f552f5cAlan Viveretteimport android.net.Uri; 2569ce69b0e1500bcf0bfa87eaf0b89ae47f552f5cAlan Viveretteimport android.os.Handler; 2643a1e3d319d77c251445339bcc8f82c82b097feeAlan Viveretteimport android.provider.Settings.Secure; 2743a1e3d319d77c251445339bcc8f82c82b097feeAlan Viveretteimport android.text.TextUtils; 2843a1e3d319d77c251445339bcc8f82c82b097feeAlan Viverette 2969ce69b0e1500bcf0bfa87eaf0b89ae47f552f5cAlan Viveretteimport java.util.ArrayList; 3043a1e3d319d77c251445339bcc8f82c82b097feeAlan Viveretteimport java.util.Locale; 3143a1e3d319d77c251445339bcc8f82c82b097feeAlan Viverette 3243a1e3d319d77c251445339bcc8f82c82b097feeAlan Viverette/** 3369ce69b0e1500bcf0bfa87eaf0b89ae47f552f5cAlan Viverette * Contains methods for accessing and monitoring preferred video captioning state and visual 3443a1e3d319d77c251445339bcc8f82c82b097feeAlan Viverette * properties. 3569ce69b0e1500bcf0bfa87eaf0b89ae47f552f5cAlan Viverette * <p> 3669ce69b0e1500bcf0bfa87eaf0b89ae47f552f5cAlan Viverette * To obtain a handle to the captioning manager, do the following: 3769ce69b0e1500bcf0bfa87eaf0b89ae47f552f5cAlan Viverette * <p> 3869ce69b0e1500bcf0bfa87eaf0b89ae47f552f5cAlan Viverette * <code> 3969ce69b0e1500bcf0bfa87eaf0b89ae47f552f5cAlan Viverette * <pre>CaptioningManager captioningManager = 4069ce69b0e1500bcf0bfa87eaf0b89ae47f552f5cAlan Viverette * (CaptioningManager) context.getSystemService(Context.CAPTIONING_SERVICE);</pre> 4169ce69b0e1500bcf0bfa87eaf0b89ae47f552f5cAlan Viverette * </code> 4243a1e3d319d77c251445339bcc8f82c82b097feeAlan Viverette */ 4343a1e3d319d77c251445339bcc8f82c82b097feeAlan Viverettepublic class CaptioningManager { 4469ce69b0e1500bcf0bfa87eaf0b89ae47f552f5cAlan Viverette /** Default captioning enabled value. */ 4569ce69b0e1500bcf0bfa87eaf0b89ae47f552f5cAlan Viverette private static final int DEFAULT_ENABLED = 0; 4643a1e3d319d77c251445339bcc8f82c82b097feeAlan Viverette 4769ce69b0e1500bcf0bfa87eaf0b89ae47f552f5cAlan Viverette /** Default style preset as an index into {@link CaptionStyle#PRESETS}. */ 4843a1e3d319d77c251445339bcc8f82c82b097feeAlan Viverette private static final int DEFAULT_PRESET = 0; 4969ce69b0e1500bcf0bfa87eaf0b89ae47f552f5cAlan Viverette 5069ce69b0e1500bcf0bfa87eaf0b89ae47f552f5cAlan Viverette /** Default scaling value for caption fonts. */ 5169ce69b0e1500bcf0bfa87eaf0b89ae47f552f5cAlan Viverette private static final float DEFAULT_FONT_SCALE = 1; 5269ce69b0e1500bcf0bfa87eaf0b89ae47f552f5cAlan Viverette 5369ce69b0e1500bcf0bfa87eaf0b89ae47f552f5cAlan Viverette private final ArrayList<CaptioningChangeListener> 5469ce69b0e1500bcf0bfa87eaf0b89ae47f552f5cAlan Viverette mListeners = new ArrayList<CaptioningChangeListener>(); 5569ce69b0e1500bcf0bfa87eaf0b89ae47f552f5cAlan Viverette private final Handler mHandler = new Handler(); 5669ce69b0e1500bcf0bfa87eaf0b89ae47f552f5cAlan Viverette 5769ce69b0e1500bcf0bfa87eaf0b89ae47f552f5cAlan Viverette private final ContentResolver mContentResolver; 5869ce69b0e1500bcf0bfa87eaf0b89ae47f552f5cAlan Viverette 5969ce69b0e1500bcf0bfa87eaf0b89ae47f552f5cAlan Viverette /** 6069ce69b0e1500bcf0bfa87eaf0b89ae47f552f5cAlan Viverette * Creates a new captioning manager for the specified context. 6169ce69b0e1500bcf0bfa87eaf0b89ae47f552f5cAlan Viverette * 6269ce69b0e1500bcf0bfa87eaf0b89ae47f552f5cAlan Viverette * @hide 6369ce69b0e1500bcf0bfa87eaf0b89ae47f552f5cAlan Viverette */ 6469ce69b0e1500bcf0bfa87eaf0b89ae47f552f5cAlan Viverette public CaptioningManager(Context context) { 6569ce69b0e1500bcf0bfa87eaf0b89ae47f552f5cAlan Viverette mContentResolver = context.getContentResolver(); 6669ce69b0e1500bcf0bfa87eaf0b89ae47f552f5cAlan Viverette } 6743a1e3d319d77c251445339bcc8f82c82b097feeAlan Viverette 6843a1e3d319d77c251445339bcc8f82c82b097feeAlan Viverette /** 6969ce69b0e1500bcf0bfa87eaf0b89ae47f552f5cAlan Viverette * @return the user's preferred captioning enabled state 7043a1e3d319d77c251445339bcc8f82c82b097feeAlan Viverette */ 7169ce69b0e1500bcf0bfa87eaf0b89ae47f552f5cAlan Viverette public final boolean isEnabled() { 7269ce69b0e1500bcf0bfa87eaf0b89ae47f552f5cAlan Viverette return Secure.getInt( 7369ce69b0e1500bcf0bfa87eaf0b89ae47f552f5cAlan Viverette mContentResolver, Secure.ACCESSIBILITY_CAPTIONING_ENABLED, DEFAULT_ENABLED) == 1; 7443a1e3d319d77c251445339bcc8f82c82b097feeAlan Viverette } 7543a1e3d319d77c251445339bcc8f82c82b097feeAlan Viverette 7643a1e3d319d77c251445339bcc8f82c82b097feeAlan Viverette /** 7769ce69b0e1500bcf0bfa87eaf0b89ae47f552f5cAlan Viverette * @return the raw locale string for the user's preferred captioning 7869ce69b0e1500bcf0bfa87eaf0b89ae47f552f5cAlan Viverette * language 7943a1e3d319d77c251445339bcc8f82c82b097feeAlan Viverette * @hide 8043a1e3d319d77c251445339bcc8f82c82b097feeAlan Viverette */ 8169ce69b0e1500bcf0bfa87eaf0b89ae47f552f5cAlan Viverette public final String getRawLocale() { 8269ce69b0e1500bcf0bfa87eaf0b89ae47f552f5cAlan Viverette return Secure.getString(mContentResolver, Secure.ACCESSIBILITY_CAPTIONING_LOCALE); 8343a1e3d319d77c251445339bcc8f82c82b097feeAlan Viverette } 8443a1e3d319d77c251445339bcc8f82c82b097feeAlan Viverette 8543a1e3d319d77c251445339bcc8f82c82b097feeAlan Viverette /** 8669ce69b0e1500bcf0bfa87eaf0b89ae47f552f5cAlan Viverette * @return the locale for the user's preferred captioning language, or null 8769ce69b0e1500bcf0bfa87eaf0b89ae47f552f5cAlan Viverette * if not specified 8843a1e3d319d77c251445339bcc8f82c82b097feeAlan Viverette */ 8969ce69b0e1500bcf0bfa87eaf0b89ae47f552f5cAlan Viverette public final Locale getLocale() { 9069ce69b0e1500bcf0bfa87eaf0b89ae47f552f5cAlan Viverette final String rawLocale = getRawLocale(); 9143a1e3d319d77c251445339bcc8f82c82b097feeAlan Viverette if (!TextUtils.isEmpty(rawLocale)) { 9243a1e3d319d77c251445339bcc8f82c82b097feeAlan Viverette final String[] splitLocale = rawLocale.split("_"); 9343a1e3d319d77c251445339bcc8f82c82b097feeAlan Viverette switch (splitLocale.length) { 9443a1e3d319d77c251445339bcc8f82c82b097feeAlan Viverette case 3: 9543a1e3d319d77c251445339bcc8f82c82b097feeAlan Viverette return new Locale(splitLocale[0], splitLocale[1], splitLocale[2]); 9643a1e3d319d77c251445339bcc8f82c82b097feeAlan Viverette case 2: 9743a1e3d319d77c251445339bcc8f82c82b097feeAlan Viverette return new Locale(splitLocale[0], splitLocale[1]); 9843a1e3d319d77c251445339bcc8f82c82b097feeAlan Viverette case 1: 9943a1e3d319d77c251445339bcc8f82c82b097feeAlan Viverette return new Locale(splitLocale[0]); 10043a1e3d319d77c251445339bcc8f82c82b097feeAlan Viverette } 10143a1e3d319d77c251445339bcc8f82c82b097feeAlan Viverette } 10243a1e3d319d77c251445339bcc8f82c82b097feeAlan Viverette 10343a1e3d319d77c251445339bcc8f82c82b097feeAlan Viverette return null; 10443a1e3d319d77c251445339bcc8f82c82b097feeAlan Viverette } 10543a1e3d319d77c251445339bcc8f82c82b097feeAlan Viverette 10643a1e3d319d77c251445339bcc8f82c82b097feeAlan Viverette /** 10769ce69b0e1500bcf0bfa87eaf0b89ae47f552f5cAlan Viverette * @return the user's preferred font scaling factor for video captions, or 1 if not 10869ce69b0e1500bcf0bfa87eaf0b89ae47f552f5cAlan Viverette * specified 10943a1e3d319d77c251445339bcc8f82c82b097feeAlan Viverette */ 11069ce69b0e1500bcf0bfa87eaf0b89ae47f552f5cAlan Viverette public final float getFontScale() { 11169ce69b0e1500bcf0bfa87eaf0b89ae47f552f5cAlan Viverette return Secure.getFloat( 11269ce69b0e1500bcf0bfa87eaf0b89ae47f552f5cAlan Viverette mContentResolver, Secure.ACCESSIBILITY_CAPTIONING_FONT_SCALE, DEFAULT_FONT_SCALE); 11369ce69b0e1500bcf0bfa87eaf0b89ae47f552f5cAlan Viverette } 11469ce69b0e1500bcf0bfa87eaf0b89ae47f552f5cAlan Viverette 11569ce69b0e1500bcf0bfa87eaf0b89ae47f552f5cAlan Viverette /** 11669ce69b0e1500bcf0bfa87eaf0b89ae47f552f5cAlan Viverette * @return the raw preset number, or the first preset if not specified 11769ce69b0e1500bcf0bfa87eaf0b89ae47f552f5cAlan Viverette * @hide 11869ce69b0e1500bcf0bfa87eaf0b89ae47f552f5cAlan Viverette */ 11969ce69b0e1500bcf0bfa87eaf0b89ae47f552f5cAlan Viverette public int getRawUserStyle() { 12069ce69b0e1500bcf0bfa87eaf0b89ae47f552f5cAlan Viverette return Secure.getInt( 12169ce69b0e1500bcf0bfa87eaf0b89ae47f552f5cAlan Viverette mContentResolver, Secure.ACCESSIBILITY_CAPTIONING_PRESET, DEFAULT_PRESET); 12269ce69b0e1500bcf0bfa87eaf0b89ae47f552f5cAlan Viverette } 12369ce69b0e1500bcf0bfa87eaf0b89ae47f552f5cAlan Viverette 12469ce69b0e1500bcf0bfa87eaf0b89ae47f552f5cAlan Viverette /** 12569ce69b0e1500bcf0bfa87eaf0b89ae47f552f5cAlan Viverette * @return the user's preferred visual properties for captions as a 12669ce69b0e1500bcf0bfa87eaf0b89ae47f552f5cAlan Viverette * {@link CaptionStyle}, or the default style if not specified 12769ce69b0e1500bcf0bfa87eaf0b89ae47f552f5cAlan Viverette */ 12869ce69b0e1500bcf0bfa87eaf0b89ae47f552f5cAlan Viverette public CaptionStyle getUserStyle() { 12969ce69b0e1500bcf0bfa87eaf0b89ae47f552f5cAlan Viverette final int preset = getRawUserStyle(); 13069ce69b0e1500bcf0bfa87eaf0b89ae47f552f5cAlan Viverette if (preset == CaptionStyle.PRESET_CUSTOM) { 13169ce69b0e1500bcf0bfa87eaf0b89ae47f552f5cAlan Viverette return CaptionStyle.getCustomStyle(mContentResolver); 13269ce69b0e1500bcf0bfa87eaf0b89ae47f552f5cAlan Viverette } 13369ce69b0e1500bcf0bfa87eaf0b89ae47f552f5cAlan Viverette 13469ce69b0e1500bcf0bfa87eaf0b89ae47f552f5cAlan Viverette return CaptionStyle.PRESETS[preset]; 13569ce69b0e1500bcf0bfa87eaf0b89ae47f552f5cAlan Viverette } 13669ce69b0e1500bcf0bfa87eaf0b89ae47f552f5cAlan Viverette 13769ce69b0e1500bcf0bfa87eaf0b89ae47f552f5cAlan Viverette /** 13869ce69b0e1500bcf0bfa87eaf0b89ae47f552f5cAlan Viverette * Adds a listener for changes in the user's preferred captioning enabled 13969ce69b0e1500bcf0bfa87eaf0b89ae47f552f5cAlan Viverette * state and visual properties. 14069ce69b0e1500bcf0bfa87eaf0b89ae47f552f5cAlan Viverette * 14169ce69b0e1500bcf0bfa87eaf0b89ae47f552f5cAlan Viverette * @param listener the listener to add 14269ce69b0e1500bcf0bfa87eaf0b89ae47f552f5cAlan Viverette */ 143d43daf361e993457e64eeeddab6d1a0ebc828c99Alan Viverette public void addCaptioningChangeListener(CaptioningChangeListener listener) { 14469ce69b0e1500bcf0bfa87eaf0b89ae47f552f5cAlan Viverette synchronized (mListeners) { 14569ce69b0e1500bcf0bfa87eaf0b89ae47f552f5cAlan Viverette if (mListeners.isEmpty()) { 14669ce69b0e1500bcf0bfa87eaf0b89ae47f552f5cAlan Viverette registerObserver(Secure.ACCESSIBILITY_CAPTIONING_ENABLED); 14769ce69b0e1500bcf0bfa87eaf0b89ae47f552f5cAlan Viverette registerObserver(Secure.ACCESSIBILITY_CAPTIONING_FOREGROUND_COLOR); 14869ce69b0e1500bcf0bfa87eaf0b89ae47f552f5cAlan Viverette registerObserver(Secure.ACCESSIBILITY_CAPTIONING_BACKGROUND_COLOR); 14969ce69b0e1500bcf0bfa87eaf0b89ae47f552f5cAlan Viverette registerObserver(Secure.ACCESSIBILITY_CAPTIONING_EDGE_TYPE); 15069ce69b0e1500bcf0bfa87eaf0b89ae47f552f5cAlan Viverette registerObserver(Secure.ACCESSIBILITY_CAPTIONING_EDGE_COLOR); 15169ce69b0e1500bcf0bfa87eaf0b89ae47f552f5cAlan Viverette registerObserver(Secure.ACCESSIBILITY_CAPTIONING_TYPEFACE); 15269ce69b0e1500bcf0bfa87eaf0b89ae47f552f5cAlan Viverette registerObserver(Secure.ACCESSIBILITY_CAPTIONING_FONT_SCALE); 15369ce69b0e1500bcf0bfa87eaf0b89ae47f552f5cAlan Viverette registerObserver(Secure.ACCESSIBILITY_CAPTIONING_LOCALE); 15469ce69b0e1500bcf0bfa87eaf0b89ae47f552f5cAlan Viverette } 15569ce69b0e1500bcf0bfa87eaf0b89ae47f552f5cAlan Viverette 15669ce69b0e1500bcf0bfa87eaf0b89ae47f552f5cAlan Viverette mListeners.add(listener); 15769ce69b0e1500bcf0bfa87eaf0b89ae47f552f5cAlan Viverette } 15869ce69b0e1500bcf0bfa87eaf0b89ae47f552f5cAlan Viverette } 15969ce69b0e1500bcf0bfa87eaf0b89ae47f552f5cAlan Viverette 16069ce69b0e1500bcf0bfa87eaf0b89ae47f552f5cAlan Viverette private void registerObserver(String key) { 16169ce69b0e1500bcf0bfa87eaf0b89ae47f552f5cAlan Viverette mContentResolver.registerContentObserver(Secure.getUriFor(key), false, mContentObserver); 16269ce69b0e1500bcf0bfa87eaf0b89ae47f552f5cAlan Viverette } 16369ce69b0e1500bcf0bfa87eaf0b89ae47f552f5cAlan Viverette 16469ce69b0e1500bcf0bfa87eaf0b89ae47f552f5cAlan Viverette /** 16569ce69b0e1500bcf0bfa87eaf0b89ae47f552f5cAlan Viverette * Removes a listener previously added using 166d43daf361e993457e64eeeddab6d1a0ebc828c99Alan Viverette * {@link #addCaptioningChangeListener}. 16769ce69b0e1500bcf0bfa87eaf0b89ae47f552f5cAlan Viverette * 16869ce69b0e1500bcf0bfa87eaf0b89ae47f552f5cAlan Viverette * @param listener the listener to remove 16969ce69b0e1500bcf0bfa87eaf0b89ae47f552f5cAlan Viverette */ 170d43daf361e993457e64eeeddab6d1a0ebc828c99Alan Viverette public void removeCaptioningChangeListener(CaptioningChangeListener listener) { 17169ce69b0e1500bcf0bfa87eaf0b89ae47f552f5cAlan Viverette synchronized (mListeners) { 17269ce69b0e1500bcf0bfa87eaf0b89ae47f552f5cAlan Viverette mListeners.remove(listener); 17369ce69b0e1500bcf0bfa87eaf0b89ae47f552f5cAlan Viverette 17469ce69b0e1500bcf0bfa87eaf0b89ae47f552f5cAlan Viverette if (mListeners.isEmpty()) { 17569ce69b0e1500bcf0bfa87eaf0b89ae47f552f5cAlan Viverette mContentResolver.unregisterContentObserver(mContentObserver); 17669ce69b0e1500bcf0bfa87eaf0b89ae47f552f5cAlan Viverette } 17769ce69b0e1500bcf0bfa87eaf0b89ae47f552f5cAlan Viverette } 17869ce69b0e1500bcf0bfa87eaf0b89ae47f552f5cAlan Viverette } 17969ce69b0e1500bcf0bfa87eaf0b89ae47f552f5cAlan Viverette 18069ce69b0e1500bcf0bfa87eaf0b89ae47f552f5cAlan Viverette private void notifyEnabledChanged() { 18169ce69b0e1500bcf0bfa87eaf0b89ae47f552f5cAlan Viverette final boolean enabled = isEnabled(); 18269ce69b0e1500bcf0bfa87eaf0b89ae47f552f5cAlan Viverette synchronized (mListeners) { 18369ce69b0e1500bcf0bfa87eaf0b89ae47f552f5cAlan Viverette for (CaptioningChangeListener listener : mListeners) { 18469ce69b0e1500bcf0bfa87eaf0b89ae47f552f5cAlan Viverette listener.onEnabledChanged(enabled); 18569ce69b0e1500bcf0bfa87eaf0b89ae47f552f5cAlan Viverette } 18669ce69b0e1500bcf0bfa87eaf0b89ae47f552f5cAlan Viverette } 18769ce69b0e1500bcf0bfa87eaf0b89ae47f552f5cAlan Viverette } 18869ce69b0e1500bcf0bfa87eaf0b89ae47f552f5cAlan Viverette 18969ce69b0e1500bcf0bfa87eaf0b89ae47f552f5cAlan Viverette private void notifyUserStyleChanged() { 19069ce69b0e1500bcf0bfa87eaf0b89ae47f552f5cAlan Viverette final CaptionStyle userStyle = getUserStyle(); 19169ce69b0e1500bcf0bfa87eaf0b89ae47f552f5cAlan Viverette synchronized (mListeners) { 19269ce69b0e1500bcf0bfa87eaf0b89ae47f552f5cAlan Viverette for (CaptioningChangeListener listener : mListeners) { 19369ce69b0e1500bcf0bfa87eaf0b89ae47f552f5cAlan Viverette listener.onUserStyleChanged(userStyle); 19469ce69b0e1500bcf0bfa87eaf0b89ae47f552f5cAlan Viverette } 19569ce69b0e1500bcf0bfa87eaf0b89ae47f552f5cAlan Viverette } 19643a1e3d319d77c251445339bcc8f82c82b097feeAlan Viverette } 19743a1e3d319d77c251445339bcc8f82c82b097feeAlan Viverette 19869ce69b0e1500bcf0bfa87eaf0b89ae47f552f5cAlan Viverette private void notifyLocaleChanged() { 19969ce69b0e1500bcf0bfa87eaf0b89ae47f552f5cAlan Viverette final Locale locale = getLocale(); 20069ce69b0e1500bcf0bfa87eaf0b89ae47f552f5cAlan Viverette synchronized (mListeners) { 20169ce69b0e1500bcf0bfa87eaf0b89ae47f552f5cAlan Viverette for (CaptioningChangeListener listener : mListeners) { 20269ce69b0e1500bcf0bfa87eaf0b89ae47f552f5cAlan Viverette listener.onLocaleChanged(locale); 20369ce69b0e1500bcf0bfa87eaf0b89ae47f552f5cAlan Viverette } 20469ce69b0e1500bcf0bfa87eaf0b89ae47f552f5cAlan Viverette } 20569ce69b0e1500bcf0bfa87eaf0b89ae47f552f5cAlan Viverette } 20669ce69b0e1500bcf0bfa87eaf0b89ae47f552f5cAlan Viverette 20769ce69b0e1500bcf0bfa87eaf0b89ae47f552f5cAlan Viverette private void notifyFontScaleChanged() { 20869ce69b0e1500bcf0bfa87eaf0b89ae47f552f5cAlan Viverette final float fontScale = getFontScale(); 20969ce69b0e1500bcf0bfa87eaf0b89ae47f552f5cAlan Viverette synchronized (mListeners) { 21069ce69b0e1500bcf0bfa87eaf0b89ae47f552f5cAlan Viverette for (CaptioningChangeListener listener : mListeners) { 21169ce69b0e1500bcf0bfa87eaf0b89ae47f552f5cAlan Viverette listener.onFontScaleChanged(fontScale); 21269ce69b0e1500bcf0bfa87eaf0b89ae47f552f5cAlan Viverette } 21369ce69b0e1500bcf0bfa87eaf0b89ae47f552f5cAlan Viverette } 21469ce69b0e1500bcf0bfa87eaf0b89ae47f552f5cAlan Viverette } 21569ce69b0e1500bcf0bfa87eaf0b89ae47f552f5cAlan Viverette 21669ce69b0e1500bcf0bfa87eaf0b89ae47f552f5cAlan Viverette private final ContentObserver mContentObserver = new ContentObserver(mHandler) { 21769ce69b0e1500bcf0bfa87eaf0b89ae47f552f5cAlan Viverette @Override 21869ce69b0e1500bcf0bfa87eaf0b89ae47f552f5cAlan Viverette public void onChange(boolean selfChange, Uri uri) { 21969ce69b0e1500bcf0bfa87eaf0b89ae47f552f5cAlan Viverette final String uriPath = uri.getPath(); 22069ce69b0e1500bcf0bfa87eaf0b89ae47f552f5cAlan Viverette final String name = uriPath.substring(uriPath.lastIndexOf('/') + 1); 22169ce69b0e1500bcf0bfa87eaf0b89ae47f552f5cAlan Viverette if (Secure.ACCESSIBILITY_CAPTIONING_ENABLED.equals(name)) { 22269ce69b0e1500bcf0bfa87eaf0b89ae47f552f5cAlan Viverette notifyEnabledChanged(); 22369ce69b0e1500bcf0bfa87eaf0b89ae47f552f5cAlan Viverette } else if (Secure.ACCESSIBILITY_CAPTIONING_LOCALE.equals(name)) { 22469ce69b0e1500bcf0bfa87eaf0b89ae47f552f5cAlan Viverette notifyLocaleChanged(); 22569ce69b0e1500bcf0bfa87eaf0b89ae47f552f5cAlan Viverette } else if (Secure.ACCESSIBILITY_CAPTIONING_FONT_SCALE.equals(name)) { 22669ce69b0e1500bcf0bfa87eaf0b89ae47f552f5cAlan Viverette notifyFontScaleChanged(); 22769ce69b0e1500bcf0bfa87eaf0b89ae47f552f5cAlan Viverette } else { 22869ce69b0e1500bcf0bfa87eaf0b89ae47f552f5cAlan Viverette // We only need a single callback when multiple style properties 22969ce69b0e1500bcf0bfa87eaf0b89ae47f552f5cAlan Viverette // change in rapid succession. 23069ce69b0e1500bcf0bfa87eaf0b89ae47f552f5cAlan Viverette mHandler.removeCallbacks(mStyleChangedRunnable); 23169ce69b0e1500bcf0bfa87eaf0b89ae47f552f5cAlan Viverette mHandler.post(mStyleChangedRunnable); 23269ce69b0e1500bcf0bfa87eaf0b89ae47f552f5cAlan Viverette } 23369ce69b0e1500bcf0bfa87eaf0b89ae47f552f5cAlan Viverette } 23469ce69b0e1500bcf0bfa87eaf0b89ae47f552f5cAlan Viverette }; 23569ce69b0e1500bcf0bfa87eaf0b89ae47f552f5cAlan Viverette 23669ce69b0e1500bcf0bfa87eaf0b89ae47f552f5cAlan Viverette /** 23769ce69b0e1500bcf0bfa87eaf0b89ae47f552f5cAlan Viverette * Runnable posted when user style properties change. This is used to 23869ce69b0e1500bcf0bfa87eaf0b89ae47f552f5cAlan Viverette * prevent unnecessary change notifications when multiple properties change 23969ce69b0e1500bcf0bfa87eaf0b89ae47f552f5cAlan Viverette * in rapid succession. 24069ce69b0e1500bcf0bfa87eaf0b89ae47f552f5cAlan Viverette */ 24169ce69b0e1500bcf0bfa87eaf0b89ae47f552f5cAlan Viverette private final Runnable mStyleChangedRunnable = new Runnable() { 24269ce69b0e1500bcf0bfa87eaf0b89ae47f552f5cAlan Viverette @Override 24369ce69b0e1500bcf0bfa87eaf0b89ae47f552f5cAlan Viverette public void run() { 24469ce69b0e1500bcf0bfa87eaf0b89ae47f552f5cAlan Viverette notifyUserStyleChanged(); 24569ce69b0e1500bcf0bfa87eaf0b89ae47f552f5cAlan Viverette } 24669ce69b0e1500bcf0bfa87eaf0b89ae47f552f5cAlan Viverette }; 24769ce69b0e1500bcf0bfa87eaf0b89ae47f552f5cAlan Viverette 24869ce69b0e1500bcf0bfa87eaf0b89ae47f552f5cAlan Viverette /** 24969ce69b0e1500bcf0bfa87eaf0b89ae47f552f5cAlan Viverette * Specifies visual properties for video captions, including foreground and 25069ce69b0e1500bcf0bfa87eaf0b89ae47f552f5cAlan Viverette * background colors, edge properties, and typeface. 25169ce69b0e1500bcf0bfa87eaf0b89ae47f552f5cAlan Viverette */ 25243a1e3d319d77c251445339bcc8f82c82b097feeAlan Viverette public static final class CaptionStyle { 25343a1e3d319d77c251445339bcc8f82c82b097feeAlan Viverette private static final CaptionStyle WHITE_ON_BLACK; 25443a1e3d319d77c251445339bcc8f82c82b097feeAlan Viverette private static final CaptionStyle BLACK_ON_WHITE; 25543a1e3d319d77c251445339bcc8f82c82b097feeAlan Viverette private static final CaptionStyle YELLOW_ON_BLACK; 25643a1e3d319d77c251445339bcc8f82c82b097feeAlan Viverette private static final CaptionStyle YELLOW_ON_BLUE; 25743a1e3d319d77c251445339bcc8f82c82b097feeAlan Viverette private static final CaptionStyle DEFAULT_CUSTOM; 25843a1e3d319d77c251445339bcc8f82c82b097feeAlan Viverette 25943a1e3d319d77c251445339bcc8f82c82b097feeAlan Viverette /** @hide */ 26043a1e3d319d77c251445339bcc8f82c82b097feeAlan Viverette public static final CaptionStyle[] PRESETS; 26143a1e3d319d77c251445339bcc8f82c82b097feeAlan Viverette 26243a1e3d319d77c251445339bcc8f82c82b097feeAlan Viverette /** @hide */ 26343a1e3d319d77c251445339bcc8f82c82b097feeAlan Viverette public static final int PRESET_CUSTOM = -1; 26443a1e3d319d77c251445339bcc8f82c82b097feeAlan Viverette 26543a1e3d319d77c251445339bcc8f82c82b097feeAlan Viverette /** Edge type value specifying no character edges. */ 26643a1e3d319d77c251445339bcc8f82c82b097feeAlan Viverette public static final int EDGE_TYPE_NONE = 0; 26743a1e3d319d77c251445339bcc8f82c82b097feeAlan Viverette 26843a1e3d319d77c251445339bcc8f82c82b097feeAlan Viverette /** Edge type value specifying uniformly outlined character edges. */ 26943a1e3d319d77c251445339bcc8f82c82b097feeAlan Viverette public static final int EDGE_TYPE_OUTLINE = 1; 27043a1e3d319d77c251445339bcc8f82c82b097feeAlan Viverette 27143a1e3d319d77c251445339bcc8f82c82b097feeAlan Viverette /** Edge type value specifying drop-shadowed character edges. */ 27243a1e3d319d77c251445339bcc8f82c82b097feeAlan Viverette public static final int EDGE_TYPE_DROP_SHADOW = 2; 27343a1e3d319d77c251445339bcc8f82c82b097feeAlan Viverette 27443a1e3d319d77c251445339bcc8f82c82b097feeAlan Viverette /** The preferred foreground color for video captions. */ 27543a1e3d319d77c251445339bcc8f82c82b097feeAlan Viverette public final int foregroundColor; 27643a1e3d319d77c251445339bcc8f82c82b097feeAlan Viverette 27743a1e3d319d77c251445339bcc8f82c82b097feeAlan Viverette /** The preferred background color for video captions. */ 27843a1e3d319d77c251445339bcc8f82c82b097feeAlan Viverette public final int backgroundColor; 27943a1e3d319d77c251445339bcc8f82c82b097feeAlan Viverette 28043a1e3d319d77c251445339bcc8f82c82b097feeAlan Viverette /** 28143a1e3d319d77c251445339bcc8f82c82b097feeAlan Viverette * The preferred edge type for video captions, one of: 28243a1e3d319d77c251445339bcc8f82c82b097feeAlan Viverette * <ul> 28343a1e3d319d77c251445339bcc8f82c82b097feeAlan Viverette * <li>{@link #EDGE_TYPE_NONE} 28443a1e3d319d77c251445339bcc8f82c82b097feeAlan Viverette * <li>{@link #EDGE_TYPE_OUTLINE} 28543a1e3d319d77c251445339bcc8f82c82b097feeAlan Viverette * <li>{@link #EDGE_TYPE_DROP_SHADOW} 28643a1e3d319d77c251445339bcc8f82c82b097feeAlan Viverette * </ul> 28743a1e3d319d77c251445339bcc8f82c82b097feeAlan Viverette */ 28843a1e3d319d77c251445339bcc8f82c82b097feeAlan Viverette public final int edgeType; 28943a1e3d319d77c251445339bcc8f82c82b097feeAlan Viverette 29043a1e3d319d77c251445339bcc8f82c82b097feeAlan Viverette /** 29143a1e3d319d77c251445339bcc8f82c82b097feeAlan Viverette * The preferred edge color for video captions, if using an edge type 29243a1e3d319d77c251445339bcc8f82c82b097feeAlan Viverette * other than {@link #EDGE_TYPE_NONE}. 29343a1e3d319d77c251445339bcc8f82c82b097feeAlan Viverette */ 29443a1e3d319d77c251445339bcc8f82c82b097feeAlan Viverette public final int edgeColor; 29543a1e3d319d77c251445339bcc8f82c82b097feeAlan Viverette 29643a1e3d319d77c251445339bcc8f82c82b097feeAlan Viverette /** 29743a1e3d319d77c251445339bcc8f82c82b097feeAlan Viverette * @hide 29843a1e3d319d77c251445339bcc8f82c82b097feeAlan Viverette */ 29943a1e3d319d77c251445339bcc8f82c82b097feeAlan Viverette public final String mRawTypeface; 30043a1e3d319d77c251445339bcc8f82c82b097feeAlan Viverette 30143a1e3d319d77c251445339bcc8f82c82b097feeAlan Viverette private Typeface mParsedTypeface; 30243a1e3d319d77c251445339bcc8f82c82b097feeAlan Viverette 30343a1e3d319d77c251445339bcc8f82c82b097feeAlan Viverette private CaptionStyle(int foregroundColor, int backgroundColor, int edgeType, int edgeColor, 30443a1e3d319d77c251445339bcc8f82c82b097feeAlan Viverette String rawTypeface) { 30543a1e3d319d77c251445339bcc8f82c82b097feeAlan Viverette this.foregroundColor = foregroundColor; 30643a1e3d319d77c251445339bcc8f82c82b097feeAlan Viverette this.backgroundColor = backgroundColor; 30743a1e3d319d77c251445339bcc8f82c82b097feeAlan Viverette this.edgeType = edgeType; 30843a1e3d319d77c251445339bcc8f82c82b097feeAlan Viverette this.edgeColor = edgeColor; 30943a1e3d319d77c251445339bcc8f82c82b097feeAlan Viverette 31043a1e3d319d77c251445339bcc8f82c82b097feeAlan Viverette mRawTypeface = rawTypeface; 31143a1e3d319d77c251445339bcc8f82c82b097feeAlan Viverette } 31243a1e3d319d77c251445339bcc8f82c82b097feeAlan Viverette 31343a1e3d319d77c251445339bcc8f82c82b097feeAlan Viverette /** 31469ce69b0e1500bcf0bfa87eaf0b89ae47f552f5cAlan Viverette * @return the preferred {@link Typeface} for video captions, or null if 31569ce69b0e1500bcf0bfa87eaf0b89ae47f552f5cAlan Viverette * not specified 31643a1e3d319d77c251445339bcc8f82c82b097feeAlan Viverette */ 31743a1e3d319d77c251445339bcc8f82c82b097feeAlan Viverette public Typeface getTypeface() { 31843a1e3d319d77c251445339bcc8f82c82b097feeAlan Viverette if (mParsedTypeface == null && !TextUtils.isEmpty(mRawTypeface)) { 31943a1e3d319d77c251445339bcc8f82c82b097feeAlan Viverette mParsedTypeface = Typeface.create(mRawTypeface, Typeface.NORMAL); 32043a1e3d319d77c251445339bcc8f82c82b097feeAlan Viverette } 32143a1e3d319d77c251445339bcc8f82c82b097feeAlan Viverette return mParsedTypeface; 32243a1e3d319d77c251445339bcc8f82c82b097feeAlan Viverette } 32343a1e3d319d77c251445339bcc8f82c82b097feeAlan Viverette 32443a1e3d319d77c251445339bcc8f82c82b097feeAlan Viverette /** 32543a1e3d319d77c251445339bcc8f82c82b097feeAlan Viverette * @hide 32643a1e3d319d77c251445339bcc8f82c82b097feeAlan Viverette */ 32743a1e3d319d77c251445339bcc8f82c82b097feeAlan Viverette public static CaptionStyle getCustomStyle(ContentResolver cr) { 32869ce69b0e1500bcf0bfa87eaf0b89ae47f552f5cAlan Viverette final CaptionStyle defStyle = CaptionStyle.DEFAULT_CUSTOM; 32943a1e3d319d77c251445339bcc8f82c82b097feeAlan Viverette final int foregroundColor = Secure.getInt( 33069ce69b0e1500bcf0bfa87eaf0b89ae47f552f5cAlan Viverette cr, Secure.ACCESSIBILITY_CAPTIONING_FOREGROUND_COLOR, defStyle.foregroundColor); 33169ce69b0e1500bcf0bfa87eaf0b89ae47f552f5cAlan Viverette final int backgroundColor = Secure.getInt( 33269ce69b0e1500bcf0bfa87eaf0b89ae47f552f5cAlan Viverette cr, Secure.ACCESSIBILITY_CAPTIONING_BACKGROUND_COLOR, defStyle.backgroundColor); 33343a1e3d319d77c251445339bcc8f82c82b097feeAlan Viverette final int edgeType = Secure.getInt( 33469ce69b0e1500bcf0bfa87eaf0b89ae47f552f5cAlan Viverette cr, Secure.ACCESSIBILITY_CAPTIONING_EDGE_TYPE, defStyle.edgeType); 33543a1e3d319d77c251445339bcc8f82c82b097feeAlan Viverette final int edgeColor = Secure.getInt( 33669ce69b0e1500bcf0bfa87eaf0b89ae47f552f5cAlan Viverette cr, Secure.ACCESSIBILITY_CAPTIONING_EDGE_COLOR, defStyle.edgeColor); 33743a1e3d319d77c251445339bcc8f82c82b097feeAlan Viverette 33843a1e3d319d77c251445339bcc8f82c82b097feeAlan Viverette String rawTypeface = Secure.getString(cr, Secure.ACCESSIBILITY_CAPTIONING_TYPEFACE); 33943a1e3d319d77c251445339bcc8f82c82b097feeAlan Viverette if (rawTypeface == null) { 34069ce69b0e1500bcf0bfa87eaf0b89ae47f552f5cAlan Viverette rawTypeface = defStyle.mRawTypeface; 34143a1e3d319d77c251445339bcc8f82c82b097feeAlan Viverette } 34243a1e3d319d77c251445339bcc8f82c82b097feeAlan Viverette 34343a1e3d319d77c251445339bcc8f82c82b097feeAlan Viverette return new CaptionStyle( 34443a1e3d319d77c251445339bcc8f82c82b097feeAlan Viverette foregroundColor, backgroundColor, edgeType, edgeColor, rawTypeface); 34543a1e3d319d77c251445339bcc8f82c82b097feeAlan Viverette } 34643a1e3d319d77c251445339bcc8f82c82b097feeAlan Viverette 34743a1e3d319d77c251445339bcc8f82c82b097feeAlan Viverette static { 34843a1e3d319d77c251445339bcc8f82c82b097feeAlan Viverette WHITE_ON_BLACK = new CaptionStyle( 34943a1e3d319d77c251445339bcc8f82c82b097feeAlan Viverette Color.WHITE, Color.BLACK, EDGE_TYPE_NONE, Color.BLACK, null); 35043a1e3d319d77c251445339bcc8f82c82b097feeAlan Viverette BLACK_ON_WHITE = new CaptionStyle( 35143a1e3d319d77c251445339bcc8f82c82b097feeAlan Viverette Color.BLACK, Color.WHITE, EDGE_TYPE_NONE, Color.BLACK, null); 35243a1e3d319d77c251445339bcc8f82c82b097feeAlan Viverette YELLOW_ON_BLACK = new CaptionStyle( 35343a1e3d319d77c251445339bcc8f82c82b097feeAlan Viverette Color.YELLOW, Color.BLACK, EDGE_TYPE_NONE, Color.BLACK, null); 35443a1e3d319d77c251445339bcc8f82c82b097feeAlan Viverette YELLOW_ON_BLUE = new CaptionStyle( 35543a1e3d319d77c251445339bcc8f82c82b097feeAlan Viverette Color.YELLOW, Color.BLUE, EDGE_TYPE_NONE, Color.BLACK, null); 35643a1e3d319d77c251445339bcc8f82c82b097feeAlan Viverette 35743a1e3d319d77c251445339bcc8f82c82b097feeAlan Viverette PRESETS = new CaptionStyle[] { 35843a1e3d319d77c251445339bcc8f82c82b097feeAlan Viverette WHITE_ON_BLACK, BLACK_ON_WHITE, YELLOW_ON_BLACK, YELLOW_ON_BLUE 35943a1e3d319d77c251445339bcc8f82c82b097feeAlan Viverette }; 36043a1e3d319d77c251445339bcc8f82c82b097feeAlan Viverette 36143a1e3d319d77c251445339bcc8f82c82b097feeAlan Viverette DEFAULT_CUSTOM = WHITE_ON_BLACK; 36243a1e3d319d77c251445339bcc8f82c82b097feeAlan Viverette } 36343a1e3d319d77c251445339bcc8f82c82b097feeAlan Viverette } 36469ce69b0e1500bcf0bfa87eaf0b89ae47f552f5cAlan Viverette 36569ce69b0e1500bcf0bfa87eaf0b89ae47f552f5cAlan Viverette /** 36669ce69b0e1500bcf0bfa87eaf0b89ae47f552f5cAlan Viverette * Listener for changes in captioning properties, including enabled state 36769ce69b0e1500bcf0bfa87eaf0b89ae47f552f5cAlan Viverette * and user style preferences. 36869ce69b0e1500bcf0bfa87eaf0b89ae47f552f5cAlan Viverette */ 369d43daf361e993457e64eeeddab6d1a0ebc828c99Alan Viverette public static abstract class CaptioningChangeListener { 37069ce69b0e1500bcf0bfa87eaf0b89ae47f552f5cAlan Viverette /** 37169ce69b0e1500bcf0bfa87eaf0b89ae47f552f5cAlan Viverette * Called when the captioning enabled state changes. 37269ce69b0e1500bcf0bfa87eaf0b89ae47f552f5cAlan Viverette * 37369ce69b0e1500bcf0bfa87eaf0b89ae47f552f5cAlan Viverette * @param enabled the user's new preferred captioning enabled state 37469ce69b0e1500bcf0bfa87eaf0b89ae47f552f5cAlan Viverette */ 37569ce69b0e1500bcf0bfa87eaf0b89ae47f552f5cAlan Viverette public void onEnabledChanged(boolean enabled) { 37669ce69b0e1500bcf0bfa87eaf0b89ae47f552f5cAlan Viverette } 37769ce69b0e1500bcf0bfa87eaf0b89ae47f552f5cAlan Viverette 37869ce69b0e1500bcf0bfa87eaf0b89ae47f552f5cAlan Viverette /** 37969ce69b0e1500bcf0bfa87eaf0b89ae47f552f5cAlan Viverette * Called when the captioning user style changes. 38069ce69b0e1500bcf0bfa87eaf0b89ae47f552f5cAlan Viverette * 38169ce69b0e1500bcf0bfa87eaf0b89ae47f552f5cAlan Viverette * @param userStyle the user's new preferred style 38269ce69b0e1500bcf0bfa87eaf0b89ae47f552f5cAlan Viverette * @see CaptioningManager#getUserStyle() 38369ce69b0e1500bcf0bfa87eaf0b89ae47f552f5cAlan Viverette */ 38469ce69b0e1500bcf0bfa87eaf0b89ae47f552f5cAlan Viverette public void onUserStyleChanged(CaptionStyle userStyle) { 38569ce69b0e1500bcf0bfa87eaf0b89ae47f552f5cAlan Viverette } 38669ce69b0e1500bcf0bfa87eaf0b89ae47f552f5cAlan Viverette 38769ce69b0e1500bcf0bfa87eaf0b89ae47f552f5cAlan Viverette /** 38869ce69b0e1500bcf0bfa87eaf0b89ae47f552f5cAlan Viverette * Called when the captioning locale changes. 38969ce69b0e1500bcf0bfa87eaf0b89ae47f552f5cAlan Viverette * 39069ce69b0e1500bcf0bfa87eaf0b89ae47f552f5cAlan Viverette * @param locale the preferred captioning locale 39169ce69b0e1500bcf0bfa87eaf0b89ae47f552f5cAlan Viverette * @see CaptioningManager#getLocale() 39269ce69b0e1500bcf0bfa87eaf0b89ae47f552f5cAlan Viverette */ 39369ce69b0e1500bcf0bfa87eaf0b89ae47f552f5cAlan Viverette public void onLocaleChanged(Locale locale) { 39469ce69b0e1500bcf0bfa87eaf0b89ae47f552f5cAlan Viverette } 39569ce69b0e1500bcf0bfa87eaf0b89ae47f552f5cAlan Viverette 39669ce69b0e1500bcf0bfa87eaf0b89ae47f552f5cAlan Viverette /** 39769ce69b0e1500bcf0bfa87eaf0b89ae47f552f5cAlan Viverette * Called when the captioning font scaling factor changes. 39869ce69b0e1500bcf0bfa87eaf0b89ae47f552f5cAlan Viverette * 39969ce69b0e1500bcf0bfa87eaf0b89ae47f552f5cAlan Viverette * @param fontScale the preferred font scaling factor 40069ce69b0e1500bcf0bfa87eaf0b89ae47f552f5cAlan Viverette * @see CaptioningManager#getFontScale() 40169ce69b0e1500bcf0bfa87eaf0b89ae47f552f5cAlan Viverette */ 40269ce69b0e1500bcf0bfa87eaf0b89ae47f552f5cAlan Viverette public void onFontScaleChanged(float fontScale) { 40369ce69b0e1500bcf0bfa87eaf0b89ae47f552f5cAlan Viverette } 40469ce69b0e1500bcf0bfa87eaf0b89ae47f552f5cAlan Viverette } 40543a1e3d319d77c251445339bcc8f82c82b097feeAlan Viverette} 406