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 19e88aee8ad85b01229b12dbc0c3cc2f0b8b490192Alan Viveretteimport android.annotation.NonNull; 20e88aee8ad85b01229b12dbc0c3cc2f0b8b490192Alan Viveretteimport android.annotation.Nullable; 21d86b8fea43ebb6e5c31691b44d8ceb0d8d3c9072Jeff Sharkeyimport android.annotation.SystemService; 2243a1e3d319d77c251445339bcc8f82c82b097feeAlan Viveretteimport android.content.ContentResolver; 2369ce69b0e1500bcf0bfa87eaf0b89ae47f552f5cAlan Viveretteimport android.content.Context; 2469ce69b0e1500bcf0bfa87eaf0b89ae47f552f5cAlan Viveretteimport android.database.ContentObserver; 2543a1e3d319d77c251445339bcc8f82c82b097feeAlan Viveretteimport android.graphics.Color; 2643a1e3d319d77c251445339bcc8f82c82b097feeAlan Viveretteimport android.graphics.Typeface; 2769ce69b0e1500bcf0bfa87eaf0b89ae47f552f5cAlan Viveretteimport android.net.Uri; 2869ce69b0e1500bcf0bfa87eaf0b89ae47f552f5cAlan Viveretteimport android.os.Handler; 2943a1e3d319d77c251445339bcc8f82c82b097feeAlan Viveretteimport android.provider.Settings.Secure; 3043a1e3d319d77c251445339bcc8f82c82b097feeAlan Viveretteimport android.text.TextUtils; 3143a1e3d319d77c251445339bcc8f82c82b097feeAlan Viverette 3269ce69b0e1500bcf0bfa87eaf0b89ae47f552f5cAlan Viveretteimport java.util.ArrayList; 3343a1e3d319d77c251445339bcc8f82c82b097feeAlan Viveretteimport java.util.Locale; 3443a1e3d319d77c251445339bcc8f82c82b097feeAlan Viverette 3543a1e3d319d77c251445339bcc8f82c82b097feeAlan Viverette/** 3669ce69b0e1500bcf0bfa87eaf0b89ae47f552f5cAlan Viverette * Contains methods for accessing and monitoring preferred video captioning state and visual 3743a1e3d319d77c251445339bcc8f82c82b097feeAlan Viverette * properties. 3843a1e3d319d77c251445339bcc8f82c82b097feeAlan Viverette */ 39d86b8fea43ebb6e5c31691b44d8ceb0d8d3c9072Jeff Sharkey@SystemService(Context.CAPTIONING_SERVICE) 4043a1e3d319d77c251445339bcc8f82c82b097feeAlan Viverettepublic class CaptioningManager { 4169ce69b0e1500bcf0bfa87eaf0b89ae47f552f5cAlan Viverette /** Default captioning enabled value. */ 4269ce69b0e1500bcf0bfa87eaf0b89ae47f552f5cAlan Viverette private static final int DEFAULT_ENABLED = 0; 4343a1e3d319d77c251445339bcc8f82c82b097feeAlan Viverette 4469ce69b0e1500bcf0bfa87eaf0b89ae47f552f5cAlan Viverette /** Default style preset as an index into {@link CaptionStyle#PRESETS}. */ 4543a1e3d319d77c251445339bcc8f82c82b097feeAlan Viverette private static final int DEFAULT_PRESET = 0; 4669ce69b0e1500bcf0bfa87eaf0b89ae47f552f5cAlan Viverette 4769ce69b0e1500bcf0bfa87eaf0b89ae47f552f5cAlan Viverette /** Default scaling value for caption fonts. */ 4869ce69b0e1500bcf0bfa87eaf0b89ae47f552f5cAlan Viverette private static final float DEFAULT_FONT_SCALE = 1; 4969ce69b0e1500bcf0bfa87eaf0b89ae47f552f5cAlan Viverette 50727dcc7e6b43902edaab88e7adfb1a8b88fd482bAlan Viverette private final ArrayList<CaptioningChangeListener> mListeners = new ArrayList<>(); 5169ce69b0e1500bcf0bfa87eaf0b89ae47f552f5cAlan Viverette private final ContentResolver mContentResolver; 52727dcc7e6b43902edaab88e7adfb1a8b88fd482bAlan Viverette private final ContentObserver mContentObserver; 5369ce69b0e1500bcf0bfa87eaf0b89ae47f552f5cAlan Viverette 5469ce69b0e1500bcf0bfa87eaf0b89ae47f552f5cAlan Viverette /** 5569ce69b0e1500bcf0bfa87eaf0b89ae47f552f5cAlan Viverette * Creates a new captioning manager for the specified context. 5669ce69b0e1500bcf0bfa87eaf0b89ae47f552f5cAlan Viverette * 5769ce69b0e1500bcf0bfa87eaf0b89ae47f552f5cAlan Viverette * @hide 5869ce69b0e1500bcf0bfa87eaf0b89ae47f552f5cAlan Viverette */ 5969ce69b0e1500bcf0bfa87eaf0b89ae47f552f5cAlan Viverette public CaptioningManager(Context context) { 6069ce69b0e1500bcf0bfa87eaf0b89ae47f552f5cAlan Viverette mContentResolver = context.getContentResolver(); 61727dcc7e6b43902edaab88e7adfb1a8b88fd482bAlan Viverette 62727dcc7e6b43902edaab88e7adfb1a8b88fd482bAlan Viverette final Handler handler = new Handler(context.getMainLooper()); 63727dcc7e6b43902edaab88e7adfb1a8b88fd482bAlan Viverette mContentObserver = new MyContentObserver(handler); 6469ce69b0e1500bcf0bfa87eaf0b89ae47f552f5cAlan Viverette } 6543a1e3d319d77c251445339bcc8f82c82b097feeAlan Viverette 6643a1e3d319d77c251445339bcc8f82c82b097feeAlan Viverette /** 6769ce69b0e1500bcf0bfa87eaf0b89ae47f552f5cAlan Viverette * @return the user's preferred captioning enabled state 6843a1e3d319d77c251445339bcc8f82c82b097feeAlan Viverette */ 6969ce69b0e1500bcf0bfa87eaf0b89ae47f552f5cAlan Viverette public final boolean isEnabled() { 7069ce69b0e1500bcf0bfa87eaf0b89ae47f552f5cAlan Viverette return Secure.getInt( 7169ce69b0e1500bcf0bfa87eaf0b89ae47f552f5cAlan Viverette mContentResolver, Secure.ACCESSIBILITY_CAPTIONING_ENABLED, DEFAULT_ENABLED) == 1; 7243a1e3d319d77c251445339bcc8f82c82b097feeAlan Viverette } 7343a1e3d319d77c251445339bcc8f82c82b097feeAlan Viverette 7443a1e3d319d77c251445339bcc8f82c82b097feeAlan Viverette /** 7569ce69b0e1500bcf0bfa87eaf0b89ae47f552f5cAlan Viverette * @return the raw locale string for the user's preferred captioning 7669ce69b0e1500bcf0bfa87eaf0b89ae47f552f5cAlan Viverette * language 7743a1e3d319d77c251445339bcc8f82c82b097feeAlan Viverette * @hide 7843a1e3d319d77c251445339bcc8f82c82b097feeAlan Viverette */ 79e88aee8ad85b01229b12dbc0c3cc2f0b8b490192Alan Viverette @Nullable 8069ce69b0e1500bcf0bfa87eaf0b89ae47f552f5cAlan Viverette public final String getRawLocale() { 8169ce69b0e1500bcf0bfa87eaf0b89ae47f552f5cAlan Viverette return Secure.getString(mContentResolver, Secure.ACCESSIBILITY_CAPTIONING_LOCALE); 8243a1e3d319d77c251445339bcc8f82c82b097feeAlan Viverette } 8343a1e3d319d77c251445339bcc8f82c82b097feeAlan Viverette 8443a1e3d319d77c251445339bcc8f82c82b097feeAlan Viverette /** 8569ce69b0e1500bcf0bfa87eaf0b89ae47f552f5cAlan Viverette * @return the locale for the user's preferred captioning language, or null 8669ce69b0e1500bcf0bfa87eaf0b89ae47f552f5cAlan Viverette * if not specified 8743a1e3d319d77c251445339bcc8f82c82b097feeAlan Viverette */ 88e88aee8ad85b01229b12dbc0c3cc2f0b8b490192Alan Viverette @Nullable 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 */ 128e88aee8ad85b01229b12dbc0c3cc2f0b8b490192Alan Viverette @NonNull 12969ce69b0e1500bcf0bfa87eaf0b89ae47f552f5cAlan Viverette public CaptionStyle getUserStyle() { 13069ce69b0e1500bcf0bfa87eaf0b89ae47f552f5cAlan Viverette final int preset = getRawUserStyle(); 13169ce69b0e1500bcf0bfa87eaf0b89ae47f552f5cAlan Viverette if (preset == CaptionStyle.PRESET_CUSTOM) { 13269ce69b0e1500bcf0bfa87eaf0b89ae47f552f5cAlan Viverette return CaptionStyle.getCustomStyle(mContentResolver); 13369ce69b0e1500bcf0bfa87eaf0b89ae47f552f5cAlan Viverette } 13469ce69b0e1500bcf0bfa87eaf0b89ae47f552f5cAlan Viverette 13569ce69b0e1500bcf0bfa87eaf0b89ae47f552f5cAlan Viverette return CaptionStyle.PRESETS[preset]; 13669ce69b0e1500bcf0bfa87eaf0b89ae47f552f5cAlan Viverette } 13769ce69b0e1500bcf0bfa87eaf0b89ae47f552f5cAlan Viverette 13869ce69b0e1500bcf0bfa87eaf0b89ae47f552f5cAlan Viverette /** 13969ce69b0e1500bcf0bfa87eaf0b89ae47f552f5cAlan Viverette * Adds a listener for changes in the user's preferred captioning enabled 14069ce69b0e1500bcf0bfa87eaf0b89ae47f552f5cAlan Viverette * state and visual properties. 14169ce69b0e1500bcf0bfa87eaf0b89ae47f552f5cAlan Viverette * 14269ce69b0e1500bcf0bfa87eaf0b89ae47f552f5cAlan Viverette * @param listener the listener to add 14369ce69b0e1500bcf0bfa87eaf0b89ae47f552f5cAlan Viverette */ 144e88aee8ad85b01229b12dbc0c3cc2f0b8b490192Alan Viverette public void addCaptioningChangeListener(@NonNull CaptioningChangeListener listener) { 14569ce69b0e1500bcf0bfa87eaf0b89ae47f552f5cAlan Viverette synchronized (mListeners) { 14669ce69b0e1500bcf0bfa87eaf0b89ae47f552f5cAlan Viverette if (mListeners.isEmpty()) { 14769ce69b0e1500bcf0bfa87eaf0b89ae47f552f5cAlan Viverette registerObserver(Secure.ACCESSIBILITY_CAPTIONING_ENABLED); 14869ce69b0e1500bcf0bfa87eaf0b89ae47f552f5cAlan Viverette registerObserver(Secure.ACCESSIBILITY_CAPTIONING_FOREGROUND_COLOR); 14969ce69b0e1500bcf0bfa87eaf0b89ae47f552f5cAlan Viverette registerObserver(Secure.ACCESSIBILITY_CAPTIONING_BACKGROUND_COLOR); 150e88aee8ad85b01229b12dbc0c3cc2f0b8b490192Alan Viverette registerObserver(Secure.ACCESSIBILITY_CAPTIONING_WINDOW_COLOR); 15169ce69b0e1500bcf0bfa87eaf0b89ae47f552f5cAlan Viverette registerObserver(Secure.ACCESSIBILITY_CAPTIONING_EDGE_TYPE); 15269ce69b0e1500bcf0bfa87eaf0b89ae47f552f5cAlan Viverette registerObserver(Secure.ACCESSIBILITY_CAPTIONING_EDGE_COLOR); 15369ce69b0e1500bcf0bfa87eaf0b89ae47f552f5cAlan Viverette registerObserver(Secure.ACCESSIBILITY_CAPTIONING_TYPEFACE); 15469ce69b0e1500bcf0bfa87eaf0b89ae47f552f5cAlan Viverette registerObserver(Secure.ACCESSIBILITY_CAPTIONING_FONT_SCALE); 15569ce69b0e1500bcf0bfa87eaf0b89ae47f552f5cAlan Viverette registerObserver(Secure.ACCESSIBILITY_CAPTIONING_LOCALE); 156e88aee8ad85b01229b12dbc0c3cc2f0b8b490192Alan Viverette registerObserver(Secure.ACCESSIBILITY_CAPTIONING_PRESET); 15769ce69b0e1500bcf0bfa87eaf0b89ae47f552f5cAlan Viverette } 15869ce69b0e1500bcf0bfa87eaf0b89ae47f552f5cAlan Viverette 15969ce69b0e1500bcf0bfa87eaf0b89ae47f552f5cAlan Viverette mListeners.add(listener); 16069ce69b0e1500bcf0bfa87eaf0b89ae47f552f5cAlan Viverette } 16169ce69b0e1500bcf0bfa87eaf0b89ae47f552f5cAlan Viverette } 16269ce69b0e1500bcf0bfa87eaf0b89ae47f552f5cAlan Viverette 16369ce69b0e1500bcf0bfa87eaf0b89ae47f552f5cAlan Viverette private void registerObserver(String key) { 16469ce69b0e1500bcf0bfa87eaf0b89ae47f552f5cAlan Viverette mContentResolver.registerContentObserver(Secure.getUriFor(key), false, mContentObserver); 16569ce69b0e1500bcf0bfa87eaf0b89ae47f552f5cAlan Viverette } 16669ce69b0e1500bcf0bfa87eaf0b89ae47f552f5cAlan Viverette 16769ce69b0e1500bcf0bfa87eaf0b89ae47f552f5cAlan Viverette /** 16869ce69b0e1500bcf0bfa87eaf0b89ae47f552f5cAlan Viverette * Removes a listener previously added using 169d43daf361e993457e64eeeddab6d1a0ebc828c99Alan Viverette * {@link #addCaptioningChangeListener}. 17069ce69b0e1500bcf0bfa87eaf0b89ae47f552f5cAlan Viverette * 17169ce69b0e1500bcf0bfa87eaf0b89ae47f552f5cAlan Viverette * @param listener the listener to remove 17269ce69b0e1500bcf0bfa87eaf0b89ae47f552f5cAlan Viverette */ 173e88aee8ad85b01229b12dbc0c3cc2f0b8b490192Alan Viverette public void removeCaptioningChangeListener(@NonNull CaptioningChangeListener listener) { 17469ce69b0e1500bcf0bfa87eaf0b89ae47f552f5cAlan Viverette synchronized (mListeners) { 17569ce69b0e1500bcf0bfa87eaf0b89ae47f552f5cAlan Viverette mListeners.remove(listener); 17669ce69b0e1500bcf0bfa87eaf0b89ae47f552f5cAlan Viverette 17769ce69b0e1500bcf0bfa87eaf0b89ae47f552f5cAlan Viverette if (mListeners.isEmpty()) { 17869ce69b0e1500bcf0bfa87eaf0b89ae47f552f5cAlan Viverette mContentResolver.unregisterContentObserver(mContentObserver); 17969ce69b0e1500bcf0bfa87eaf0b89ae47f552f5cAlan Viverette } 18069ce69b0e1500bcf0bfa87eaf0b89ae47f552f5cAlan Viverette } 18169ce69b0e1500bcf0bfa87eaf0b89ae47f552f5cAlan Viverette } 18269ce69b0e1500bcf0bfa87eaf0b89ae47f552f5cAlan Viverette 18369ce69b0e1500bcf0bfa87eaf0b89ae47f552f5cAlan Viverette private void notifyEnabledChanged() { 18469ce69b0e1500bcf0bfa87eaf0b89ae47f552f5cAlan Viverette final boolean enabled = isEnabled(); 18569ce69b0e1500bcf0bfa87eaf0b89ae47f552f5cAlan Viverette synchronized (mListeners) { 18669ce69b0e1500bcf0bfa87eaf0b89ae47f552f5cAlan Viverette for (CaptioningChangeListener listener : mListeners) { 18769ce69b0e1500bcf0bfa87eaf0b89ae47f552f5cAlan Viverette listener.onEnabledChanged(enabled); 18869ce69b0e1500bcf0bfa87eaf0b89ae47f552f5cAlan Viverette } 18969ce69b0e1500bcf0bfa87eaf0b89ae47f552f5cAlan Viverette } 19069ce69b0e1500bcf0bfa87eaf0b89ae47f552f5cAlan Viverette } 19169ce69b0e1500bcf0bfa87eaf0b89ae47f552f5cAlan Viverette 19269ce69b0e1500bcf0bfa87eaf0b89ae47f552f5cAlan Viverette private void notifyUserStyleChanged() { 19369ce69b0e1500bcf0bfa87eaf0b89ae47f552f5cAlan Viverette final CaptionStyle userStyle = getUserStyle(); 19469ce69b0e1500bcf0bfa87eaf0b89ae47f552f5cAlan Viverette synchronized (mListeners) { 19569ce69b0e1500bcf0bfa87eaf0b89ae47f552f5cAlan Viverette for (CaptioningChangeListener listener : mListeners) { 19669ce69b0e1500bcf0bfa87eaf0b89ae47f552f5cAlan Viverette listener.onUserStyleChanged(userStyle); 19769ce69b0e1500bcf0bfa87eaf0b89ae47f552f5cAlan Viverette } 19869ce69b0e1500bcf0bfa87eaf0b89ae47f552f5cAlan Viverette } 19943a1e3d319d77c251445339bcc8f82c82b097feeAlan Viverette } 20043a1e3d319d77c251445339bcc8f82c82b097feeAlan Viverette 20169ce69b0e1500bcf0bfa87eaf0b89ae47f552f5cAlan Viverette private void notifyLocaleChanged() { 20269ce69b0e1500bcf0bfa87eaf0b89ae47f552f5cAlan Viverette final Locale locale = getLocale(); 20369ce69b0e1500bcf0bfa87eaf0b89ae47f552f5cAlan Viverette synchronized (mListeners) { 20469ce69b0e1500bcf0bfa87eaf0b89ae47f552f5cAlan Viverette for (CaptioningChangeListener listener : mListeners) { 20569ce69b0e1500bcf0bfa87eaf0b89ae47f552f5cAlan Viverette listener.onLocaleChanged(locale); 20669ce69b0e1500bcf0bfa87eaf0b89ae47f552f5cAlan Viverette } 20769ce69b0e1500bcf0bfa87eaf0b89ae47f552f5cAlan Viverette } 20869ce69b0e1500bcf0bfa87eaf0b89ae47f552f5cAlan Viverette } 20969ce69b0e1500bcf0bfa87eaf0b89ae47f552f5cAlan Viverette 21069ce69b0e1500bcf0bfa87eaf0b89ae47f552f5cAlan Viverette private void notifyFontScaleChanged() { 21169ce69b0e1500bcf0bfa87eaf0b89ae47f552f5cAlan Viverette final float fontScale = getFontScale(); 21269ce69b0e1500bcf0bfa87eaf0b89ae47f552f5cAlan Viverette synchronized (mListeners) { 21369ce69b0e1500bcf0bfa87eaf0b89ae47f552f5cAlan Viverette for (CaptioningChangeListener listener : mListeners) { 21469ce69b0e1500bcf0bfa87eaf0b89ae47f552f5cAlan Viverette listener.onFontScaleChanged(fontScale); 21569ce69b0e1500bcf0bfa87eaf0b89ae47f552f5cAlan Viverette } 21669ce69b0e1500bcf0bfa87eaf0b89ae47f552f5cAlan Viverette } 21769ce69b0e1500bcf0bfa87eaf0b89ae47f552f5cAlan Viverette } 21869ce69b0e1500bcf0bfa87eaf0b89ae47f552f5cAlan Viverette 219727dcc7e6b43902edaab88e7adfb1a8b88fd482bAlan Viverette private class MyContentObserver extends ContentObserver { 220727dcc7e6b43902edaab88e7adfb1a8b88fd482bAlan Viverette private final Handler mHandler; 221727dcc7e6b43902edaab88e7adfb1a8b88fd482bAlan Viverette 222727dcc7e6b43902edaab88e7adfb1a8b88fd482bAlan Viverette public MyContentObserver(Handler handler) { 223727dcc7e6b43902edaab88e7adfb1a8b88fd482bAlan Viverette super(handler); 224727dcc7e6b43902edaab88e7adfb1a8b88fd482bAlan Viverette 225727dcc7e6b43902edaab88e7adfb1a8b88fd482bAlan Viverette mHandler = handler; 226727dcc7e6b43902edaab88e7adfb1a8b88fd482bAlan Viverette } 227727dcc7e6b43902edaab88e7adfb1a8b88fd482bAlan Viverette 22869ce69b0e1500bcf0bfa87eaf0b89ae47f552f5cAlan Viverette @Override 22969ce69b0e1500bcf0bfa87eaf0b89ae47f552f5cAlan Viverette public void onChange(boolean selfChange, Uri uri) { 23069ce69b0e1500bcf0bfa87eaf0b89ae47f552f5cAlan Viverette final String uriPath = uri.getPath(); 23169ce69b0e1500bcf0bfa87eaf0b89ae47f552f5cAlan Viverette final String name = uriPath.substring(uriPath.lastIndexOf('/') + 1); 23269ce69b0e1500bcf0bfa87eaf0b89ae47f552f5cAlan Viverette if (Secure.ACCESSIBILITY_CAPTIONING_ENABLED.equals(name)) { 23369ce69b0e1500bcf0bfa87eaf0b89ae47f552f5cAlan Viverette notifyEnabledChanged(); 23469ce69b0e1500bcf0bfa87eaf0b89ae47f552f5cAlan Viverette } else if (Secure.ACCESSIBILITY_CAPTIONING_LOCALE.equals(name)) { 23569ce69b0e1500bcf0bfa87eaf0b89ae47f552f5cAlan Viverette notifyLocaleChanged(); 23669ce69b0e1500bcf0bfa87eaf0b89ae47f552f5cAlan Viverette } else if (Secure.ACCESSIBILITY_CAPTIONING_FONT_SCALE.equals(name)) { 23769ce69b0e1500bcf0bfa87eaf0b89ae47f552f5cAlan Viverette notifyFontScaleChanged(); 23869ce69b0e1500bcf0bfa87eaf0b89ae47f552f5cAlan Viverette } else { 23969ce69b0e1500bcf0bfa87eaf0b89ae47f552f5cAlan Viverette // We only need a single callback when multiple style properties 24069ce69b0e1500bcf0bfa87eaf0b89ae47f552f5cAlan Viverette // change in rapid succession. 24169ce69b0e1500bcf0bfa87eaf0b89ae47f552f5cAlan Viverette mHandler.removeCallbacks(mStyleChangedRunnable); 24269ce69b0e1500bcf0bfa87eaf0b89ae47f552f5cAlan Viverette mHandler.post(mStyleChangedRunnable); 24369ce69b0e1500bcf0bfa87eaf0b89ae47f552f5cAlan Viverette } 24469ce69b0e1500bcf0bfa87eaf0b89ae47f552f5cAlan Viverette } 24569ce69b0e1500bcf0bfa87eaf0b89ae47f552f5cAlan Viverette }; 24669ce69b0e1500bcf0bfa87eaf0b89ae47f552f5cAlan Viverette 24769ce69b0e1500bcf0bfa87eaf0b89ae47f552f5cAlan Viverette /** 24869ce69b0e1500bcf0bfa87eaf0b89ae47f552f5cAlan Viverette * Runnable posted when user style properties change. This is used to 24969ce69b0e1500bcf0bfa87eaf0b89ae47f552f5cAlan Viverette * prevent unnecessary change notifications when multiple properties change 25069ce69b0e1500bcf0bfa87eaf0b89ae47f552f5cAlan Viverette * in rapid succession. 25169ce69b0e1500bcf0bfa87eaf0b89ae47f552f5cAlan Viverette */ 25269ce69b0e1500bcf0bfa87eaf0b89ae47f552f5cAlan Viverette private final Runnable mStyleChangedRunnable = new Runnable() { 25369ce69b0e1500bcf0bfa87eaf0b89ae47f552f5cAlan Viverette @Override 25469ce69b0e1500bcf0bfa87eaf0b89ae47f552f5cAlan Viverette public void run() { 25569ce69b0e1500bcf0bfa87eaf0b89ae47f552f5cAlan Viverette notifyUserStyleChanged(); 25669ce69b0e1500bcf0bfa87eaf0b89ae47f552f5cAlan Viverette } 25769ce69b0e1500bcf0bfa87eaf0b89ae47f552f5cAlan Viverette }; 25869ce69b0e1500bcf0bfa87eaf0b89ae47f552f5cAlan Viverette 25969ce69b0e1500bcf0bfa87eaf0b89ae47f552f5cAlan Viverette /** 26069ce69b0e1500bcf0bfa87eaf0b89ae47f552f5cAlan Viverette * Specifies visual properties for video captions, including foreground and 26169ce69b0e1500bcf0bfa87eaf0b89ae47f552f5cAlan Viverette * background colors, edge properties, and typeface. 26269ce69b0e1500bcf0bfa87eaf0b89ae47f552f5cAlan Viverette */ 26343a1e3d319d77c251445339bcc8f82c82b097feeAlan Viverette public static final class CaptionStyle { 2647e4019b7413511bb60e19d6011c80baf00e40b76Alan Viverette /** 2657e4019b7413511bb60e19d6011c80baf00e40b76Alan Viverette * Packed value for a color of 'none' and a cached opacity of 100%. 2667e4019b7413511bb60e19d6011c80baf00e40b76Alan Viverette * 2677e4019b7413511bb60e19d6011c80baf00e40b76Alan Viverette * @hide 2687e4019b7413511bb60e19d6011c80baf00e40b76Alan Viverette */ 269ce32ea7345f0157a595b1dd4306a9a65f444d7c2Alan Viverette private static final int COLOR_NONE_OPAQUE = 0x000000FF; 270ce32ea7345f0157a595b1dd4306a9a65f444d7c2Alan Viverette 2717e4019b7413511bb60e19d6011c80baf00e40b76Alan Viverette /** 2727e4019b7413511bb60e19d6011c80baf00e40b76Alan Viverette * Packed value for a color of 'default' and opacity of 100%. 2737e4019b7413511bb60e19d6011c80baf00e40b76Alan Viverette * 2747e4019b7413511bb60e19d6011c80baf00e40b76Alan Viverette * @hide 2757e4019b7413511bb60e19d6011c80baf00e40b76Alan Viverette */ 2767e4019b7413511bb60e19d6011c80baf00e40b76Alan Viverette public static final int COLOR_UNSPECIFIED = 0x00FFFFFF; 277e88aee8ad85b01229b12dbc0c3cc2f0b8b490192Alan Viverette 27843a1e3d319d77c251445339bcc8f82c82b097feeAlan Viverette private static final CaptionStyle WHITE_ON_BLACK; 27943a1e3d319d77c251445339bcc8f82c82b097feeAlan Viverette private static final CaptionStyle BLACK_ON_WHITE; 28043a1e3d319d77c251445339bcc8f82c82b097feeAlan Viverette private static final CaptionStyle YELLOW_ON_BLACK; 28143a1e3d319d77c251445339bcc8f82c82b097feeAlan Viverette private static final CaptionStyle YELLOW_ON_BLUE; 28243a1e3d319d77c251445339bcc8f82c82b097feeAlan Viverette private static final CaptionStyle DEFAULT_CUSTOM; 283e88aee8ad85b01229b12dbc0c3cc2f0b8b490192Alan Viverette private static final CaptionStyle UNSPECIFIED; 284e88aee8ad85b01229b12dbc0c3cc2f0b8b490192Alan Viverette 285e88aee8ad85b01229b12dbc0c3cc2f0b8b490192Alan Viverette /** The default caption style used to fill in unspecified values. @hide */ 286e88aee8ad85b01229b12dbc0c3cc2f0b8b490192Alan Viverette public static final CaptionStyle DEFAULT; 28743a1e3d319d77c251445339bcc8f82c82b097feeAlan Viverette 28843a1e3d319d77c251445339bcc8f82c82b097feeAlan Viverette /** @hide */ 28943a1e3d319d77c251445339bcc8f82c82b097feeAlan Viverette public static final CaptionStyle[] PRESETS; 29043a1e3d319d77c251445339bcc8f82c82b097feeAlan Viverette 29143a1e3d319d77c251445339bcc8f82c82b097feeAlan Viverette /** @hide */ 29243a1e3d319d77c251445339bcc8f82c82b097feeAlan Viverette public static final int PRESET_CUSTOM = -1; 29343a1e3d319d77c251445339bcc8f82c82b097feeAlan Viverette 294e88aee8ad85b01229b12dbc0c3cc2f0b8b490192Alan Viverette /** Unspecified edge type value. */ 295e88aee8ad85b01229b12dbc0c3cc2f0b8b490192Alan Viverette public static final int EDGE_TYPE_UNSPECIFIED = -1; 296e88aee8ad85b01229b12dbc0c3cc2f0b8b490192Alan Viverette 29743a1e3d319d77c251445339bcc8f82c82b097feeAlan Viverette /** Edge type value specifying no character edges. */ 29843a1e3d319d77c251445339bcc8f82c82b097feeAlan Viverette public static final int EDGE_TYPE_NONE = 0; 29943a1e3d319d77c251445339bcc8f82c82b097feeAlan Viverette 30043a1e3d319d77c251445339bcc8f82c82b097feeAlan Viverette /** Edge type value specifying uniformly outlined character edges. */ 30143a1e3d319d77c251445339bcc8f82c82b097feeAlan Viverette public static final int EDGE_TYPE_OUTLINE = 1; 30243a1e3d319d77c251445339bcc8f82c82b097feeAlan Viverette 30343a1e3d319d77c251445339bcc8f82c82b097feeAlan Viverette /** Edge type value specifying drop-shadowed character edges. */ 30443a1e3d319d77c251445339bcc8f82c82b097feeAlan Viverette public static final int EDGE_TYPE_DROP_SHADOW = 2; 30543a1e3d319d77c251445339bcc8f82c82b097feeAlan Viverette 306ce32ea7345f0157a595b1dd4306a9a65f444d7c2Alan Viverette /** Edge type value specifying raised bevel character edges. */ 307ce32ea7345f0157a595b1dd4306a9a65f444d7c2Alan Viverette public static final int EDGE_TYPE_RAISED = 3; 308ce32ea7345f0157a595b1dd4306a9a65f444d7c2Alan Viverette 309ce32ea7345f0157a595b1dd4306a9a65f444d7c2Alan Viverette /** Edge type value specifying depressed bevel character edges. */ 310ce32ea7345f0157a595b1dd4306a9a65f444d7c2Alan Viverette public static final int EDGE_TYPE_DEPRESSED = 4; 311ce32ea7345f0157a595b1dd4306a9a65f444d7c2Alan Viverette 31243a1e3d319d77c251445339bcc8f82c82b097feeAlan Viverette /** The preferred foreground color for video captions. */ 31343a1e3d319d77c251445339bcc8f82c82b097feeAlan Viverette public final int foregroundColor; 31443a1e3d319d77c251445339bcc8f82c82b097feeAlan Viverette 31543a1e3d319d77c251445339bcc8f82c82b097feeAlan Viverette /** The preferred background color for video captions. */ 31643a1e3d319d77c251445339bcc8f82c82b097feeAlan Viverette public final int backgroundColor; 31743a1e3d319d77c251445339bcc8f82c82b097feeAlan Viverette 31843a1e3d319d77c251445339bcc8f82c82b097feeAlan Viverette /** 31943a1e3d319d77c251445339bcc8f82c82b097feeAlan Viverette * The preferred edge type for video captions, one of: 32043a1e3d319d77c251445339bcc8f82c82b097feeAlan Viverette * <ul> 321e88aee8ad85b01229b12dbc0c3cc2f0b8b490192Alan Viverette * <li>{@link #EDGE_TYPE_UNSPECIFIED} 32243a1e3d319d77c251445339bcc8f82c82b097feeAlan Viverette * <li>{@link #EDGE_TYPE_NONE} 32343a1e3d319d77c251445339bcc8f82c82b097feeAlan Viverette * <li>{@link #EDGE_TYPE_OUTLINE} 32443a1e3d319d77c251445339bcc8f82c82b097feeAlan Viverette * <li>{@link #EDGE_TYPE_DROP_SHADOW} 325ce32ea7345f0157a595b1dd4306a9a65f444d7c2Alan Viverette * <li>{@link #EDGE_TYPE_RAISED} 326ce32ea7345f0157a595b1dd4306a9a65f444d7c2Alan Viverette * <li>{@link #EDGE_TYPE_DEPRESSED} 32743a1e3d319d77c251445339bcc8f82c82b097feeAlan Viverette * </ul> 32843a1e3d319d77c251445339bcc8f82c82b097feeAlan Viverette */ 32943a1e3d319d77c251445339bcc8f82c82b097feeAlan Viverette public final int edgeType; 33043a1e3d319d77c251445339bcc8f82c82b097feeAlan Viverette 33143a1e3d319d77c251445339bcc8f82c82b097feeAlan Viverette /** 33243a1e3d319d77c251445339bcc8f82c82b097feeAlan Viverette * The preferred edge color for video captions, if using an edge type 33343a1e3d319d77c251445339bcc8f82c82b097feeAlan Viverette * other than {@link #EDGE_TYPE_NONE}. 33443a1e3d319d77c251445339bcc8f82c82b097feeAlan Viverette */ 33543a1e3d319d77c251445339bcc8f82c82b097feeAlan Viverette public final int edgeColor; 33643a1e3d319d77c251445339bcc8f82c82b097feeAlan Viverette 33755d70620d9fda8afafb2fdec59757a710eec0e89Alan Viverette /** The preferred window color for video captions. */ 33855d70620d9fda8afafb2fdec59757a710eec0e89Alan Viverette public final int windowColor; 33955d70620d9fda8afafb2fdec59757a710eec0e89Alan Viverette 34043a1e3d319d77c251445339bcc8f82c82b097feeAlan Viverette /** 34143a1e3d319d77c251445339bcc8f82c82b097feeAlan Viverette * @hide 34243a1e3d319d77c251445339bcc8f82c82b097feeAlan Viverette */ 34343a1e3d319d77c251445339bcc8f82c82b097feeAlan Viverette public final String mRawTypeface; 34443a1e3d319d77c251445339bcc8f82c82b097feeAlan Viverette 345f1820064d9cfcf43e4cfd16872acca3bf5a7d94bAlan Viverette private final boolean mHasForegroundColor; 346f1820064d9cfcf43e4cfd16872acca3bf5a7d94bAlan Viverette private final boolean mHasBackgroundColor; 347f1820064d9cfcf43e4cfd16872acca3bf5a7d94bAlan Viverette private final boolean mHasEdgeType; 348f1820064d9cfcf43e4cfd16872acca3bf5a7d94bAlan Viverette private final boolean mHasEdgeColor; 349f1820064d9cfcf43e4cfd16872acca3bf5a7d94bAlan Viverette private final boolean mHasWindowColor; 350f1820064d9cfcf43e4cfd16872acca3bf5a7d94bAlan Viverette 351f1820064d9cfcf43e4cfd16872acca3bf5a7d94bAlan Viverette /** Lazily-created typeface based on the raw typeface string. */ 35243a1e3d319d77c251445339bcc8f82c82b097feeAlan Viverette private Typeface mParsedTypeface; 35343a1e3d319d77c251445339bcc8f82c82b097feeAlan Viverette 35443a1e3d319d77c251445339bcc8f82c82b097feeAlan Viverette private CaptionStyle(int foregroundColor, int backgroundColor, int edgeType, int edgeColor, 35555d70620d9fda8afafb2fdec59757a710eec0e89Alan Viverette int windowColor, String rawTypeface) { 3567e4019b7413511bb60e19d6011c80baf00e40b76Alan Viverette mHasForegroundColor = hasColor(foregroundColor); 3577e4019b7413511bb60e19d6011c80baf00e40b76Alan Viverette mHasBackgroundColor = hasColor(backgroundColor); 358f1820064d9cfcf43e4cfd16872acca3bf5a7d94bAlan Viverette mHasEdgeType = edgeType != EDGE_TYPE_UNSPECIFIED; 3597e4019b7413511bb60e19d6011c80baf00e40b76Alan Viverette mHasEdgeColor = hasColor(edgeColor); 3607e4019b7413511bb60e19d6011c80baf00e40b76Alan Viverette mHasWindowColor = hasColor(windowColor); 361f1820064d9cfcf43e4cfd16872acca3bf5a7d94bAlan Viverette 362f1820064d9cfcf43e4cfd16872acca3bf5a7d94bAlan Viverette // Always use valid colors, even when no override is specified, to 363f1820064d9cfcf43e4cfd16872acca3bf5a7d94bAlan Viverette // ensure backwards compatibility with apps targeting KitKat MR2. 364f1820064d9cfcf43e4cfd16872acca3bf5a7d94bAlan Viverette this.foregroundColor = mHasForegroundColor ? foregroundColor : Color.WHITE; 365f1820064d9cfcf43e4cfd16872acca3bf5a7d94bAlan Viverette this.backgroundColor = mHasBackgroundColor ? backgroundColor : Color.BLACK; 366f1820064d9cfcf43e4cfd16872acca3bf5a7d94bAlan Viverette this.edgeType = mHasEdgeType ? edgeType : EDGE_TYPE_NONE; 367f1820064d9cfcf43e4cfd16872acca3bf5a7d94bAlan Viverette this.edgeColor = mHasEdgeColor ? edgeColor : Color.BLACK; 368f1820064d9cfcf43e4cfd16872acca3bf5a7d94bAlan Viverette this.windowColor = mHasWindowColor ? windowColor : COLOR_NONE_OPAQUE; 36943a1e3d319d77c251445339bcc8f82c82b097feeAlan Viverette 37043a1e3d319d77c251445339bcc8f82c82b097feeAlan Viverette mRawTypeface = rawTypeface; 37143a1e3d319d77c251445339bcc8f82c82b097feeAlan Viverette } 37243a1e3d319d77c251445339bcc8f82c82b097feeAlan Viverette 37343a1e3d319d77c251445339bcc8f82c82b097feeAlan Viverette /** 3747e4019b7413511bb60e19d6011c80baf00e40b76Alan Viverette * Returns whether a packed color indicates a non-default value. 3757e4019b7413511bb60e19d6011c80baf00e40b76Alan Viverette * 3767e4019b7413511bb60e19d6011c80baf00e40b76Alan Viverette * @param packedColor the packed color value 3777e4019b7413511bb60e19d6011c80baf00e40b76Alan Viverette * @return {@code true} if a non-default value is specified 3787e4019b7413511bb60e19d6011c80baf00e40b76Alan Viverette * @hide 3797e4019b7413511bb60e19d6011c80baf00e40b76Alan Viverette */ 3807e4019b7413511bb60e19d6011c80baf00e40b76Alan Viverette public static boolean hasColor(int packedColor) { 3817e4019b7413511bb60e19d6011c80baf00e40b76Alan Viverette // Matches the color packing code from Settings. "Default" packed 3827e4019b7413511bb60e19d6011c80baf00e40b76Alan Viverette // colors are indicated by zero alpha and non-zero red/blue. The 3837e4019b7413511bb60e19d6011c80baf00e40b76Alan Viverette // cached alpha value used by Settings is stored in green. 3847e4019b7413511bb60e19d6011c80baf00e40b76Alan Viverette return (packedColor >>> 24) != 0 || (packedColor & 0xFFFF00) == 0; 3857e4019b7413511bb60e19d6011c80baf00e40b76Alan Viverette } 3867e4019b7413511bb60e19d6011c80baf00e40b76Alan Viverette 3877e4019b7413511bb60e19d6011c80baf00e40b76Alan Viverette /** 388e88aee8ad85b01229b12dbc0c3cc2f0b8b490192Alan Viverette * Applies a caption style, overriding any properties that are specified 389e88aee8ad85b01229b12dbc0c3cc2f0b8b490192Alan Viverette * in the overlay caption. 390e88aee8ad85b01229b12dbc0c3cc2f0b8b490192Alan Viverette * 391e88aee8ad85b01229b12dbc0c3cc2f0b8b490192Alan Viverette * @param overlay The style to apply 392e88aee8ad85b01229b12dbc0c3cc2f0b8b490192Alan Viverette * @return A caption style with the overlay style applied 393e88aee8ad85b01229b12dbc0c3cc2f0b8b490192Alan Viverette * @hide 394e88aee8ad85b01229b12dbc0c3cc2f0b8b490192Alan Viverette */ 395e88aee8ad85b01229b12dbc0c3cc2f0b8b490192Alan Viverette @NonNull 396e88aee8ad85b01229b12dbc0c3cc2f0b8b490192Alan Viverette public CaptionStyle applyStyle(@NonNull CaptionStyle overlay) { 397e88aee8ad85b01229b12dbc0c3cc2f0b8b490192Alan Viverette final int newForegroundColor = overlay.hasForegroundColor() ? 398e88aee8ad85b01229b12dbc0c3cc2f0b8b490192Alan Viverette overlay.foregroundColor : foregroundColor; 399e88aee8ad85b01229b12dbc0c3cc2f0b8b490192Alan Viverette final int newBackgroundColor = overlay.hasBackgroundColor() ? 400e88aee8ad85b01229b12dbc0c3cc2f0b8b490192Alan Viverette overlay.backgroundColor : backgroundColor; 401e88aee8ad85b01229b12dbc0c3cc2f0b8b490192Alan Viverette final int newEdgeType = overlay.hasEdgeType() ? 402e88aee8ad85b01229b12dbc0c3cc2f0b8b490192Alan Viverette overlay.edgeType : edgeType; 403e88aee8ad85b01229b12dbc0c3cc2f0b8b490192Alan Viverette final int newEdgeColor = overlay.hasEdgeColor() ? 404e88aee8ad85b01229b12dbc0c3cc2f0b8b490192Alan Viverette overlay.edgeColor : edgeColor; 405e88aee8ad85b01229b12dbc0c3cc2f0b8b490192Alan Viverette final int newWindowColor = overlay.hasWindowColor() ? 406e88aee8ad85b01229b12dbc0c3cc2f0b8b490192Alan Viverette overlay.windowColor : windowColor; 407e88aee8ad85b01229b12dbc0c3cc2f0b8b490192Alan Viverette final String newRawTypeface = overlay.mRawTypeface != null ? 408e88aee8ad85b01229b12dbc0c3cc2f0b8b490192Alan Viverette overlay.mRawTypeface : mRawTypeface; 409e88aee8ad85b01229b12dbc0c3cc2f0b8b490192Alan Viverette return new CaptionStyle(newForegroundColor, newBackgroundColor, newEdgeType, 410e88aee8ad85b01229b12dbc0c3cc2f0b8b490192Alan Viverette newEdgeColor, newWindowColor, newRawTypeface); 411e88aee8ad85b01229b12dbc0c3cc2f0b8b490192Alan Viverette } 412e88aee8ad85b01229b12dbc0c3cc2f0b8b490192Alan Viverette 413e88aee8ad85b01229b12dbc0c3cc2f0b8b490192Alan Viverette /** 414e88aee8ad85b01229b12dbc0c3cc2f0b8b490192Alan Viverette * @return {@code true} if the user has specified a background color 415e88aee8ad85b01229b12dbc0c3cc2f0b8b490192Alan Viverette * that should override the application default, {@code false} 416e88aee8ad85b01229b12dbc0c3cc2f0b8b490192Alan Viverette * otherwise 417e88aee8ad85b01229b12dbc0c3cc2f0b8b490192Alan Viverette */ 418e88aee8ad85b01229b12dbc0c3cc2f0b8b490192Alan Viverette public boolean hasBackgroundColor() { 419f1820064d9cfcf43e4cfd16872acca3bf5a7d94bAlan Viverette return mHasBackgroundColor; 420e88aee8ad85b01229b12dbc0c3cc2f0b8b490192Alan Viverette } 421e88aee8ad85b01229b12dbc0c3cc2f0b8b490192Alan Viverette 422e88aee8ad85b01229b12dbc0c3cc2f0b8b490192Alan Viverette /** 423e88aee8ad85b01229b12dbc0c3cc2f0b8b490192Alan Viverette * @return {@code true} if the user has specified a foreground color 424e88aee8ad85b01229b12dbc0c3cc2f0b8b490192Alan Viverette * that should override the application default, {@code false} 425e88aee8ad85b01229b12dbc0c3cc2f0b8b490192Alan Viverette * otherwise 426e88aee8ad85b01229b12dbc0c3cc2f0b8b490192Alan Viverette */ 427e88aee8ad85b01229b12dbc0c3cc2f0b8b490192Alan Viverette public boolean hasForegroundColor() { 428f1820064d9cfcf43e4cfd16872acca3bf5a7d94bAlan Viverette return mHasForegroundColor; 429e88aee8ad85b01229b12dbc0c3cc2f0b8b490192Alan Viverette } 430e88aee8ad85b01229b12dbc0c3cc2f0b8b490192Alan Viverette 431e88aee8ad85b01229b12dbc0c3cc2f0b8b490192Alan Viverette /** 432e88aee8ad85b01229b12dbc0c3cc2f0b8b490192Alan Viverette * @return {@code true} if the user has specified an edge type that 433e88aee8ad85b01229b12dbc0c3cc2f0b8b490192Alan Viverette * should override the application default, {@code false} 434e88aee8ad85b01229b12dbc0c3cc2f0b8b490192Alan Viverette * otherwise 435e88aee8ad85b01229b12dbc0c3cc2f0b8b490192Alan Viverette */ 436e88aee8ad85b01229b12dbc0c3cc2f0b8b490192Alan Viverette public boolean hasEdgeType() { 437f1820064d9cfcf43e4cfd16872acca3bf5a7d94bAlan Viverette return mHasEdgeType; 438e88aee8ad85b01229b12dbc0c3cc2f0b8b490192Alan Viverette } 439e88aee8ad85b01229b12dbc0c3cc2f0b8b490192Alan Viverette 440e88aee8ad85b01229b12dbc0c3cc2f0b8b490192Alan Viverette /** 441e88aee8ad85b01229b12dbc0c3cc2f0b8b490192Alan Viverette * @return {@code true} if the user has specified an edge color that 442e88aee8ad85b01229b12dbc0c3cc2f0b8b490192Alan Viverette * should override the application default, {@code false} 443e88aee8ad85b01229b12dbc0c3cc2f0b8b490192Alan Viverette * otherwise 444e88aee8ad85b01229b12dbc0c3cc2f0b8b490192Alan Viverette */ 445e88aee8ad85b01229b12dbc0c3cc2f0b8b490192Alan Viverette public boolean hasEdgeColor() { 446f1820064d9cfcf43e4cfd16872acca3bf5a7d94bAlan Viverette return mHasEdgeColor; 447e88aee8ad85b01229b12dbc0c3cc2f0b8b490192Alan Viverette } 448e88aee8ad85b01229b12dbc0c3cc2f0b8b490192Alan Viverette 449e88aee8ad85b01229b12dbc0c3cc2f0b8b490192Alan Viverette /** 450e88aee8ad85b01229b12dbc0c3cc2f0b8b490192Alan Viverette * @return {@code true} if the user has specified a window color that 451e88aee8ad85b01229b12dbc0c3cc2f0b8b490192Alan Viverette * should override the application default, {@code false} 452e88aee8ad85b01229b12dbc0c3cc2f0b8b490192Alan Viverette * otherwise 453e88aee8ad85b01229b12dbc0c3cc2f0b8b490192Alan Viverette */ 454e88aee8ad85b01229b12dbc0c3cc2f0b8b490192Alan Viverette public boolean hasWindowColor() { 455f1820064d9cfcf43e4cfd16872acca3bf5a7d94bAlan Viverette return mHasWindowColor; 456e88aee8ad85b01229b12dbc0c3cc2f0b8b490192Alan Viverette } 457e88aee8ad85b01229b12dbc0c3cc2f0b8b490192Alan Viverette 458e88aee8ad85b01229b12dbc0c3cc2f0b8b490192Alan Viverette /** 45969ce69b0e1500bcf0bfa87eaf0b89ae47f552f5cAlan Viverette * @return the preferred {@link Typeface} for video captions, or null if 46069ce69b0e1500bcf0bfa87eaf0b89ae47f552f5cAlan Viverette * not specified 46143a1e3d319d77c251445339bcc8f82c82b097feeAlan Viverette */ 462e88aee8ad85b01229b12dbc0c3cc2f0b8b490192Alan Viverette @Nullable 46343a1e3d319d77c251445339bcc8f82c82b097feeAlan Viverette public Typeface getTypeface() { 46443a1e3d319d77c251445339bcc8f82c82b097feeAlan Viverette if (mParsedTypeface == null && !TextUtils.isEmpty(mRawTypeface)) { 46543a1e3d319d77c251445339bcc8f82c82b097feeAlan Viverette mParsedTypeface = Typeface.create(mRawTypeface, Typeface.NORMAL); 46643a1e3d319d77c251445339bcc8f82c82b097feeAlan Viverette } 46743a1e3d319d77c251445339bcc8f82c82b097feeAlan Viverette return mParsedTypeface; 46843a1e3d319d77c251445339bcc8f82c82b097feeAlan Viverette } 46943a1e3d319d77c251445339bcc8f82c82b097feeAlan Viverette 47043a1e3d319d77c251445339bcc8f82c82b097feeAlan Viverette /** 47143a1e3d319d77c251445339bcc8f82c82b097feeAlan Viverette * @hide 47243a1e3d319d77c251445339bcc8f82c82b097feeAlan Viverette */ 473e88aee8ad85b01229b12dbc0c3cc2f0b8b490192Alan Viverette @NonNull 47443a1e3d319d77c251445339bcc8f82c82b097feeAlan Viverette public static CaptionStyle getCustomStyle(ContentResolver cr) { 47569ce69b0e1500bcf0bfa87eaf0b89ae47f552f5cAlan Viverette final CaptionStyle defStyle = CaptionStyle.DEFAULT_CUSTOM; 47643a1e3d319d77c251445339bcc8f82c82b097feeAlan Viverette final int foregroundColor = Secure.getInt( 47769ce69b0e1500bcf0bfa87eaf0b89ae47f552f5cAlan Viverette cr, Secure.ACCESSIBILITY_CAPTIONING_FOREGROUND_COLOR, defStyle.foregroundColor); 47869ce69b0e1500bcf0bfa87eaf0b89ae47f552f5cAlan Viverette final int backgroundColor = Secure.getInt( 47969ce69b0e1500bcf0bfa87eaf0b89ae47f552f5cAlan Viverette cr, Secure.ACCESSIBILITY_CAPTIONING_BACKGROUND_COLOR, defStyle.backgroundColor); 48043a1e3d319d77c251445339bcc8f82c82b097feeAlan Viverette final int edgeType = Secure.getInt( 48169ce69b0e1500bcf0bfa87eaf0b89ae47f552f5cAlan Viverette cr, Secure.ACCESSIBILITY_CAPTIONING_EDGE_TYPE, defStyle.edgeType); 48243a1e3d319d77c251445339bcc8f82c82b097feeAlan Viverette final int edgeColor = Secure.getInt( 48369ce69b0e1500bcf0bfa87eaf0b89ae47f552f5cAlan Viverette cr, Secure.ACCESSIBILITY_CAPTIONING_EDGE_COLOR, defStyle.edgeColor); 48455d70620d9fda8afafb2fdec59757a710eec0e89Alan Viverette final int windowColor = Secure.getInt( 48555d70620d9fda8afafb2fdec59757a710eec0e89Alan Viverette cr, Secure.ACCESSIBILITY_CAPTIONING_WINDOW_COLOR, defStyle.windowColor); 48643a1e3d319d77c251445339bcc8f82c82b097feeAlan Viverette 48743a1e3d319d77c251445339bcc8f82c82b097feeAlan Viverette String rawTypeface = Secure.getString(cr, Secure.ACCESSIBILITY_CAPTIONING_TYPEFACE); 48843a1e3d319d77c251445339bcc8f82c82b097feeAlan Viverette if (rawTypeface == null) { 48969ce69b0e1500bcf0bfa87eaf0b89ae47f552f5cAlan Viverette rawTypeface = defStyle.mRawTypeface; 49043a1e3d319d77c251445339bcc8f82c82b097feeAlan Viverette } 49143a1e3d319d77c251445339bcc8f82c82b097feeAlan Viverette 49255d70620d9fda8afafb2fdec59757a710eec0e89Alan Viverette return new CaptionStyle(foregroundColor, backgroundColor, edgeType, edgeColor, 49355d70620d9fda8afafb2fdec59757a710eec0e89Alan Viverette windowColor, rawTypeface); 49443a1e3d319d77c251445339bcc8f82c82b097feeAlan Viverette } 49543a1e3d319d77c251445339bcc8f82c82b097feeAlan Viverette 49643a1e3d319d77c251445339bcc8f82c82b097feeAlan Viverette static { 49755d70620d9fda8afafb2fdec59757a710eec0e89Alan Viverette WHITE_ON_BLACK = new CaptionStyle(Color.WHITE, Color.BLACK, EDGE_TYPE_NONE, 498ce32ea7345f0157a595b1dd4306a9a65f444d7c2Alan Viverette Color.BLACK, COLOR_NONE_OPAQUE, null); 49955d70620d9fda8afafb2fdec59757a710eec0e89Alan Viverette BLACK_ON_WHITE = new CaptionStyle(Color.BLACK, Color.WHITE, EDGE_TYPE_NONE, 500ce32ea7345f0157a595b1dd4306a9a65f444d7c2Alan Viverette Color.BLACK, COLOR_NONE_OPAQUE, null); 50155d70620d9fda8afafb2fdec59757a710eec0e89Alan Viverette YELLOW_ON_BLACK = new CaptionStyle(Color.YELLOW, Color.BLACK, EDGE_TYPE_NONE, 502ce32ea7345f0157a595b1dd4306a9a65f444d7c2Alan Viverette Color.BLACK, COLOR_NONE_OPAQUE, null); 50355d70620d9fda8afafb2fdec59757a710eec0e89Alan Viverette YELLOW_ON_BLUE = new CaptionStyle(Color.YELLOW, Color.BLUE, EDGE_TYPE_NONE, 504ce32ea7345f0157a595b1dd4306a9a65f444d7c2Alan Viverette Color.BLACK, COLOR_NONE_OPAQUE, null); 505e88aee8ad85b01229b12dbc0c3cc2f0b8b490192Alan Viverette UNSPECIFIED = new CaptionStyle(COLOR_UNSPECIFIED, COLOR_UNSPECIFIED, 506e88aee8ad85b01229b12dbc0c3cc2f0b8b490192Alan Viverette EDGE_TYPE_UNSPECIFIED, COLOR_UNSPECIFIED, COLOR_UNSPECIFIED, null); 50743a1e3d319d77c251445339bcc8f82c82b097feeAlan Viverette 508e88aee8ad85b01229b12dbc0c3cc2f0b8b490192Alan Viverette // The ordering of these cannot change since we store the index 509e88aee8ad85b01229b12dbc0c3cc2f0b8b490192Alan Viverette // directly in preferences. 51043a1e3d319d77c251445339bcc8f82c82b097feeAlan Viverette PRESETS = new CaptionStyle[] { 511e88aee8ad85b01229b12dbc0c3cc2f0b8b490192Alan Viverette WHITE_ON_BLACK, BLACK_ON_WHITE, YELLOW_ON_BLACK, YELLOW_ON_BLUE, UNSPECIFIED 51243a1e3d319d77c251445339bcc8f82c82b097feeAlan Viverette }; 51343a1e3d319d77c251445339bcc8f82c82b097feeAlan Viverette 51443a1e3d319d77c251445339bcc8f82c82b097feeAlan Viverette DEFAULT_CUSTOM = WHITE_ON_BLACK; 515e88aee8ad85b01229b12dbc0c3cc2f0b8b490192Alan Viverette DEFAULT = WHITE_ON_BLACK; 51643a1e3d319d77c251445339bcc8f82c82b097feeAlan Viverette } 51743a1e3d319d77c251445339bcc8f82c82b097feeAlan Viverette } 51869ce69b0e1500bcf0bfa87eaf0b89ae47f552f5cAlan Viverette 51969ce69b0e1500bcf0bfa87eaf0b89ae47f552f5cAlan Viverette /** 52069ce69b0e1500bcf0bfa87eaf0b89ae47f552f5cAlan Viverette * Listener for changes in captioning properties, including enabled state 52169ce69b0e1500bcf0bfa87eaf0b89ae47f552f5cAlan Viverette * and user style preferences. 52269ce69b0e1500bcf0bfa87eaf0b89ae47f552f5cAlan Viverette */ 523d43daf361e993457e64eeeddab6d1a0ebc828c99Alan Viverette public static abstract class CaptioningChangeListener { 52469ce69b0e1500bcf0bfa87eaf0b89ae47f552f5cAlan Viverette /** 52569ce69b0e1500bcf0bfa87eaf0b89ae47f552f5cAlan Viverette * Called when the captioning enabled state changes. 52669ce69b0e1500bcf0bfa87eaf0b89ae47f552f5cAlan Viverette * 52769ce69b0e1500bcf0bfa87eaf0b89ae47f552f5cAlan Viverette * @param enabled the user's new preferred captioning enabled state 52869ce69b0e1500bcf0bfa87eaf0b89ae47f552f5cAlan Viverette */ 529e88aee8ad85b01229b12dbc0c3cc2f0b8b490192Alan Viverette public void onEnabledChanged(boolean enabled) {} 53069ce69b0e1500bcf0bfa87eaf0b89ae47f552f5cAlan Viverette 53169ce69b0e1500bcf0bfa87eaf0b89ae47f552f5cAlan Viverette /** 53269ce69b0e1500bcf0bfa87eaf0b89ae47f552f5cAlan Viverette * Called when the captioning user style changes. 53369ce69b0e1500bcf0bfa87eaf0b89ae47f552f5cAlan Viverette * 53469ce69b0e1500bcf0bfa87eaf0b89ae47f552f5cAlan Viverette * @param userStyle the user's new preferred style 53569ce69b0e1500bcf0bfa87eaf0b89ae47f552f5cAlan Viverette * @see CaptioningManager#getUserStyle() 53669ce69b0e1500bcf0bfa87eaf0b89ae47f552f5cAlan Viverette */ 537e88aee8ad85b01229b12dbc0c3cc2f0b8b490192Alan Viverette public void onUserStyleChanged(@NonNull CaptionStyle userStyle) {} 53869ce69b0e1500bcf0bfa87eaf0b89ae47f552f5cAlan Viverette 53969ce69b0e1500bcf0bfa87eaf0b89ae47f552f5cAlan Viverette /** 54069ce69b0e1500bcf0bfa87eaf0b89ae47f552f5cAlan Viverette * Called when the captioning locale changes. 54169ce69b0e1500bcf0bfa87eaf0b89ae47f552f5cAlan Viverette * 542e88aee8ad85b01229b12dbc0c3cc2f0b8b490192Alan Viverette * @param locale the preferred captioning locale, or {@code null} if not specified 54369ce69b0e1500bcf0bfa87eaf0b89ae47f552f5cAlan Viverette * @see CaptioningManager#getLocale() 54469ce69b0e1500bcf0bfa87eaf0b89ae47f552f5cAlan Viverette */ 545e88aee8ad85b01229b12dbc0c3cc2f0b8b490192Alan Viverette public void onLocaleChanged(@Nullable Locale locale) {} 54669ce69b0e1500bcf0bfa87eaf0b89ae47f552f5cAlan Viverette 54769ce69b0e1500bcf0bfa87eaf0b89ae47f552f5cAlan Viverette /** 54869ce69b0e1500bcf0bfa87eaf0b89ae47f552f5cAlan Viverette * Called when the captioning font scaling factor changes. 54969ce69b0e1500bcf0bfa87eaf0b89ae47f552f5cAlan Viverette * 55069ce69b0e1500bcf0bfa87eaf0b89ae47f552f5cAlan Viverette * @param fontScale the preferred font scaling factor 55169ce69b0e1500bcf0bfa87eaf0b89ae47f552f5cAlan Viverette * @see CaptioningManager#getFontScale() 55269ce69b0e1500bcf0bfa87eaf0b89ae47f552f5cAlan Viverette */ 553e88aee8ad85b01229b12dbc0c3cc2f0b8b490192Alan Viverette public void onFontScaleChanged(float fontScale) {} 55469ce69b0e1500bcf0bfa87eaf0b89ae47f552f5cAlan Viverette } 55543a1e3d319d77c251445339bcc8f82c82b097feeAlan Viverette} 556