diff options
author | Alan Viverette <alanv@google.com> | 2013-08-30 21:34:42 +0000 |
---|---|---|
committer | Android (Google) Code Review <android-gerrit@google.com> | 2013-08-30 21:34:43 +0000 |
commit | 083199efed839274619eb7a003a7d7c9229e5ffc (patch) | |
tree | af1371b84386e9761028d0fbf7dad6feec0965cf /core/java | |
parent | 6627e5b2aef2783cfa505a48195d7b8153eda25c (diff) | |
parent | 69ce69b0e1500bcf0bfa87eaf0b89ae47f552f5c (diff) | |
download | frameworks_base-083199efed839274619eb7a003a7d7c9229e5ffc.zip frameworks_base-083199efed839274619eb7a003a7d7c9229e5ffc.tar.gz frameworks_base-083199efed839274619eb7a003a7d7c9229e5ffc.tar.bz2 |
Merge "Update captioning APIs" into klp-dev
Diffstat (limited to 'core/java')
-rw-r--r-- | core/java/android/app/ContextImpl.java | 6 | ||||
-rw-r--r-- | core/java/android/content/Context.java | 11 | ||||
-rw-r--r-- | core/java/android/provider/Settings.java | 35 | ||||
-rw-r--r-- | core/java/android/view/accessibility/CaptioningManager.java | 300 |
4 files changed, 278 insertions, 74 deletions
diff --git a/core/java/android/app/ContextImpl.java b/core/java/android/app/ContextImpl.java index cdec399..f10290d 100644 --- a/core/java/android/app/ContextImpl.java +++ b/core/java/android/app/ContextImpl.java @@ -105,6 +105,7 @@ import android.view.ContextThemeWrapper; import android.view.Display; import android.view.WindowManagerImpl; import android.view.accessibility.AccessibilityManager; +import android.view.accessibility.CaptioningManager; import android.view.inputmethod.InputMethodManager; import android.view.textservice.TextServicesManager; import android.accounts.AccountManager; @@ -307,6 +308,11 @@ class ContextImpl extends Context { return AccessibilityManager.getInstance(ctx); }}); + registerService(CAPTIONING_SERVICE, new ServiceFetcher() { + public Object getService(ContextImpl ctx) { + return new CaptioningManager(ctx); + }}); + registerService(ACCOUNT_SERVICE, new ServiceFetcher() { public Object createService(ContextImpl ctx) { IBinder b = ServiceManager.getService(ACCOUNT_SERVICE); diff --git a/core/java/android/content/Context.java b/core/java/android/content/Context.java index cd1f87b..2ff9182 100644 --- a/core/java/android/content/Context.java +++ b/core/java/android/content/Context.java @@ -2011,6 +2011,17 @@ public abstract class Context { /** * Use with {@link #getSystemService} to retrieve a + * {@link android.view.accessibility.CaptioningManager} for obtaining + * captioning properties and listening for changes in captioning + * preferences. + * + * @see #getSystemService + * @see android.view.accessibility.CaptioningManager + */ + public static final String CAPTIONING_SERVICE = "captioning"; + + /** + * Use with {@link #getSystemService} to retrieve a * {@link android.app.NotificationManager} for controlling keyguard. * * @see #getSystemService diff --git a/core/java/android/provider/Settings.java b/core/java/android/provider/Settings.java index 802bedf..31817cc 100644 --- a/core/java/android/provider/Settings.java +++ b/core/java/android/provider/Settings.java @@ -690,6 +690,19 @@ public final class Settings { public static final String ACTION_NOTIFICATION_LISTENER_SETTINGS = "android.settings.NOTIFICATION_LISTENER_SETTINGS"; + /** + * Activity Action: Show settings for video captioning. + * <p> + * In some cases, a matching Activity may not exist, so ensure you safeguard + * against this. + * <p> + * Input: Nothing. + * <p> + * Output: Nothing. + */ + @SdkConstant(SdkConstantType.ACTIVITY_INTENT_ACTION) + public static final String ACTION_CAPTIONING_SETTINGS = "android.settings.CAPTIONING_SETTINGS"; + // End of Intent actions for Settings /** @@ -3588,7 +3601,7 @@ public final class Settings { * <li>{@link #ACCESSIBILITY_CAPTIONING_EDGE_COLOR} * <li>{@link #ACCESSIBILITY_CAPTIONING_EDGE_TYPE} * <li>{@link #ACCESSIBILITY_CAPTIONING_TYPEFACE} - * <li>{@link #ACCESSIBILITY_CAPTIONING_FONT_SIZE} + * <li>{@link #ACCESSIBILITY_CAPTIONING_FONT_SCALE} * </ul> * * @hide @@ -3610,9 +3623,8 @@ public final class Settings { * Integer property that specifies the preset style for captions, one * of: * <ul> - * <li>{@link android.view.accessibility.CaptioningManager#PRESET_WHITE_ON_BLACK} - * <li>{@link android.view.accessibility.CaptioningManager#PRESET_BLACK_ON_WHITE} - * <li>{@link android.view.accessibility.CaptioningManager#PRESET_CUSTOM} + * <li>{@link android.view.accessibility.CaptioningManager.CaptionStyle#PRESET_CUSTOM} + * <li>a valid index of {@link android.view.accessibility.CaptioningManager.CaptionStyle#PRESETS} * </ul> * * @see java.util.Locale#toString @@ -3644,9 +3656,9 @@ public final class Settings { /** * Integer property that specifes the edge type for captions, one of: * <ul> - * <li>{@link android.view.accessibility.CaptioningManager#EDGE_TYPE_NONE} - * <li>{@link android.view.accessibility.CaptioningManager#EDGE_TYPE_OUTLINE} - * <li>{@link android.view.accessibility.CaptioningManager#EDGE_TYPE_DROP_SHADOWED} + * <li>{@link android.view.accessibility.CaptioningManager.CaptionStyle#EDGE_TYPE_NONE} + * <li>{@link android.view.accessibility.CaptioningManager.CaptionStyle#EDGE_TYPE_OUTLINE} + * <li>{@link android.view.accessibility.CaptioningManager.CaptionStyle#EDGE_TYPE_DROP_SHADOW} * </ul> * * @see #ACCESSIBILITY_CAPTIONING_EDGE_COLOR @@ -3682,13 +3694,12 @@ public final class Settings { "accessibility_captioning_typeface"; /** - * Integer point property that specifies font size for captions in - * scaled pixels (sp). + * Floating point property that specifies font scaling for captions. * * @hide */ - public static final String ACCESSIBILITY_CAPTIONING_FONT_SIZE = - "accessibility_captioning_font_size"; + public static final String ACCESSIBILITY_CAPTIONING_FONT_SCALE = + "accessibility_captioning_font_scale"; /** * The timout for considering a press to be a long press in milliseconds. @@ -4327,7 +4338,7 @@ public final class Settings { ACCESSIBILITY_CAPTIONING_EDGE_TYPE, ACCESSIBILITY_CAPTIONING_EDGE_COLOR, ACCESSIBILITY_CAPTIONING_TYPEFACE, - ACCESSIBILITY_CAPTIONING_FONT_SIZE, + ACCESSIBILITY_CAPTIONING_FONT_SCALE, TTS_USE_DEFAULTS, TTS_DEFAULT_RATE, TTS_DEFAULT_PITCH, diff --git a/core/java/android/view/accessibility/CaptioningManager.java b/core/java/android/view/accessibility/CaptioningManager.java index b1be24c..d4c6abe 100644 --- a/core/java/android/view/accessibility/CaptioningManager.java +++ b/core/java/android/view/accessibility/CaptioningManager.java @@ -17,58 +17,77 @@ package android.view.accessibility; import android.content.ContentResolver; +import android.content.Context; +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 java.util.ArrayList; import java.util.Locale; /** - * Contains methods for accessing preferred video captioning state and + * Contains methods for accessing and monitoring preferred video captioning state and visual * properties. + * <p> + * To obtain a handle to the captioning manager, do the following: + * <p> + * <code> + * <pre>CaptioningManager captioningManager = + * (CaptioningManager) context.getSystemService(Context.CAPTIONING_SERVICE);</pre> + * </code> */ public class CaptioningManager { - /** - * Activity Action: Show settings for video captioning. - * <p> - * In some cases, a matching Activity may not exist, so ensure you safeguard - * against this. - * <p> - * Input: Nothing. - * <p> - * Output: Nothing. - */ - public static final String ACTION_CAPTIONING_SETTINGS = "android.settings.CAPTIONING_SETTINGS"; + /** Default captioning enabled value. */ + private static final int DEFAULT_ENABLED = 0; + /** Default style preset as an index into {@link CaptionStyle#PRESETS}. */ private static final int DEFAULT_PRESET = 0; - private static final int DEFAULT_ENABLED = 0; - private static final float DEFAULT_FONT_SIZE = 24; + + /** Default scaling value for caption fonts. */ + private static final float DEFAULT_FONT_SCALE = 1; + + private final ArrayList<CaptioningChangeListener> + mListeners = new ArrayList<CaptioningChangeListener>(); + private final Handler mHandler = new Handler(); + + private final ContentResolver mContentResolver; + + /** + * Creates a new captioning manager for the specified context. + * + * @hide + */ + public CaptioningManager(Context context) { + mContentResolver = context.getContentResolver(); + } /** - * @param cr Resolver to access the database with. - * @return The user's preferred caption enabled state. + * @return the user's preferred captioning enabled state */ - public static final boolean isEnabled(ContentResolver cr) { - return Secure.getInt(cr, Secure.ACCESSIBILITY_CAPTIONING_ENABLED, DEFAULT_ENABLED) == 1; + public final boolean isEnabled() { + return Secure.getInt( + mContentResolver, Secure.ACCESSIBILITY_CAPTIONING_ENABLED, DEFAULT_ENABLED) == 1; } /** - * @param cr Resolver to access the database with. - * @return The raw locale string for the user's preferred caption language. + * @return the raw locale string for the user's preferred captioning + * language * @hide */ - public static final String getRawLocale(ContentResolver cr) { - return Secure.getString(cr, Secure.ACCESSIBILITY_CAPTIONING_LOCALE); + public final String getRawLocale() { + return Secure.getString(mContentResolver, Secure.ACCESSIBILITY_CAPTIONING_LOCALE); } /** - * @param cr Resolver to access the database with. - * @return The locale for the user's preferred caption language, or null if - * not specified. + * @return the locale for the user's preferred captioning language, or null + * if not specified */ - public static final Locale getLocale(ContentResolver cr) { - final String rawLocale = getRawLocale(cr); + public final Locale getLocale() { + final String rawLocale = getRawLocale(); if (!TextUtils.isEmpty(rawLocale)) { final String[] splitLocale = rawLocale.split("_"); switch (splitLocale.length) { @@ -85,14 +104,151 @@ public class CaptioningManager { } /** - * @param cr Resolver to access the database with. - * @return The user's preferred font size for video captions, or 0 if not - * specified. + * @return the user's preferred font scaling factor for video captions, or 1 if not + * specified */ - public static final float getFontSize(ContentResolver cr) { - return Secure.getFloat(cr, Secure.ACCESSIBILITY_CAPTIONING_FONT_SIZE, DEFAULT_FONT_SIZE); + 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 + */ + public CaptionStyle getUserStyle() { + final int preset = getRawUserStyle(); + if (preset == CaptionStyle.PRESET_CUSTOM) { + return CaptionStyle.getCustomStyle(mContentResolver); + } + + return CaptionStyle.PRESETS[preset]; + } + + /** + * Adds a listener for changes in the user's preferred captioning enabled + * state and visual properties. + * + * @param listener the listener to add + */ + public void addCaptioningStateChangeListener(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_EDGE_TYPE); + registerObserver(Secure.ACCESSIBILITY_CAPTIONING_EDGE_COLOR); + registerObserver(Secure.ACCESSIBILITY_CAPTIONING_TYPEFACE); + registerObserver(Secure.ACCESSIBILITY_CAPTIONING_FONT_SCALE); + registerObserver(Secure.ACCESSIBILITY_CAPTIONING_LOCALE); + } + + mListeners.add(listener); + } + } + + private void registerObserver(String key) { + mContentResolver.registerContentObserver(Secure.getUriFor(key), false, mContentObserver); + } + + /** + * Removes a listener previously added using + * {@link #addCaptioningStateChangeListener}. + * + * @param listener the listener to remove + */ + public void removeCaptioningStateChangeListener(CaptioningChangeListener listener) { + synchronized (mListeners) { + mListeners.remove(listener); + + if (mListeners.isEmpty()) { + mContentResolver.unregisterContentObserver(mContentObserver); + } + } + } + + 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 final ContentObserver mContentObserver = new ContentObserver(mHandler) { + @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 { + // 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 { private static final CaptionStyle WHITE_ON_BLACK; private static final CaptionStyle BLACK_ON_WHITE; @@ -155,8 +311,8 @@ public class CaptioningManager { } /** - * @return The preferred {@link Typeface} for video captions, or null if - * not specified. + * @return the preferred {@link Typeface} for video captions, or null if + * not specified */ public Typeface getTypeface() { if (mParsedTypeface == null && !TextUtils.isEmpty(mRawTypeface)) { @@ -168,41 +324,20 @@ public class CaptioningManager { /** * @hide */ - public static int getRawPreset(ContentResolver cr) { - return Secure.getInt(cr, Secure.ACCESSIBILITY_CAPTIONING_PRESET, DEFAULT_PRESET); - } - - /** - * @param cr Resolver to access the database with. - * @return The user's preferred caption style. - */ - public static CaptionStyle defaultUserStyle(ContentResolver cr) { - final int preset = getRawPreset(cr); - if (preset == PRESET_CUSTOM) { - return getCustomStyle(cr); - } - - return PRESETS[preset]; - } - - /** - * @hide - */ public static CaptionStyle getCustomStyle(ContentResolver cr) { + final CaptionStyle defStyle = CaptionStyle.DEFAULT_CUSTOM; final int foregroundColor = Secure.getInt( - cr, Secure.ACCESSIBILITY_CAPTIONING_FOREGROUND_COLOR, - DEFAULT_CUSTOM.foregroundColor); - final int backgroundColor = Secure.getInt(cr, - Secure.ACCESSIBILITY_CAPTIONING_BACKGROUND_COLOR, - DEFAULT_CUSTOM.backgroundColor); + 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, DEFAULT_CUSTOM.edgeType); + cr, Secure.ACCESSIBILITY_CAPTIONING_EDGE_TYPE, defStyle.edgeType); final int edgeColor = Secure.getInt( - cr, Secure.ACCESSIBILITY_CAPTIONING_EDGE_COLOR, DEFAULT_CUSTOM.edgeColor); + cr, Secure.ACCESSIBILITY_CAPTIONING_EDGE_COLOR, defStyle.edgeColor); String rawTypeface = Secure.getString(cr, Secure.ACCESSIBILITY_CAPTIONING_TYPEFACE); if (rawTypeface == null) { - rawTypeface = DEFAULT_CUSTOM.mRawTypeface; + rawTypeface = defStyle.mRawTypeface; } return new CaptionStyle( @@ -226,4 +361,45 @@ public class CaptioningManager { DEFAULT_CUSTOM = WHITE_ON_BLACK; } } + + /** + * Listener for changes in captioning properties, including enabled state + * and user style preferences. + */ + public 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(CaptionStyle userStyle) { + } + + /** + * Called when the captioning locale changes. + * + * @param locale the preferred captioning locale + * @see CaptioningManager#getLocale() + */ + public void onLocaleChanged(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) { + } + } } |