diff options
| -rw-r--r-- | core/api/current.txt | 6 | ||||
| -rw-r--r-- | core/java/android/view/accessibility/AccessibilityManager.java | 88 |
2 files changed, 90 insertions, 4 deletions
diff --git a/core/api/current.txt b/core/api/current.txt index 93f100349a95..7f93f058d266 100644 --- a/core/api/current.txt +++ b/core/api/current.txt @@ -51145,6 +51145,7 @@ package android.view.accessibility { method public void addAccessibilityServicesStateChangeListener(@NonNull android.view.accessibility.AccessibilityManager.AccessibilityServicesStateChangeListener); method public boolean addAccessibilityStateChangeListener(@NonNull android.view.accessibility.AccessibilityManager.AccessibilityStateChangeListener); method public void addAccessibilityStateChangeListener(@NonNull android.view.accessibility.AccessibilityManager.AccessibilityStateChangeListener, @Nullable android.os.Handler); + method public void addAudioDescriptionByDefaultStateChangeListener(@NonNull java.util.concurrent.Executor, @NonNull android.view.accessibility.AccessibilityManager.AudioDescriptionByDefaultStateChangeListener); method public boolean addTouchExplorationStateChangeListener(@NonNull android.view.accessibility.AccessibilityManager.TouchExplorationStateChangeListener); method public void addTouchExplorationStateChangeListener(@NonNull android.view.accessibility.AccessibilityManager.TouchExplorationStateChangeListener, @Nullable android.os.Handler); method @ColorInt public int getAccessibilityFocusColor(); @@ -51161,6 +51162,7 @@ package android.view.accessibility { method public void removeAccessibilityRequestPreparer(android.view.accessibility.AccessibilityRequestPreparer); method public boolean removeAccessibilityServicesStateChangeListener(@NonNull android.view.accessibility.AccessibilityManager.AccessibilityServicesStateChangeListener); method public boolean removeAccessibilityStateChangeListener(@NonNull android.view.accessibility.AccessibilityManager.AccessibilityStateChangeListener); + method public boolean removeAudioDescriptionByDefaultStateChangeListener(@NonNull android.view.accessibility.AccessibilityManager.AudioDescriptionByDefaultStateChangeListener); method public boolean removeTouchExplorationStateChangeListener(@NonNull android.view.accessibility.AccessibilityManager.TouchExplorationStateChangeListener); method public void sendAccessibilityEvent(android.view.accessibility.AccessibilityEvent); field public static final int FLAG_CONTENT_CONTROLS = 4; // 0x4 @@ -51176,6 +51178,10 @@ package android.view.accessibility { method public void onAccessibilityStateChanged(boolean); } + public static interface AccessibilityManager.AudioDescriptionByDefaultStateChangeListener { + method public void onAudioDescriptionByDefaultStateChanged(boolean); + } + public static interface AccessibilityManager.TouchExplorationStateChangeListener { method public void onTouchExplorationStateChanged(boolean); } diff --git a/core/java/android/view/accessibility/AccessibilityManager.java b/core/java/android/view/accessibility/AccessibilityManager.java index dc617270cbf9..078b76752512 100644 --- a/core/java/android/view/accessibility/AccessibilityManager.java +++ b/core/java/android/view/accessibility/AccessibilityManager.java @@ -273,6 +273,9 @@ public final class AccessibilityManager { private final ArrayMap<AccessibilityServicesStateChangeListener, Executor> mServicesStateChangeListeners = new ArrayMap<>(); + private final ArrayMap<AudioDescriptionByDefaultStateChangeListener, Executor> + mAudioDescriptionByDefaultStateChangeListeners = new ArrayMap<>(); + /** * Map from a view's accessibility id to the list of request preparers set for that view */ @@ -353,6 +356,21 @@ public final class AccessibilityManager { } /** + * Listener for the audio description by default state. To listen for + * changes to the audio description by default state on the device, + * implement this interface and register it with the system by calling + * {@link #addAudioDescriptionByDefaultStateChangeListener}. + */ + public interface AudioDescriptionByDefaultStateChangeListener { + /** + * Called when the audio description enabled state changes. + * + * @param enabled Whether audio description by default is enabled. + */ + void onAudioDescriptionByDefaultStateChanged(boolean enabled); + } + + /** * Policy to inject behavior into the accessibility manager. * * @hide @@ -1159,6 +1177,35 @@ public final class AccessibilityManager { } /** + * Registers a {@link AudioDescriptionByDefaultStateChangeListener} + * for changes in the audio description by default state of the system. + * The value could be read via {@link #isAudioDescriptionRequested}. + * + * @param executor The executor on which the listener should be called back. + * @param listener The listener. + */ + public void addAudioDescriptionByDefaultStateChangeListener( + @NonNull Executor executor, + @NonNull AudioDescriptionByDefaultStateChangeListener listener) { + synchronized (mLock) { + mAudioDescriptionByDefaultStateChangeListeners.put(listener, executor); + } + } + + /** + * Unregisters a {@link AudioDescriptionByDefaultStateChangeListener}. + * + * @param listener The listener. + * @return True if listener was previously registered. + */ + public boolean removeAudioDescriptionByDefaultStateChangeListener( + @NonNull AudioDescriptionByDefaultStateChangeListener listener) { + synchronized (mLock) { + return (mAudioDescriptionByDefaultStateChangeListeners.remove(listener) != null); + } + } + + /** * Sets the {@link AccessibilityPolicy} controlling this manager. * * @param policy The policy. @@ -1303,7 +1350,7 @@ public final class AccessibilityManager { final boolean wasEnabled = isEnabled(); final boolean wasTouchExplorationEnabled = mIsTouchExplorationEnabled; final boolean wasHighTextContrastEnabled = mIsHighTextContrastEnabled; - + final boolean wasAudioDescriptionByDefaultRequested = mIsAudioDescriptionByDefaultRequested; // Ensure listeners get current state from isZzzEnabled() calls. mIsEnabled = enabled; @@ -1323,6 +1370,11 @@ public final class AccessibilityManager { notifyHighTextContrastStateChanged(); } + if (wasAudioDescriptionByDefaultRequested + != audioDescriptionEnabled) { + notifyAudioDescriptionbyDefaultStateChanged(); + } + updateAccessibilityTracingState(stateFlags); } @@ -1688,15 +1740,20 @@ public final class AccessibilityManager { /** * Determines if users want to select sound track with audio description by default. - * + * <p> * Audio description, also referred to as a video description, described video, or * more precisely called a visual description, is a form of narration used to provide * information surrounding key visual elements in a media work for the benefit of * blind and visually impaired consumers. - * + * </p> + * <p> * The method provides the preference value to content provider apps to select the * default sound track during playing a video or movie. - * + * </p> + * <p> + * Add listener to detect the state change via + * {@link #addAudioDescriptionByDefaultStateChangeListener} + * </p> * @return {@code true} if the audio description is enabled, {@code false} otherwise. */ public boolean isAudioDescriptionRequested() { @@ -1804,6 +1861,29 @@ public final class AccessibilityManager { } /** + * Notifies the registered {@link AudioDescriptionStateChangeListener}s. + */ + private void notifyAudioDescriptionbyDefaultStateChanged() { + final boolean isAudioDescriptionByDefaultRequested; + final ArrayMap<AudioDescriptionByDefaultStateChangeListener, Executor> listeners; + synchronized (mLock) { + if (mAudioDescriptionByDefaultStateChangeListeners.isEmpty()) { + return; + } + isAudioDescriptionByDefaultRequested = mIsAudioDescriptionByDefaultRequested; + listeners = new ArrayMap<>(mAudioDescriptionByDefaultStateChangeListeners); + } + + final int numListeners = listeners.size(); + for (int i = 0; i < numListeners; i++) { + final AudioDescriptionByDefaultStateChangeListener listener = listeners.keyAt(i); + listeners.valueAt(i).execute(() -> + listener.onAudioDescriptionByDefaultStateChanged( + isAudioDescriptionByDefaultRequested)); + } + } + + /** * Update mAccessibilityTracingState. */ private void updateAccessibilityTracingState(int stateFlag) { |