Merge "Taking into account data change for AbsListView when prefetching node infos." into jb-mr2-dev
diff --git a/core/java/android/view/View.java b/core/java/android/view/View.java
index 0cd7c6e..4e8005f 100644
--- a/core/java/android/view/View.java
+++ b/core/java/android/view/View.java
@@ -4928,6 +4928,17 @@
      * @see AccessibilityNodeInfo
      */
     public AccessibilityNodeInfo createAccessibilityNodeInfo() {
+        if (mAccessibilityDelegate != null) {
+            return mAccessibilityDelegate.createAccessibilityNodeInfo(this);
+        } else {
+            return createAccessibilityNodeInfoInternal();
+        }
+    }
+
+    /**
+     * @see #createAccessibilityNodeInfo()
+     */
+    AccessibilityNodeInfo createAccessibilityNodeInfoInternal() {
         AccessibilityNodeProvider provider = getAccessibilityNodeProvider();
         if (provider != null) {
             return provider.createAccessibilityNodeInfo(View.NO_ID);
@@ -18690,6 +18701,33 @@
         public AccessibilityNodeProvider getAccessibilityNodeProvider(View host) {
             return null;
         }
+
+        /**
+         * Returns an {@link AccessibilityNodeInfo} representing the host view from the
+         * point of view of an {@link android.accessibilityservice.AccessibilityService}.
+         * This method is responsible for obtaining an accessibility node info from a
+         * pool of reusable instances and calling
+         * {@link #onInitializeAccessibilityNodeInfo(AccessibilityNodeInfo)} on the host
+         * view to initialize the former.
+         * <p>
+         * <strong>Note:</strong> The client is responsible for recycling the obtained
+         * instance by calling {@link AccessibilityNodeInfo#recycle()} to minimize object
+         * creation.
+         * </p>
+         * <p>
+         * The default implementation behaves as
+         * {@link View#createAccessibilityNodeInfo() View#createAccessibilityNodeInfo()} for
+         * the case of no accessibility delegate been set.
+         * </p>
+         * @return A populated {@link AccessibilityNodeInfo}.
+         *
+         * @see AccessibilityNodeInfo
+         *
+         * @hide
+         */
+        public AccessibilityNodeInfo createAccessibilityNodeInfo(View host) {
+            return host.createAccessibilityNodeInfoInternal();
+        }
     }
 
     private class MatchIdPredicate implements Predicate<View> {
diff --git a/core/java/android/widget/AbsListView.java b/core/java/android/widget/AbsListView.java
index 5a40368..bf66292 100644
--- a/core/java/android/widget/AbsListView.java
+++ b/core/java/android/widget/AbsListView.java
@@ -2213,6 +2213,18 @@
 
     class ListItemAccessibilityDelegate extends AccessibilityDelegate {
         @Override
+        public AccessibilityNodeInfo createAccessibilityNodeInfo(View host) {
+            // If the data changed the children are invalid since the data model changed.
+            // Hence, we pretend they do not exist. After a layout the children will sync
+            // with the model at which point we notify that the accessibility state changed,
+            // so a service will be able to re-fetch the views.
+            if (mDataChanged) {
+                return null;
+            }
+            return super.createAccessibilityNodeInfo(host);
+        }
+
+        @Override
         public void onInitializeAccessibilityNodeInfo(View host, AccessibilityNodeInfo info) {
             super.onInitializeAccessibilityNodeInfo(host, info);