708 lines
26 KiB
Java
708 lines
26 KiB
Java
/*
|
|
* Copyright (C) 2013 The Android Open Source Project
|
|
*
|
|
* Licensed under the Apache License, Version 2.0 (the "License");
|
|
* you may not use this file except in compliance with the License.
|
|
* You may obtain a copy of the License at
|
|
*
|
|
* http://www.apache.org/licenses/LICENSE-2.0
|
|
*
|
|
* Unless required by applicable law or agreed to in writing, software
|
|
* distributed under the License is distributed on an "AS IS" BASIS,
|
|
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
* See the License for the specific language governing permissions and
|
|
* limitations under the License.
|
|
*/
|
|
|
|
package android.view.accessibility;
|
|
|
|
import android.Manifest;
|
|
import android.annotation.NonNull;
|
|
import android.annotation.Nullable;
|
|
import android.annotation.RequiresPermission;
|
|
import android.annotation.SystemApi;
|
|
import android.annotation.SystemService;
|
|
import android.compat.annotation.UnsupportedAppUsage;
|
|
import android.content.ContentResolver;
|
|
import android.content.Context;
|
|
import android.content.res.Resources;
|
|
import android.database.ContentObserver;
|
|
import android.graphics.Color;
|
|
import android.graphics.Typeface;
|
|
import android.net.Uri;
|
|
import android.os.Handler;
|
|
import android.provider.Settings.Secure;
|
|
import android.text.TextUtils;
|
|
|
|
import com.android.internal.R;
|
|
|
|
import java.util.ArrayList;
|
|
import java.util.Locale;
|
|
|
|
/**
|
|
* Contains methods for accessing and monitoring preferred video captioning state and visual
|
|
* properties.
|
|
*/
|
|
@SystemService(Context.CAPTIONING_SERVICE)
|
|
public class CaptioningManager {
|
|
/** Default captioning enabled value. */
|
|
private static final int DEFAULT_ENABLED = 0;
|
|
private static final boolean SYSTEM_AUDIO_CAPTIONING_DEFAULT_ENABLED = false;
|
|
|
|
/** Default style preset as an index into {@link CaptionStyle#PRESETS}. */
|
|
private static final int DEFAULT_PRESET = 0;
|
|
|
|
/** Default scaling value for caption fonts. */
|
|
private static final float DEFAULT_FONT_SCALE = 1;
|
|
|
|
private final ArrayList<CaptioningChangeListener> mListeners = new ArrayList<>();
|
|
private final ContentResolver mContentResolver;
|
|
private final ContentObserver mContentObserver;
|
|
private final Resources mResources;
|
|
private final Context mContext;
|
|
private final AccessibilityManager mAccessibilityManager;
|
|
|
|
/**
|
|
* Creates a new captioning manager for the specified context.
|
|
*
|
|
* @hide
|
|
*/
|
|
public CaptioningManager(Context context) {
|
|
mContext = context;
|
|
mContentResolver = context.getContentResolver();
|
|
mAccessibilityManager = mContext.getSystemService(AccessibilityManager.class);
|
|
|
|
final Handler handler = new Handler(context.getMainLooper());
|
|
mContentObserver = new MyContentObserver(handler);
|
|
mResources = context.getResources();
|
|
}
|
|
|
|
/**
|
|
* @return the user's preferred captioning enabled state
|
|
*/
|
|
public final boolean isEnabled() {
|
|
return Secure.getInt(
|
|
mContentResolver, Secure.ACCESSIBILITY_CAPTIONING_ENABLED, DEFAULT_ENABLED) == 1;
|
|
}
|
|
|
|
/**
|
|
* @return the raw locale string for the user's preferred captioning
|
|
* language
|
|
* @hide
|
|
*/
|
|
@Nullable
|
|
public final String getRawLocale() {
|
|
return Secure.getString(mContentResolver, Secure.ACCESSIBILITY_CAPTIONING_LOCALE);
|
|
}
|
|
|
|
/**
|
|
* @return the locale for the user's preferred captioning language, or null
|
|
* if not specified
|
|
*/
|
|
@Nullable
|
|
public final Locale getLocale() {
|
|
final String rawLocale = getRawLocale();
|
|
if (!TextUtils.isEmpty(rawLocale)) {
|
|
final String[] splitLocale = rawLocale.split("_");
|
|
switch (splitLocale.length) {
|
|
case 3:
|
|
return new Locale(splitLocale[0], splitLocale[1], splitLocale[2]);
|
|
case 2:
|
|
return new Locale(splitLocale[0], splitLocale[1]);
|
|
case 1:
|
|
return new Locale(splitLocale[0]);
|
|
}
|
|
}
|
|
|
|
return null;
|
|
}
|
|
|
|
/**
|
|
* @return the user's preferred font scaling factor for video captions, or 1 if not
|
|
* specified
|
|
*/
|
|
public final float getFontScale() {
|
|
return Secure.getFloat(
|
|
mContentResolver, Secure.ACCESSIBILITY_CAPTIONING_FONT_SCALE, DEFAULT_FONT_SCALE);
|
|
}
|
|
|
|
/**
|
|
* @return the raw preset number, or the first preset if not specified
|
|
* @hide
|
|
*/
|
|
public int getRawUserStyle() {
|
|
return Secure.getInt(
|
|
mContentResolver, Secure.ACCESSIBILITY_CAPTIONING_PRESET, DEFAULT_PRESET);
|
|
}
|
|
|
|
/**
|
|
* @return the user's preferred visual properties for captions as a
|
|
* {@link CaptionStyle}, or the default style if not specified
|
|
*/
|
|
@NonNull
|
|
public CaptionStyle getUserStyle() {
|
|
final int preset = getRawUserStyle();
|
|
if (preset == CaptionStyle.PRESET_CUSTOM) {
|
|
return CaptionStyle.getCustomStyle(mContentResolver);
|
|
}
|
|
|
|
return CaptionStyle.PRESETS[preset];
|
|
}
|
|
|
|
/**
|
|
* @return the system audio caption enabled state.
|
|
*/
|
|
public final boolean isSystemAudioCaptioningEnabled() {
|
|
return Secure.getIntForUser(mContentResolver, Secure.ODI_CAPTIONS_ENABLED,
|
|
SYSTEM_AUDIO_CAPTIONING_DEFAULT_ENABLED ? 1 : 0, mContext.getUserId()) == 1;
|
|
}
|
|
|
|
/**
|
|
* Sets the system audio caption enabled state.
|
|
*
|
|
* @param isEnabled The system audio captioning enabled state.
|
|
*
|
|
* @throws SecurityException if the caller does not have permission
|
|
* {@link Manifest.permission#SET_SYSTEM_AUDIO_CAPTION}
|
|
*
|
|
* @hide
|
|
*/
|
|
@SystemApi
|
|
@RequiresPermission(Manifest.permission.SET_SYSTEM_AUDIO_CAPTION)
|
|
public final void setSystemAudioCaptioningEnabled(boolean isEnabled) {
|
|
if (mAccessibilityManager != null) {
|
|
mAccessibilityManager.setSystemAudioCaptioningEnabled(isEnabled,
|
|
mContext.getUserId());
|
|
}
|
|
}
|
|
|
|
/**
|
|
* @return the system audio caption UI enabled state.
|
|
*/
|
|
public final boolean isSystemAudioCaptioningUiEnabled() {
|
|
return mAccessibilityManager != null
|
|
&& mAccessibilityManager.isSystemAudioCaptioningUiEnabled(mContext.getUserId());
|
|
}
|
|
|
|
/**
|
|
* Sets the system audio caption UI enabled state.
|
|
*
|
|
* @param isEnabled The system audio captioning UI enabled state.
|
|
*
|
|
* @throws SecurityException if the caller does not have permission
|
|
* {@link Manifest.permission#SET_SYSTEM_AUDIO_CAPTION}
|
|
*
|
|
* @hide
|
|
*/
|
|
@SystemApi
|
|
@RequiresPermission(Manifest.permission.SET_SYSTEM_AUDIO_CAPTION)
|
|
public final void setSystemAudioCaptioningUiEnabled(boolean isEnabled) {
|
|
if (mAccessibilityManager != null) {
|
|
mAccessibilityManager.setSystemAudioCaptioningUiEnabled(isEnabled,
|
|
mContext.getUserId());
|
|
}
|
|
}
|
|
|
|
/**
|
|
* Adds a listener for changes in the user's preferred captioning enabled
|
|
* state and visual properties.
|
|
*
|
|
* @param listener the listener to add
|
|
*/
|
|
public void addCaptioningChangeListener(@NonNull CaptioningChangeListener listener) {
|
|
synchronized (mListeners) {
|
|
if (mListeners.isEmpty()) {
|
|
registerObserver(Secure.ACCESSIBILITY_CAPTIONING_ENABLED);
|
|
registerObserver(Secure.ACCESSIBILITY_CAPTIONING_FOREGROUND_COLOR);
|
|
registerObserver(Secure.ACCESSIBILITY_CAPTIONING_BACKGROUND_COLOR);
|
|
registerObserver(Secure.ACCESSIBILITY_CAPTIONING_WINDOW_COLOR);
|
|
registerObserver(Secure.ACCESSIBILITY_CAPTIONING_EDGE_TYPE);
|
|
registerObserver(Secure.ACCESSIBILITY_CAPTIONING_EDGE_COLOR);
|
|
registerObserver(Secure.ACCESSIBILITY_CAPTIONING_TYPEFACE);
|
|
registerObserver(Secure.ACCESSIBILITY_CAPTIONING_FONT_SCALE);
|
|
registerObserver(Secure.ACCESSIBILITY_CAPTIONING_LOCALE);
|
|
registerObserver(Secure.ACCESSIBILITY_CAPTIONING_PRESET);
|
|
registerObserver(Secure.ODI_CAPTIONS_ENABLED);
|
|
registerObserver(Secure.ODI_CAPTIONS_VOLUME_UI_ENABLED);
|
|
}
|
|
|
|
mListeners.add(listener);
|
|
}
|
|
}
|
|
|
|
private void registerObserver(String key) {
|
|
mContentResolver.registerContentObserver(Secure.getUriFor(key), false, mContentObserver);
|
|
}
|
|
|
|
/**
|
|
* Removes a listener previously added using
|
|
* {@link #addCaptioningChangeListener}.
|
|
*
|
|
* @param listener the listener to remove
|
|
*/
|
|
public void removeCaptioningChangeListener(@NonNull CaptioningChangeListener listener) {
|
|
synchronized (mListeners) {
|
|
mListeners.remove(listener);
|
|
|
|
if (mListeners.isEmpty()) {
|
|
mContentResolver.unregisterContentObserver(mContentObserver);
|
|
}
|
|
}
|
|
}
|
|
|
|
/**
|
|
* Returns true if system wide call captioning is enabled for this device.
|
|
*/
|
|
public boolean isCallCaptioningEnabled() {
|
|
try {
|
|
return mResources.getBoolean(
|
|
R.bool.config_systemCaptionsServiceCallsEnabled);
|
|
} catch (Resources.NotFoundException e) {
|
|
// The resource may not be defined, return false in that case
|
|
return false;
|
|
}
|
|
}
|
|
|
|
private void notifyEnabledChanged() {
|
|
final boolean enabled = isEnabled();
|
|
synchronized (mListeners) {
|
|
for (CaptioningChangeListener listener : mListeners) {
|
|
listener.onEnabledChanged(enabled);
|
|
}
|
|
}
|
|
}
|
|
|
|
private void notifyUserStyleChanged() {
|
|
final CaptionStyle userStyle = getUserStyle();
|
|
synchronized (mListeners) {
|
|
for (CaptioningChangeListener listener : mListeners) {
|
|
listener.onUserStyleChanged(userStyle);
|
|
}
|
|
}
|
|
}
|
|
|
|
private void notifyLocaleChanged() {
|
|
final Locale locale = getLocale();
|
|
synchronized (mListeners) {
|
|
for (CaptioningChangeListener listener : mListeners) {
|
|
listener.onLocaleChanged(locale);
|
|
}
|
|
}
|
|
}
|
|
|
|
private void notifyFontScaleChanged() {
|
|
final float fontScale = getFontScale();
|
|
synchronized (mListeners) {
|
|
for (CaptioningChangeListener listener : mListeners) {
|
|
listener.onFontScaleChanged(fontScale);
|
|
}
|
|
}
|
|
}
|
|
|
|
private void notifySystemAudioCaptionChanged() {
|
|
final boolean enabled = isSystemAudioCaptioningEnabled();
|
|
synchronized (mListeners) {
|
|
for (CaptioningChangeListener listener : mListeners) {
|
|
listener.onSystemAudioCaptioningChanged(enabled);
|
|
}
|
|
}
|
|
}
|
|
|
|
private void notifySystemAudioCaptionUiChanged() {
|
|
final boolean enabled = isSystemAudioCaptioningUiEnabled();
|
|
synchronized (mListeners) {
|
|
for (CaptioningChangeListener listener : mListeners) {
|
|
listener.onSystemAudioCaptioningUiChanged(enabled);
|
|
}
|
|
}
|
|
}
|
|
|
|
private class MyContentObserver extends ContentObserver {
|
|
private final Handler mHandler;
|
|
|
|
public MyContentObserver(Handler handler) {
|
|
super(handler);
|
|
|
|
mHandler = handler;
|
|
}
|
|
|
|
@Override
|
|
public void onChange(boolean selfChange, Uri uri) {
|
|
final String uriPath = uri.getPath();
|
|
final String name = uriPath.substring(uriPath.lastIndexOf('/') + 1);
|
|
if (Secure.ACCESSIBILITY_CAPTIONING_ENABLED.equals(name)) {
|
|
notifyEnabledChanged();
|
|
} else if (Secure.ACCESSIBILITY_CAPTIONING_LOCALE.equals(name)) {
|
|
notifyLocaleChanged();
|
|
} else if (Secure.ACCESSIBILITY_CAPTIONING_FONT_SCALE.equals(name)) {
|
|
notifyFontScaleChanged();
|
|
} else if (Secure.ODI_CAPTIONS_ENABLED.equals(name)) {
|
|
notifySystemAudioCaptionChanged();
|
|
} else if (Secure.ODI_CAPTIONS_VOLUME_UI_ENABLED.equals(name)) {
|
|
notifySystemAudioCaptionUiChanged();
|
|
} else {
|
|
// We only need a single callback when multiple style properties
|
|
// change in rapid succession.
|
|
mHandler.removeCallbacks(mStyleChangedRunnable);
|
|
mHandler.post(mStyleChangedRunnable);
|
|
}
|
|
}
|
|
};
|
|
|
|
/**
|
|
* Runnable posted when user style properties change. This is used to
|
|
* prevent unnecessary change notifications when multiple properties change
|
|
* in rapid succession.
|
|
*/
|
|
private final Runnable mStyleChangedRunnable = new Runnable() {
|
|
@Override
|
|
public void run() {
|
|
notifyUserStyleChanged();
|
|
}
|
|
};
|
|
|
|
/**
|
|
* Specifies visual properties for video captions, including foreground and
|
|
* background colors, edge properties, and typeface.
|
|
*/
|
|
public static final class CaptionStyle {
|
|
/**
|
|
* Packed value for a color of 'none' and a cached opacity of 100%.
|
|
*
|
|
* @hide
|
|
*/
|
|
private static final int COLOR_NONE_OPAQUE = 0x000000FF;
|
|
|
|
/**
|
|
* Packed value for a color of 'default' and opacity of 100%.
|
|
*
|
|
* @hide
|
|
*/
|
|
public static final int COLOR_UNSPECIFIED = 0x00FFFFFF;
|
|
|
|
private static final CaptionStyle WHITE_ON_BLACK;
|
|
private static final CaptionStyle BLACK_ON_WHITE;
|
|
private static final CaptionStyle YELLOW_ON_BLACK;
|
|
private static final CaptionStyle YELLOW_ON_BLUE;
|
|
private static final CaptionStyle DEFAULT_CUSTOM;
|
|
private static final CaptionStyle UNSPECIFIED;
|
|
|
|
/** The default caption style used to fill in unspecified values. @hide */
|
|
public static final CaptionStyle DEFAULT;
|
|
|
|
/** @hide */
|
|
@UnsupportedAppUsage
|
|
public static final CaptionStyle[] PRESETS;
|
|
|
|
/** @hide */
|
|
public static final int PRESET_CUSTOM = -1;
|
|
|
|
/** Unspecified edge type value. */
|
|
public static final int EDGE_TYPE_UNSPECIFIED = -1;
|
|
|
|
/** Edge type value specifying no character edges. */
|
|
public static final int EDGE_TYPE_NONE = 0;
|
|
|
|
/** Edge type value specifying uniformly outlined character edges. */
|
|
public static final int EDGE_TYPE_OUTLINE = 1;
|
|
|
|
/** Edge type value specifying drop-shadowed character edges. */
|
|
public static final int EDGE_TYPE_DROP_SHADOW = 2;
|
|
|
|
/** Edge type value specifying raised bevel character edges. */
|
|
public static final int EDGE_TYPE_RAISED = 3;
|
|
|
|
/** Edge type value specifying depressed bevel character edges. */
|
|
public static final int EDGE_TYPE_DEPRESSED = 4;
|
|
|
|
/** The preferred foreground color for video captions. */
|
|
public final int foregroundColor;
|
|
|
|
/** The preferred background color for video captions. */
|
|
public final int backgroundColor;
|
|
|
|
/**
|
|
* The preferred edge type for video captions, one of:
|
|
* <ul>
|
|
* <li>{@link #EDGE_TYPE_UNSPECIFIED}
|
|
* <li>{@link #EDGE_TYPE_NONE}
|
|
* <li>{@link #EDGE_TYPE_OUTLINE}
|
|
* <li>{@link #EDGE_TYPE_DROP_SHADOW}
|
|
* <li>{@link #EDGE_TYPE_RAISED}
|
|
* <li>{@link #EDGE_TYPE_DEPRESSED}
|
|
* </ul>
|
|
*/
|
|
public final int edgeType;
|
|
|
|
/**
|
|
* The preferred edge color for video captions, if using an edge type
|
|
* other than {@link #EDGE_TYPE_NONE}.
|
|
*/
|
|
public final int edgeColor;
|
|
|
|
/** The preferred window color for video captions. */
|
|
public final int windowColor;
|
|
|
|
/**
|
|
* @hide
|
|
*/
|
|
public final String mRawTypeface;
|
|
|
|
private final boolean mHasForegroundColor;
|
|
private final boolean mHasBackgroundColor;
|
|
private final boolean mHasEdgeType;
|
|
private final boolean mHasEdgeColor;
|
|
private final boolean mHasWindowColor;
|
|
|
|
/** Lazily-created typeface based on the raw typeface string. */
|
|
private Typeface mParsedTypeface;
|
|
|
|
private CaptionStyle(int foregroundColor, int backgroundColor, int edgeType, int edgeColor,
|
|
int windowColor, String rawTypeface) {
|
|
mHasForegroundColor = hasColor(foregroundColor);
|
|
mHasBackgroundColor = hasColor(backgroundColor);
|
|
mHasEdgeType = edgeType != EDGE_TYPE_UNSPECIFIED;
|
|
mHasEdgeColor = hasColor(edgeColor);
|
|
mHasWindowColor = hasColor(windowColor);
|
|
|
|
// Always use valid colors, even when no override is specified, to
|
|
// ensure backwards compatibility with apps targeting KitKat MR2.
|
|
this.foregroundColor = mHasForegroundColor ? foregroundColor : Color.WHITE;
|
|
this.backgroundColor = mHasBackgroundColor ? backgroundColor : Color.BLACK;
|
|
this.edgeType = mHasEdgeType ? edgeType : EDGE_TYPE_NONE;
|
|
this.edgeColor = mHasEdgeColor ? edgeColor : Color.BLACK;
|
|
this.windowColor = mHasWindowColor ? windowColor : COLOR_NONE_OPAQUE;
|
|
|
|
mRawTypeface = rawTypeface;
|
|
}
|
|
|
|
/**
|
|
* Returns whether a packed color indicates a non-default value.
|
|
*
|
|
* @param packedColor the packed color value
|
|
* @return {@code true} if a non-default value is specified
|
|
* @hide
|
|
*/
|
|
public static boolean hasColor(int packedColor) {
|
|
// Matches the color packing code from Settings. "Default" packed
|
|
// colors are indicated by zero alpha and non-zero red/blue. The
|
|
// cached alpha value used by Settings is stored in green.
|
|
return (packedColor >>> 24) != 0 || (packedColor & 0xFFFF00) == 0;
|
|
}
|
|
|
|
/**
|
|
* Applies a caption style, overriding any properties that are specified
|
|
* in the overlay caption.
|
|
*
|
|
* @param overlay The style to apply
|
|
* @return A caption style with the overlay style applied
|
|
* @hide
|
|
*/
|
|
@NonNull
|
|
public CaptionStyle applyStyle(@NonNull CaptionStyle overlay) {
|
|
final int newForegroundColor = overlay.hasForegroundColor() ?
|
|
overlay.foregroundColor : foregroundColor;
|
|
final int newBackgroundColor = overlay.hasBackgroundColor() ?
|
|
overlay.backgroundColor : backgroundColor;
|
|
final int newEdgeType = overlay.hasEdgeType() ?
|
|
overlay.edgeType : edgeType;
|
|
final int newEdgeColor = overlay.hasEdgeColor() ?
|
|
overlay.edgeColor : edgeColor;
|
|
final int newWindowColor = overlay.hasWindowColor() ?
|
|
overlay.windowColor : windowColor;
|
|
final String newRawTypeface = overlay.mRawTypeface != null ?
|
|
overlay.mRawTypeface : mRawTypeface;
|
|
return new CaptionStyle(newForegroundColor, newBackgroundColor, newEdgeType,
|
|
newEdgeColor, newWindowColor, newRawTypeface);
|
|
}
|
|
|
|
/**
|
|
* @return {@code true} if the user has specified a background color
|
|
* that should override the application default, {@code false}
|
|
* otherwise
|
|
*/
|
|
public boolean hasBackgroundColor() {
|
|
return mHasBackgroundColor;
|
|
}
|
|
|
|
/**
|
|
* @return {@code true} if the user has specified a foreground color
|
|
* that should override the application default, {@code false}
|
|
* otherwise
|
|
*/
|
|
public boolean hasForegroundColor() {
|
|
return mHasForegroundColor;
|
|
}
|
|
|
|
/**
|
|
* @return {@code true} if the user has specified an edge type that
|
|
* should override the application default, {@code false}
|
|
* otherwise
|
|
*/
|
|
public boolean hasEdgeType() {
|
|
return mHasEdgeType;
|
|
}
|
|
|
|
/**
|
|
* @return {@code true} if the user has specified an edge color that
|
|
* should override the application default, {@code false}
|
|
* otherwise
|
|
*/
|
|
public boolean hasEdgeColor() {
|
|
return mHasEdgeColor;
|
|
}
|
|
|
|
/**
|
|
* @return {@code true} if the user has specified a window color that
|
|
* should override the application default, {@code false}
|
|
* otherwise
|
|
*/
|
|
public boolean hasWindowColor() {
|
|
return mHasWindowColor;
|
|
}
|
|
|
|
/**
|
|
* @return the preferred {@link Typeface} for video captions, or null if
|
|
* not specified
|
|
*/
|
|
@Nullable
|
|
public Typeface getTypeface() {
|
|
if (mParsedTypeface == null && !TextUtils.isEmpty(mRawTypeface)) {
|
|
mParsedTypeface = Typeface.create(mRawTypeface, Typeface.NORMAL);
|
|
}
|
|
return mParsedTypeface;
|
|
}
|
|
|
|
/**
|
|
* @hide
|
|
*/
|
|
@NonNull
|
|
public static CaptionStyle getCustomStyle(ContentResolver cr) {
|
|
final CaptionStyle defStyle = CaptionStyle.DEFAULT_CUSTOM;
|
|
final int foregroundColor = Secure.getInt(
|
|
cr, Secure.ACCESSIBILITY_CAPTIONING_FOREGROUND_COLOR, defStyle.foregroundColor);
|
|
final int backgroundColor = Secure.getInt(
|
|
cr, Secure.ACCESSIBILITY_CAPTIONING_BACKGROUND_COLOR, defStyle.backgroundColor);
|
|
final int edgeType = Secure.getInt(
|
|
cr, Secure.ACCESSIBILITY_CAPTIONING_EDGE_TYPE, defStyle.edgeType);
|
|
final int edgeColor = Secure.getInt(
|
|
cr, Secure.ACCESSIBILITY_CAPTIONING_EDGE_COLOR, defStyle.edgeColor);
|
|
final int windowColor = Secure.getInt(
|
|
cr, Secure.ACCESSIBILITY_CAPTIONING_WINDOW_COLOR, defStyle.windowColor);
|
|
|
|
String rawTypeface = Secure.getString(cr, Secure.ACCESSIBILITY_CAPTIONING_TYPEFACE);
|
|
if (rawTypeface == null) {
|
|
rawTypeface = defStyle.mRawTypeface;
|
|
}
|
|
|
|
return new CaptionStyle(foregroundColor, backgroundColor, edgeType, edgeColor,
|
|
windowColor, rawTypeface);
|
|
}
|
|
|
|
static {
|
|
WHITE_ON_BLACK = new CaptionStyle(Color.WHITE, Color.BLACK, EDGE_TYPE_NONE,
|
|
Color.BLACK, COLOR_NONE_OPAQUE, null);
|
|
BLACK_ON_WHITE = new CaptionStyle(Color.BLACK, Color.WHITE, EDGE_TYPE_NONE,
|
|
Color.BLACK, COLOR_NONE_OPAQUE, null);
|
|
YELLOW_ON_BLACK = new CaptionStyle(Color.YELLOW, Color.BLACK, EDGE_TYPE_NONE,
|
|
Color.BLACK, COLOR_NONE_OPAQUE, null);
|
|
YELLOW_ON_BLUE = new CaptionStyle(Color.YELLOW, Color.BLUE, EDGE_TYPE_NONE,
|
|
Color.BLACK, COLOR_NONE_OPAQUE, null);
|
|
UNSPECIFIED = new CaptionStyle(COLOR_UNSPECIFIED, COLOR_UNSPECIFIED,
|
|
EDGE_TYPE_UNSPECIFIED, COLOR_UNSPECIFIED, COLOR_UNSPECIFIED, null);
|
|
|
|
// The ordering of these cannot change since we store the index
|
|
// directly in preferences.
|
|
PRESETS = new CaptionStyle[] {
|
|
WHITE_ON_BLACK, BLACK_ON_WHITE, YELLOW_ON_BLACK, YELLOW_ON_BLUE, UNSPECIFIED
|
|
};
|
|
|
|
DEFAULT_CUSTOM = WHITE_ON_BLACK;
|
|
DEFAULT = WHITE_ON_BLACK;
|
|
}
|
|
}
|
|
|
|
/**
|
|
* Listener for changes in captioning properties, including enabled state
|
|
* and user style preferences.
|
|
*/
|
|
public static abstract class CaptioningChangeListener {
|
|
/**
|
|
* Called when the captioning enabled state changes.
|
|
*
|
|
* @param enabled the user's new preferred captioning enabled state
|
|
*/
|
|
public void onEnabledChanged(boolean enabled) {}
|
|
|
|
/**
|
|
* Called when the captioning user style changes.
|
|
*
|
|
* @param userStyle the user's new preferred style
|
|
* @see CaptioningManager#getUserStyle()
|
|
*/
|
|
public void onUserStyleChanged(@NonNull CaptionStyle userStyle) {}
|
|
|
|
/**
|
|
* Called when the captioning locale changes.
|
|
*
|
|
* @param locale the preferred captioning locale, or {@code null} if not specified
|
|
* @see CaptioningManager#getLocale()
|
|
*/
|
|
public void onLocaleChanged(@Nullable Locale locale) {}
|
|
|
|
/**
|
|
* Called when the captioning font scaling factor changes.
|
|
*
|
|
* @param fontScale the preferred font scaling factor
|
|
* @see CaptioningManager#getFontScale()
|
|
*/
|
|
public void onFontScaleChanged(float fontScale) {}
|
|
|
|
|
|
/**
|
|
* Called when the system audio caption enabled state changes.
|
|
*
|
|
* @param enabled the system audio caption enabled state
|
|
*/
|
|
public void onSystemAudioCaptioningChanged(boolean enabled) {}
|
|
|
|
/**
|
|
* Called when the system audio caption UI enabled state changes.
|
|
*
|
|
* @param enabled the system audio caption UI enabled state
|
|
*/
|
|
public void onSystemAudioCaptioningUiChanged(boolean enabled) {}
|
|
}
|
|
|
|
/**
|
|
* Interface for accessing the system audio captioning related secure setting keys.
|
|
*
|
|
* @hide
|
|
*/
|
|
public interface SystemAudioCaptioningAccessing {
|
|
/**
|
|
* Sets the system audio caption enabled state.
|
|
*
|
|
* @param isEnabled The system audio captioning enabled state.
|
|
* @param userId The user Id.
|
|
*/
|
|
void setSystemAudioCaptioningEnabled(boolean isEnabled, int userId);
|
|
|
|
/**
|
|
* Gets the system audio caption UI enabled state.
|
|
*
|
|
* @param userId The user Id.
|
|
* @return the system audio caption UI enabled state.
|
|
*/
|
|
boolean isSystemAudioCaptioningUiEnabled(int userId);
|
|
|
|
/**
|
|
* Sets the system audio caption UI enabled state.
|
|
*
|
|
* @param isEnabled The system audio captioning UI enabled state.
|
|
* @param userId The user Id.
|
|
*/
|
|
void setSystemAudioCaptioningUiEnabled(boolean isEnabled, int userId);
|
|
}
|
|
}
|