Touch exploration state set to clients asynchronously and depended on talking service being enabled.

1. Upon registration of an accessibility client the latter received only
   the accessiiblity state and waiting for the touch exploration state
   to be sent by the system in async manner. This led the very first
   check of touch exploration state is checked a wrong value to be reported.
   Now a state of the accessibility layer is returned to the client
   upon registration.

2. Removing the dependency on talking accessibility service to be enabled
   for getting into touch exploration mode. What if the user wants to use
   an accessibility service that shows a dialog with the text of the touched
   view?

bug:5051546

Change-Id: Ib377babb3f560929ee73bd3d8b0d277341ba23f7
diff --git a/core/java/android/accessibilityservice/AccessibilityServiceInfo.java b/core/java/android/accessibilityservice/AccessibilityServiceInfo.java
index a09607a..41a3eaca 100644
--- a/core/java/android/accessibilityservice/AccessibilityServiceInfo.java
+++ b/core/java/android/accessibilityservice/AccessibilityServiceInfo.java
@@ -75,6 +75,17 @@
     public static final int FEEDBACK_GENERIC = 0x0000010;
 
     /**
+     * Mask for all feedback types.
+     *
+     * @see #FEEDBACK_SPOKEN
+     * @see #FEEDBACK_HAPTIC
+     * @see #FEEDBACK_AUDIBLE
+     * @see #FEEDBACK_VISUAL
+     * @see #FEEDBACK_GENERIC
+     */
+    public static final int FEEDBACK_ALL_MASK = 0xFFFFFFFF;
+
+    /**
      * If an {@link AccessibilityService} is the default for a given type.
      * Default service is invoked only if no package specific one exists. In case of
      * more than one package specific service only the earlier registered is notified.
diff --git a/core/java/android/provider/Settings.java b/core/java/android/provider/Settings.java
index cb87e94..e48c858 100644
--- a/core/java/android/provider/Settings.java
+++ b/core/java/android/provider/Settings.java
@@ -2691,11 +2691,9 @@
         public static final String ACCESSIBILITY_ENABLED = "accessibility_enabled";
 
         /**
-         * If touch exploration is requested. Touch exploration is enabled if it is
-         * requested by this setting, accessibility is enabled and there is at least
-         * one enabled accessibility serivce that provides spoken feedback.
+         * If touch exploration is enabled.
          */
-        public static final String TOUCH_EXPLORATION_REQUESTED = "touch_exploration_requested";
+        public static final String TOUCH_EXPLORATION_ENABLED = "touch_exploration_enabled";
 
         /**
          * List of the enabled accessibility providers.
diff --git a/core/java/android/view/accessibility/AccessibilityManager.java b/core/java/android/view/accessibility/AccessibilityManager.java
index 83c73cb..a80c2a7 100644
--- a/core/java/android/view/accessibility/AccessibilityManager.java
+++ b/core/java/android/view/accessibility/AccessibilityManager.java
@@ -67,13 +67,17 @@
 
     private static final String LOG_TAG = "AccessibilityManager";
 
+    /** @hide */
+    public static final int STATE_FLAG_ACCESSIBILITY_ENABLED = 0x00000001;
+
+    /** @hide */
+    public static final int STATE_FLAG_TOUCH_EXPLORATION_ENABLED = 0x00000002;
+
     static final Object sInstanceSync = new Object();
 
     private static AccessibilityManager sInstance;
 
-    private static final int DO_SET_ACCESSIBILITY_ENABLED = 10;
-
-    private static final int DO_SET_TOUCH_EXPLORATION_ENABLED = 20;
+    private static final int DO_SET_STATE = 10;
 
     final IAccessibilityManager mService;
 
@@ -100,13 +104,8 @@
     }
 
     final IAccessibilityManagerClient.Stub mClient = new IAccessibilityManagerClient.Stub() {
-        public void setEnabled(boolean enabled) {
-            mHandler.obtainMessage(DO_SET_ACCESSIBILITY_ENABLED, enabled ? 1 : 0, 0).sendToTarget();
-        }
-
-        public void setTouchExplorationEnabled(boolean enabled) {
-            mHandler.obtainMessage(DO_SET_TOUCH_EXPLORATION_ENABLED,
-                    enabled ? 1 : 0, 0).sendToTarget();
+        public void setState(int state) {
+            mHandler.obtainMessage(DO_SET_STATE, state, 0).sendToTarget();
         }
     };
 
@@ -119,14 +118,8 @@
         @Override
         public void handleMessage(Message message) {
             switch (message.what) {
-                case DO_SET_ACCESSIBILITY_ENABLED :
-                    final boolean isAccessibilityEnabled = (message.arg1 == 1);
-                    setAccessibilityState(isAccessibilityEnabled);
-                    return;
-                case DO_SET_TOUCH_EXPLORATION_ENABLED :
-                    synchronized (mHandler) {
-                        mIsTouchExplorationEnabled = (message.arg1 == 1);
-                    }
+                case DO_SET_STATE :
+                    setState(message.arg1);
                     return;
                 default :
                     Log.w(LOG_TAG, "Unknown message type: " + message.what);
@@ -163,8 +156,8 @@
         mService = service;
 
         try {
-            final boolean isEnabled = mService.addClient(mClient);
-            setAccessibilityState(isEnabled);
+            final int stateFlags = mService.addClient(mClient);
+            setState(stateFlags);
         } catch (RemoteException re) {
             Log.e(LOG_TAG, "AccessibilityManagerService is dead", re);
         }
@@ -341,6 +334,17 @@
     }
 
     /**
+     * Sets the current state.
+     *
+     * @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.
diff --git a/core/java/android/view/accessibility/AccessibilityNodeInfo.java b/core/java/android/view/accessibility/AccessibilityNodeInfo.java
index 0e04471..6469b35 100644
--- a/core/java/android/view/accessibility/AccessibilityNodeInfo.java
+++ b/core/java/android/view/accessibility/AccessibilityNodeInfo.java
@@ -294,14 +294,14 @@
     }
 
     /**
-     * Gets the unique id identifying this node's parent.
+     * Gets the parent.
      * <p>
      *   <strong>Note:</strong> It is a client responsibility to recycle the
      *     received info by calling {@link AccessibilityNodeInfo#recycle()}
      *     to avoid creating of multiple instances.
      * </p>
      *
-     * @return The node's patent id.
+     * @return The parent.
      */
     public AccessibilityNodeInfo getParent() {
         enforceSealed();
diff --git a/core/java/android/view/accessibility/IAccessibilityManager.aidl b/core/java/android/view/accessibility/IAccessibilityManager.aidl
index b14f02a..c621ff6 100644
--- a/core/java/android/view/accessibility/IAccessibilityManager.aidl
+++ b/core/java/android/view/accessibility/IAccessibilityManager.aidl
@@ -34,7 +34,7 @@
  */
 interface IAccessibilityManager {
 
-    boolean addClient(IAccessibilityManagerClient client);
+    int addClient(IAccessibilityManagerClient client);
 
     boolean sendAccessibilityEvent(in AccessibilityEvent uiEvent);
 
diff --git a/core/java/android/view/accessibility/IAccessibilityManagerClient.aidl b/core/java/android/view/accessibility/IAccessibilityManagerClient.aidl
index 4e69692..5e7e813 100644
--- a/core/java/android/view/accessibility/IAccessibilityManagerClient.aidl
+++ b/core/java/android/view/accessibility/IAccessibilityManagerClient.aidl
@@ -24,7 +24,5 @@
  */
 oneway interface IAccessibilityManagerClient {
 
-    void setEnabled(boolean enabled);
-
-    void setTouchExplorationEnabled(boolean enabled);
+    void setState(int stateFlags);
 }
diff --git a/core/res/res/values/attrs.xml b/core/res/res/values/attrs.xml
index 082284a..e307c179 100755
--- a/core/res/res/values/attrs.xml
+++ b/core/res/res/values/attrs.xml
@@ -2281,6 +2281,8 @@
             <flag name="feedbackVisual" value="0x00000008" />
             <!-- Provides {@link android.accessibilityservice.AccessibilityServiceInfo#FEEDBACK_GENERIC} feedback. -->
             <flag name="feedbackGeneric" value="0x00000010" />
+            <!-- Provides {@link android.accessibilityservice.AccessibilityServiceInfo#FEEDBACK_ALL_MASK} feedback. -->
+            <flag name="feedbackAllMask" value="0xffffffff" />
         </attr>
         <!-- The minimal period in milliseconds between two accessibility events of the same type
              are sent to this serivce. This setting can be changed at runtime by calling
diff --git a/core/tests/coretests/src/android/view/accessibility/RecycleAccessibilityEventTest.java b/core/tests/coretests/src/android/view/accessibility/RecycleAccessibilityEventTest.java
index bbf1696..4814c61 100644
--- a/core/tests/coretests/src/android/view/accessibility/RecycleAccessibilityEventTest.java
+++ b/core/tests/coretests/src/android/view/accessibility/RecycleAccessibilityEventTest.java
@@ -65,13 +65,13 @@
         assertEquals(0, first.getText().size());
         assertFalse(first.isChecked());
         assertNull(first.getContentDescription());
-        assertEquals(0, first.getItemCount());
+        assertEquals(-1, first.getItemCount());
         assertEquals(AccessibilityEvent.INVALID_POSITION, first.getCurrentItemIndex());
         assertFalse(first.isEnabled());
         assertFalse(first.isPassword());
-        assertEquals(0, first.getFromIndex());
-        assertEquals(0, first.getAddedCount());
-        assertEquals(0, first.getRemovedCount());
+        assertEquals(-1, first.getFromIndex());
+        assertEquals(-1, first.getAddedCount());
+        assertEquals(-1, first.getRemovedCount());
 
         // get another event from the pool (this must be the recycled first)
         AccessibilityEvent second = AccessibilityEvent.obtain();