Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 3e09c1a3 authored by Alan Viverette's avatar Alan Viverette Committed by Android Git Automerger
Browse files

am 083199ef: Merge "Update captioning APIs" into klp-dev

* commit '083199ef':
  Update captioning APIs
parents 3a9c7161 083199ef
Loading
Loading
Loading
Loading
+16 −6
Original line number Diff line number Diff line
@@ -5957,6 +5957,7 @@ package android.content {
    field public static final int BIND_WAIVE_PRIORITY = 32; // 0x20
    field public static final java.lang.String BLUETOOTH_SERVICE = "bluetooth";
    field public static final java.lang.String CAMERA_SERVICE = "camera";
    field public static final java.lang.String CAPTIONING_SERVICE = "captioning";
    field public static final java.lang.String CLIPBOARD_SERVICE = "clipboard";
    field public static final java.lang.String CONNECTIVITY_SERVICE = "connectivity";
    field public static final int CONTEXT_IGNORE_SECURITY = 2; // 0x2
@@ -21253,6 +21254,7 @@ package android.provider {
    field public static final java.lang.String ACTION_APPLICATION_DEVELOPMENT_SETTINGS = "android.settings.APPLICATION_DEVELOPMENT_SETTINGS";
    field public static final java.lang.String ACTION_APPLICATION_SETTINGS = "android.settings.APPLICATION_SETTINGS";
    field public static final java.lang.String ACTION_BLUETOOTH_SETTINGS = "android.settings.BLUETOOTH_SETTINGS";
    field public static final java.lang.String ACTION_CAPTIONING_SETTINGS = "android.settings.CAPTIONING_SETTINGS";
    field public static final java.lang.String ACTION_DATA_ROAMING_SETTINGS = "android.settings.DATA_ROAMING_SETTINGS";
    field public static final java.lang.String ACTION_DATE_SETTINGS = "android.settings.DATE_SETTINGS";
    field public static final java.lang.String ACTION_DEVICE_INFO_SETTINGS = "android.settings.DEVICE_INFO_SETTINGS";
@@ -28963,15 +28965,15 @@ package android.view.accessibility {
  }
  public class CaptioningManager {
    ctor public CaptioningManager();
    method public static final float getFontSize(android.content.ContentResolver);
    method public static final java.util.Locale getLocale(android.content.ContentResolver);
    method public static final boolean isEnabled(android.content.ContentResolver);
    field public static final java.lang.String ACTION_CAPTIONING_SETTINGS = "android.settings.CAPTIONING_SETTINGS";
    method public void addCaptioningStateChangeListener(android.view.accessibility.CaptioningManager.CaptioningChangeListener);
    method public final float getFontScale();
    method public final java.util.Locale getLocale();
    method public android.view.accessibility.CaptioningManager.CaptionStyle getUserStyle();
    method public final boolean isEnabled();
    method public void removeCaptioningStateChangeListener(android.view.accessibility.CaptioningManager.CaptioningChangeListener);
  }
  public static final class CaptioningManager.CaptionStyle {
    method public static android.view.accessibility.CaptioningManager.CaptionStyle defaultUserStyle(android.content.ContentResolver);
    method public android.graphics.Typeface getTypeface();
    field public static final int EDGE_TYPE_DROP_SHADOW = 2; // 0x2
    field public static final int EDGE_TYPE_NONE = 0; // 0x0
@@ -28982,6 +28984,14 @@ package android.view.accessibility {
    field public final int foregroundColor;
  }
  public abstract class CaptioningManager.CaptioningChangeListener {
    ctor public CaptioningManager.CaptioningChangeListener();
    method public void onEnabledChanged(boolean);
    method public void onFontScaleChanged(float);
    method public void onLocaleChanged(java.util.Locale);
    method public void onUserStyleChanged(android.view.accessibility.CaptioningManager.CaptionStyle);
  }
}
package android.view.animation {
+6 −0
Original line number Diff line number Diff line
@@ -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);
+11 −0
Original line number Diff line number Diff line
@@ -2009,6 +2009,17 @@ public abstract class Context {
     */
    public static final String ACCESSIBILITY_SERVICE = "accessibility";

    /**
     * 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.
+23 −12
Original line number Diff line number Diff line
@@ -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,
+238 −62
Original line number Diff line number Diff line
@@ -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.
 */
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.
 * To obtain a handle to the captioning manager, do the following:
 * <p>
     * Output: Nothing.
 * <code>
 * <pre>CaptioningManager captioningManager =
 *        (CaptioningManager) context.getSystemService(Context.CAPTIONING_SERVICE);</pre>
 * </code>
 */
    public static final String ACTION_CAPTIONING_SETTINGS = "android.settings.CAPTIONING_SETTINGS";
public class CaptioningManager {
    /** 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;

    /**
     * @param cr Resolver to access the database with.
     * @return The user's preferred caption enabled state.
     * Creates a new captioning manager for the specified context.
     *
     * @hide
     */
    public static final boolean isEnabled(ContentResolver cr) {
        return Secure.getInt(cr, Secure.ACCESSIBILITY_CAPTIONING_ENABLED, DEFAULT_ENABLED) == 1;
    public CaptioningManager(Context context) {
        mContentResolver = context.getContentResolver();
    }

    /**
     * @param cr Resolver to access the database with.
     * @return The raw locale string for the user's preferred caption language.
     * @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
     */
    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 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.
     */
    public static final float getFontSize(ContentResolver cr) {
        return Secure.getFloat(cr, Secure.ACCESSIBILITY_CAPTIONING_FONT_SIZE, DEFAULT_FONT_SIZE);
    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)) {
@@ -165,44 +321,23 @@ public class CaptioningManager {
            return mParsedTypeface;
        }

        /**
         * @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) {
        }
    }
}