am 972de252: am 24305da7: Merge "Add listener for changes to touch exploration state" into klp-dev

* commit '972de25202c414519e78eaf8f73927cfbd11fe75':
  Add listener for changes to touch exploration state
diff --git a/api/current.txt b/api/current.txt
index c13f3eb..c1cc278 100644
--- a/api/current.txt
+++ b/api/current.txt
@@ -29287,6 +29287,7 @@
 
   public final class AccessibilityManager {
     method public boolean addAccessibilityStateChangeListener(android.view.accessibility.AccessibilityManager.AccessibilityStateChangeListener);
+    method public boolean addTouchExplorationStateChangeListener(android.view.accessibility.AccessibilityManager.TouchExplorationStateChangeListener);
     method public deprecated java.util.List<android.content.pm.ServiceInfo> getAccessibilityServiceList();
     method public java.util.List<android.accessibilityservice.AccessibilityServiceInfo> getEnabledAccessibilityServiceList(int);
     method public java.util.List<android.accessibilityservice.AccessibilityServiceInfo> getInstalledAccessibilityServiceList();
@@ -29294,6 +29295,7 @@
     method public boolean isEnabled();
     method public boolean isTouchExplorationEnabled();
     method public boolean removeAccessibilityStateChangeListener(android.view.accessibility.AccessibilityManager.AccessibilityStateChangeListener);
+    method public boolean removeTouchExplorationStateChangeListener(android.view.accessibility.AccessibilityManager.TouchExplorationStateChangeListener);
     method public void sendAccessibilityEvent(android.view.accessibility.AccessibilityEvent);
   }
 
@@ -29301,6 +29303,10 @@
     method public abstract void onAccessibilityStateChanged(boolean);
   }
 
+  public static abstract interface AccessibilityManager.TouchExplorationStateChangeListener {
+    method public abstract void onTouchExplorationStateChanged(boolean);
+  }
+
   public class AccessibilityNodeInfo implements android.os.Parcelable {
     method public void addAction(int);
     method public void addChild(android.view.View);
diff --git a/core/java/android/view/accessibility/AccessibilityManager.java b/core/java/android/view/accessibility/AccessibilityManager.java
index 04ce7e2..2e8f1a2 100644
--- a/core/java/android/view/accessibility/AccessibilityManager.java
+++ b/core/java/android/view/accessibility/AccessibilityManager.java
@@ -91,25 +91,45 @@
 
     boolean mIsTouchExplorationEnabled;
 
-    final CopyOnWriteArrayList<AccessibilityStateChangeListener> mAccessibilityStateChangeListeners =
-        new CopyOnWriteArrayList<AccessibilityStateChangeListener>();
+    private final CopyOnWriteArrayList<AccessibilityStateChangeListener>
+            mAccessibilityStateChangeListeners = new CopyOnWriteArrayList<
+                    AccessibilityStateChangeListener>();
+
+    private final CopyOnWriteArrayList<TouchExplorationStateChangeListener>
+            mTouchExplorationStateChangeListeners = new CopyOnWriteArrayList<
+                    TouchExplorationStateChangeListener>();
 
     /**
-     * Listener for the system accessibility state. To listen for changes to the accessibility
-     * state on the device, implement this interface and register it with the system by
-     * calling {@link AccessibilityManager#addAccessibilityStateChangeListener
-     * addAccessibilityStateChangeListener()}.
+     * Listener for the system accessibility state. To listen for changes to the
+     * accessibility state on the device, implement this interface and register
+     * it with the system by calling {@link #addAccessibilityStateChangeListener}.
      */
     public interface AccessibilityStateChangeListener {
 
         /**
-         * Called back on change in the accessibility state.
+         * Called when the accessibility enabled state changes.
          *
          * @param enabled Whether accessibility is enabled.
          */
         public void onAccessibilityStateChanged(boolean enabled);
     }
 
+    /**
+     * Listener for the system touch exploration state. To listen for changes to
+     * the touch exploration state on the device, implement this interface and
+     * register it with the system by calling
+     * {@link #addTouchExplorationStateChangeListener}.
+     */
+    public interface TouchExplorationStateChangeListener {
+
+        /**
+         * Called when the touch exploration enabled state changes.
+         *
+         * @param enabled Whether touch exploration is enabled.
+         */
+        public void onTouchExplorationStateChanged(boolean enabled);
+    }
+
     final IAccessibilityManagerClient.Stub mClient = new IAccessibilityManagerClient.Stub() {
         public void setState(int state) {
             mHandler.obtainMessage(DO_SET_STATE, state, 0).sendToTarget();
@@ -363,34 +383,57 @@
     }
 
     /**
-     * Sets the current state.
+     * Registers a {@link TouchExplorationStateChangeListener} for changes in
+     * the global touch exploration state of the system.
+     *
+     * @param listener The listener.
+     * @return True if successfully registered.
+     */
+    public boolean addTouchExplorationStateChangeListener(
+            TouchExplorationStateChangeListener listener) {
+        return mTouchExplorationStateChangeListeners.add(listener);
+    }
+
+    /**
+     * Unregisters a {@link TouchExplorationStateChangeListener}.
+     *
+     * @param listener The listener.
+     * @return True if successfully unregistered.
+     */
+    public boolean removeTouchExplorationStateChangeListener(
+            TouchExplorationStateChangeListener listener) {
+        return mTouchExplorationStateChangeListeners.remove(listener);
+    }
+
+    /**
+     * Sets the current state and notifies listeners, if necessary.
      *
      * @param stateFlags The state flags.
      */
     private void setState(int stateFlags) {
-        final boolean accessibilityEnabled = (stateFlags & STATE_FLAG_ACCESSIBILITY_ENABLED) != 0;
-        setAccessibilityState(accessibilityEnabled);
-        mIsTouchExplorationEnabled = (stateFlags & STATE_FLAG_TOUCH_EXPLORATION_ENABLED) != 0;
-    }
-
-    /**
-     * Sets the enabled state.
-     *
-     * @param isEnabled The accessibility state.
-     */
-    private void setAccessibilityState(boolean isEnabled) {
+        final boolean enabled = (stateFlags & STATE_FLAG_ACCESSIBILITY_ENABLED) != 0;
+        final boolean touchExplorationEnabled =
+                (stateFlags & STATE_FLAG_TOUCH_EXPLORATION_ENABLED) != 0;
         synchronized (mHandler) {
-            if (isEnabled != mIsEnabled) {
-                mIsEnabled = isEnabled;
-                notifyAccessibilityStateChanged();
+            mIsEnabled = enabled;
+            mIsTouchExplorationEnabled = touchExplorationEnabled;
+
+            if (enabled != mIsEnabled) {
+                notifyAccessibilityStateChangedLh();
+            }
+
+            if (touchExplorationEnabled != mIsTouchExplorationEnabled) {
+                notifyTouchExplorationStateChangedLh();
             }
         }
     }
 
     /**
      * Notifies the registered {@link AccessibilityStateChangeListener}s.
+     * <p>
+     * The caller must be locked on {@link #mHandler}.
      */
-    private void notifyAccessibilityStateChanged() {
+    private void notifyAccessibilityStateChangedLh() {
         final int listenerCount = mAccessibilityStateChangeListeners.size();
         for (int i = 0; i < listenerCount; i++) {
             mAccessibilityStateChangeListeners.get(i).onAccessibilityStateChanged(mIsEnabled);
@@ -398,6 +441,19 @@
     }
 
     /**
+     * Notifies the registered {@link TouchExplorationStateChangeListener}s.
+     * <p>
+     * The caller must be locked on {@link #mHandler}.
+     */
+    private void notifyTouchExplorationStateChangedLh() {
+        final int listenerCount = mTouchExplorationStateChangeListeners.size();
+        for (int i = 0; i < listenerCount; i++) {
+            mTouchExplorationStateChangeListeners.get(i)
+                    .onTouchExplorationStateChanged(mIsTouchExplorationEnabled);
+        }
+    }
+
+    /**
      * Adds an accessibility interaction connection interface for a given window.
      * @param windowToken The window token to which a connection is added.
      * @param connection The connection.