Merge "Fixing errors in position information of scrollable views reported for accessibility."
diff --git a/core/java/android/view/View.java b/core/java/android/view/View.java
index 632ab4a..43654d2 100644
--- a/core/java/android/view/View.java
+++ b/core/java/android/view/View.java
@@ -4003,23 +4003,13 @@
         event.setEnabled(isEnabled());
         event.setContentDescription(mContentDescription);
 
-        final int eventType = event.getEventType();
-        switch (eventType) {
-            case AccessibilityEvent.TYPE_VIEW_FOCUSED: {
-                if (mAttachInfo != null) {
-                    ArrayList<View> focusablesTempList = mAttachInfo.mFocusablesTempList;
-                    getRootView().addFocusables(focusablesTempList, View.FOCUS_FORWARD,
-                            FOCUSABLES_ALL);
-                    event.setItemCount(focusablesTempList.size());
-                    event.setCurrentItemIndex(focusablesTempList.indexOf(this));
-                    focusablesTempList.clear();
-                }
-            } break;
-            case AccessibilityEvent.TYPE_VIEW_SCROLLED: {
-                event.setScrollX(mScrollX);
-                event.setScrollY(mScrollY);
-                event.setItemCount(getHeight());
-            } break;
+        if (event.getEventType() == AccessibilityEvent.TYPE_VIEW_FOCUSED && mAttachInfo != null) {
+            ArrayList<View> focusablesTempList = mAttachInfo.mFocusablesTempList;
+            getRootView().addFocusables(focusablesTempList, View.FOCUS_FORWARD,
+                    FOCUSABLES_ALL);
+            event.setItemCount(focusablesTempList.size());
+            event.setCurrentItemIndex(focusablesTempList.indexOf(this));
+            focusablesTempList.clear();
         }
     }
 
diff --git a/core/java/android/view/accessibility/AccessibilityEvent.java b/core/java/android/view/accessibility/AccessibilityEvent.java
index 91fbb0e..25bc559 100644
--- a/core/java/android/view/accessibility/AccessibilityEvent.java
+++ b/core/java/android/view/accessibility/AccessibilityEvent.java
@@ -79,6 +79,16 @@
  *   <li>{@link #isPassword()} - Whether the source is password.</li>
  *   <li>{@link #isChecked()} - Whether the source is checked.</li>
  *   <li>{@link #getContentDescription()} - The content description of the source.</li>
+ *   <li>{@link #getScrollX()} - The offset of the source left edge in pixels
+ *       (without descendants of AdapterView).</li>
+ *   <li>{@link #getScrollY()} - The offset of the source top edge in pixels
+ *       (without descendants of AdapterView).</li>
+ *   <li>{@link #getFromIndex()} - The zero based index of the first visible item of the source,
+ *       inclusive (for descendants of AdapterView).</li>
+ *   <li>{@link #getToIndex()} - The zero based index of the last visible item of the source,
+ *       inclusive (for descendants of AdapterView).</li>
+ *   <li>{@link #getItemCount()} - The total items of the source
+ *       (for descendants of AdapterView).</li>
  * </ul>
  * </p>
  * <p>
@@ -97,6 +107,16 @@
  *   <li>{@link #isPassword()} - Whether the source is password.</li>
  *   <li>{@link #isChecked()} - Whether the source is checked.</li>
  *   <li>{@link #getContentDescription()} - The content description of the source.</li>
+ *   <li>{@link #getScrollX()} - The offset of the source left edge in pixels
+ *       (without descendants of AdapterView).</li>
+ *   <li>{@link #getScrollY()} - The offset of the source top edge in pixels
+ *       (without descendants of AdapterView).</li>
+ *   <li>{@link #getFromIndex()} - The zero based index of the first visible item of the source,
+ *       inclusive (for descendants of AdapterView).</li>
+ *   <li>{@link #getToIndex()} - The zero based index of the last visible item of the source,
+ *       inclusive (for descendants of AdapterView).</li>
+ *   <li>{@link #getItemCount()} - The total items of the source
+ *       (for descendants of AdapterView).</li>
  * </ul>
  * </p>
  * <p>
@@ -117,6 +137,16 @@
  *   <li>{@link #getItemCount()} - The number of selectable items of the source.</li>
  *   <li>{@link #getCurrentItemIndex()} - The currently selected item index.</li>
  *   <li>{@link #getContentDescription()} - The content description of the source.</li>
+ *   <li>{@link #getScrollX()} - The offset of the source left edge in pixels
+ *       (without descendants of AdapterView).</li>
+ *   <li>{@link #getScrollY()} - The offset of the source top edge in pixels
+ *       (without descendants of AdapterView).</li>
+ *   <li>{@link #getFromIndex()} - The zero based index of the first visible item of the source,
+ *       inclusive (for descendants of AdapterView).</li>
+ *   <li>{@link #getToIndex()} - The zero based index of the last visible item of the source,
+ *       inclusive (for descendants of AdapterView).</li>
+ *   <li>{@link #getItemCount()} - The total items of the source
+ *       (for descendants of AdapterView).</li>
  * </ul>
  * </p>
  * <p>
@@ -137,6 +167,16 @@
  *   <li>{@link #getItemCount()} - The number of focusable items on the screen.</li>
  *   <li>{@link #getCurrentItemIndex()} - The currently focused item index.</li>
  *   <li>{@link #getContentDescription()} - The content description of the source.</li>
+ *   <li>{@link #getScrollX()} - The offset of the source left edge in pixels
+ *       (without descendants of AdapterView).</li>
+ *   <li>{@link #getScrollY()} - The offset of the source top edge in pixels
+ *       (without descendants of AdapterView).</li>
+ *   <li>{@link #getFromIndex()} - The zero based index of the first visible item of the source,
+ *       inclusive (for descendants of AdapterView).</li>
+ *   <li>{@link #getToIndex()} - The zero based index of the last visible item of the source,
+ *       inclusive (for descendants of AdapterView).</li>
+ *   <li>{@link #getItemCount()} - The total items of the source
+ *       (for descendants of AdapterView).</li>
  * </ul>
  * </p>
  * <p>
@@ -218,18 +258,17 @@
  *   <li>{@link #getEventTime()}  - The event time.</li>
  *   <li>{@link #getText()} - The text of the source's sub-tree.</li>
  *   <li>{@link #isEnabled()} - Whether the source is enabled.</li>
- *   <li>{@link #getScrollX()} - The horizontal offset of the source
- *                                (without descendants of AdapterView)).</li>
- *   <li>{@link #getScrollY()} - The vertical offset of the source
- *                                (without descendants of AdapterView)).</li>
- *   <li>{@link #getFromIndex()} - The index of the first visible item of the source
- *                                 (for descendants of AdapterView).</li>
- *   <li>{@link #getToIndex()} - The index of the last visible item of the source
- *                               (for descendants of AdapterView).</li>
- *   <li>{@link #getItemCount()} - The total items of the source (for descendants of AdapterView)
- *                                 or the height of the source in pixels (all other cases).</li>
- *   <li>{@link #getText()} - Text for providing more context.</li>
  *   <li>{@link #getContentDescription()} - The content description of the source.</li>
+ *   <li>{@link #getScrollX()} - The offset of the source left edge in pixels
+ *       (without descendants of AdapterView).</li>
+ *   <li>{@link #getScrollY()} - The offset of the source top edge in pixels
+ *       (without descendants of AdapterView).</li>
+ *   <li>{@link #getFromIndex()} - The zero based index of the first visible item of the source,
+ *       inclusive (for descendants of AdapterView).</li>
+ *   <li>{@link #getToIndex()} - The zero based index of the last visible item of the source,
+ *       inclusive (for descendants of AdapterView).</li>
+ *   <li>{@link #getItemCount()} - The total items of the source
+ *       (for descendants of AdapterView).</li>
  * </ul>
  * <em>Note:</em> This event type is not dispatched to descendants though
  * {@link android.view.View#dispatchPopulateAccessibilityEvent(AccessibilityEvent)
@@ -334,6 +373,16 @@
  *   <li>{@link #getText()} - The text of the source's sub-tree.</li>
  *   <li>{@link #isEnabled()} - Whether the source is enabled.</li>
  *   <li>{@link #getContentDescription()} - The content description of the source.</li>
+ *   <li>{@link #getScrollX()} - The offset of the source left edge in pixels
+ *       (without descendants of AdapterView).</li>
+ *   <li>{@link #getScrollY()} - The offset of the source top edge in pixels
+ *       (without descendants of AdapterView).</li>
+ *   <li>{@link #getFromIndex()} - The zero based index of the first visible item of the source,
+ *       inclusive (for descendants of AdapterView).</li>
+ *   <li>{@link #getToIndex()} - The zero based index of the last visible item of the source,
+ *       inclusive (for descendants of AdapterView).</li>
+ *   <li>{@link #getItemCount()} - The total items of the source
+ *       (for descendants of AdapterView).</li>
  * </ul>
  * </p>
  * <b>View hover exit</b> - represents the event of stopping to hover
@@ -350,6 +399,16 @@
  *   <li>{@link #getText()} - The text of the source's sub-tree.</li>
  *   <li>{@link #isEnabled()} - Whether the source is enabled.</li>
  *   <li>{@link #getContentDescription()} - The content description of the source.</li>
+ *   <li>{@link #getScrollX()} - The offset of the source left edge in pixels
+ *       (without descendants of AdapterView).</li>
+ *   <li>{@link #getScrollY()} - The offset of the source top edge in pixels
+ *       (without descendants of AdapterView).</li>
+ *   <li>{@link #getFromIndex()} - The zero based index of the first visible item of the source,
+ *       inclusive (for descendants of AdapterView).</li>
+ *   <li>{@link #getToIndex()} - The zero based index of the last visible item of the source,
+ *       inclusive (for descendants of AdapterView).</li>
+ *   <li>{@link #getItemCount()} - The total items of the source
+ *       (for descendants of AdapterView).</li>
  * </ul>
  * </p>
  * <p>
@@ -816,6 +875,8 @@
         record.mToIndex = parcel.readInt();
         record.mScrollX = parcel.readInt();
         record.mScrollY =  parcel.readInt();
+        record.mMaxScrollX = parcel.readInt();
+        record.mMaxScrollY =  parcel.readInt();
         record.mAddedCount = parcel.readInt();
         record.mRemovedCount = parcel.readInt();
         record.mClassName = TextUtils.CHAR_SEQUENCE_CREATOR.createFromParcel(parcel);
@@ -868,6 +929,8 @@
         parcel.writeInt(record.mToIndex);
         parcel.writeInt(record.mScrollX);
         parcel.writeInt(record.mScrollY);
+        parcel.writeInt(record.mMaxScrollX);
+        parcel.writeInt(record.mMaxScrollY);
         parcel.writeInt(record.mAddedCount);
         parcel.writeInt(record.mRemovedCount);
         TextUtils.writeToParcel(record.mClassName, parcel, flags);
diff --git a/core/java/android/view/accessibility/AccessibilityRecord.java b/core/java/android/view/accessibility/AccessibilityRecord.java
index afd7473..fe06d98 100644
--- a/core/java/android/view/accessibility/AccessibilityRecord.java
+++ b/core/java/android/view/accessibility/AccessibilityRecord.java
@@ -73,6 +73,8 @@
     int mToIndex = UNDEFINED;
     int mScrollX = UNDEFINED;
     int mScrollY = UNDEFINED;
+    int mMaxScrollX = UNDEFINED;
+    int mMaxScrollY = UNDEFINED;
 
     int mAddedCount= UNDEFINED;
     int mRemovedCount = UNDEFINED;
@@ -348,18 +350,18 @@
     }
 
     /**
-     * Gets the scroll position of the source along the X axis.
+     * Gets the scroll offset of the source left edge in pixels.
      *
-     * @return The scroll along the X axis.
+     * @return The scroll.
      */
     public int getScrollX() {
         return mScrollX;
     }
 
     /**
-     * Sets the scroll position of the source along the X axis.
+     * Sets the scroll offset of the source left edge in pixels.
      *
-     * @param scrollX The scroll along the X axis.
+     * @param scrollX The scroll.
      */
     public void setScrollX(int scrollX) {
         enforceNotSealed();
@@ -367,18 +369,18 @@
     }
 
     /**
-     * Gets the scroll position of the source along the Y axis.
+     * Gets the scroll offset of the source top edge in pixels.
      *
-     * @return The scroll along the Y axis.
+     * @return The scroll.
      */
     public int getScrollY() {
         return mScrollY;
     }
 
     /**
-     * Sets the scroll position of the source along the Y axis.
+     * Sets the scroll offset of the source top edge in pixels.
      *
-     * @param scrollY The scroll along the Y axis.
+     * @param scrollY The scroll.
      */
     public void setScrollY(int scrollY) {
         enforceNotSealed();
@@ -386,6 +388,51 @@
     }
 
     /**
+     * Gets the max scroll offset of the source left edge in pixels.
+     *
+     * @return The max scroll.
+     *
+     * @hide
+     */
+    public int getMaxScrollX() {
+        return mMaxScrollX;
+    }
+    /**
+     * Sets the max scroll offset of the source left edge in pixels.
+     *
+     * @param maxScrollX The max scroll.
+     *
+     * @hide
+     */
+    public void setMaxScrollX(int maxScrollX) {
+        enforceNotSealed();
+        mMaxScrollX = maxScrollX;
+    }
+
+    /**
+     * Gets the max scroll offset of the source top edge in pixels.
+     *
+     * @return The max scroll.
+     *
+     * @hide
+     */
+    public int getMaxScrollY() {
+        return mMaxScrollY;
+    }
+
+    /**
+     * Sets the max scroll offset of the source top edge in pixels.
+     *
+     * @param maxScrollY The max scroll.
+     *
+     * @hide
+     */
+    public void setMaxScrollY(int maxScrollY) {
+        enforceNotSealed();
+        mMaxScrollY = maxScrollY;
+    }
+
+    /**
      * Gets the number of added characters.
      *
      * @return The number of added characters.
@@ -658,6 +705,8 @@
         mToIndex = record.mToIndex;
         mScrollX = record.mScrollX;
         mScrollY = record.mScrollY;
+        mMaxScrollX = record.mMaxScrollX;
+        mMaxScrollY = record.mMaxScrollY;
         mAddedCount = record.mAddedCount;
         mRemovedCount = record.mRemovedCount;
         mClassName = record.mClassName;
@@ -682,6 +731,8 @@
         mToIndex = UNDEFINED;
         mScrollX = UNDEFINED;
         mScrollY = UNDEFINED;
+        mMaxScrollX = UNDEFINED;
+        mMaxScrollY = UNDEFINED;
         mAddedCount = UNDEFINED;
         mRemovedCount = UNDEFINED;
         mClassName = null;
@@ -711,6 +762,8 @@
         builder.append("; ToIndex: " + mToIndex);
         builder.append("; ScrollX: " + mScrollX);
         builder.append("; ScrollY: " + mScrollY);
+        builder.append("; MaxScrollX: " + mMaxScrollX);
+        builder.append("; MaxScrollY: " + mMaxScrollY);
         builder.append("; AddedCount: " + mAddedCount);
         builder.append("; RemovedCount: " + mRemovedCount);
         builder.append("; ParcelableData: " + mParcelableData);
diff --git a/core/java/android/webkit/WebView.java b/core/java/android/webkit/WebView.java
index 5111969..d920f27 100644
--- a/core/java/android/webkit/WebView.java
+++ b/core/java/android/webkit/WebView.java
@@ -77,7 +77,9 @@
 import android.view.ViewGroup;
 import android.view.ViewParent;
 import android.view.ViewTreeObserver;
+import android.view.accessibility.AccessibilityEvent;
 import android.view.accessibility.AccessibilityManager;
+import android.view.accessibility.AccessibilityNodeInfo;
 import android.view.inputmethod.EditorInfo;
 import android.view.inputmethod.InputConnection;
 import android.view.inputmethod.InputMethodManager;
@@ -1303,6 +1305,31 @@
     }
 
     @Override
+    public void onInitializeAccessibilityNodeInfo(AccessibilityNodeInfo info) {
+        super.onInitializeAccessibilityNodeInfo(info);
+        info.setScrollable(isScrollableForAccessibility());
+    }
+
+    @Override
+    public void onInitializeAccessibilityEvent(AccessibilityEvent event) {
+        super.onInitializeAccessibilityEvent(event);
+        event.setScrollable(isScrollableForAccessibility());
+        event.setScrollX(mScrollX);
+        event.setScrollY(mScrollY);
+        final int convertedContentWidth = contentToViewX(getContentWidth());
+        final int adjustedViewWidth = getWidth() - mPaddingLeft - mPaddingRight;
+        event.setMaxScrollX(Math.max(convertedContentWidth - adjustedViewWidth, 0));
+        final int convertedContentHeight = contentToViewY(getContentHeight());
+        final int adjustedViewHeight = getHeight() - mPaddingTop - mPaddingBottom;
+        event.setMaxScrollY(Math.max(convertedContentHeight - adjustedViewHeight, 0));
+    }
+
+    private boolean isScrollableForAccessibility() {
+        return (contentToViewX(getContentWidth()) > getWidth() - mPaddingLeft - mPaddingRight
+                || contentToViewY(getContentHeight()) > getHeight() - mPaddingTop - mPaddingBottom);
+    }
+
+    @Override
     public void setOverScrollMode(int mode) {
         super.setOverScrollMode(mode);
         if (mode != OVER_SCROLL_NEVER) {
diff --git a/core/java/android/widget/AbsListView.java b/core/java/android/widget/AbsListView.java
index 7b8c7f2..c218f23 100644
--- a/core/java/android/widget/AbsListView.java
+++ b/core/java/android/widget/AbsListView.java
@@ -1270,40 +1270,24 @@
     }
 
     @Override
-    public void onInitializeAccessibilityNodeInfo(AccessibilityNodeInfo info) {
-        super.onInitializeAccessibilityNodeInfo(info);
-        info.setScrollable(true);
-    }
-
-    @Override
     public void sendAccessibilityEvent(int eventType) {
         // Since this class calls onScrollChanged even if the mFirstPosition and the
         // child count have not changed we will avoid sending duplicate accessibility
         // events.
         if (eventType == AccessibilityEvent.TYPE_VIEW_SCROLLED) {
-            final int lastPosition = mFirstPosition + getChildCount();
-            if (mLastAccessibilityScrollEventFromIndex == mFirstPosition
-                    && mLastAccessibilityScrollEventToIndex == lastPosition) {
+            final int firstVisiblePosition = getFirstVisiblePosition();
+            final int lastVisiblePosition = getLastVisiblePosition();
+            if (mLastAccessibilityScrollEventFromIndex == firstVisiblePosition
+                    && mLastAccessibilityScrollEventToIndex == lastVisiblePosition) {
                 return;   
             } else {
-                mLastAccessibilityScrollEventFromIndex = mFirstPosition;
-                mLastAccessibilityScrollEventToIndex = lastPosition;       
+                mLastAccessibilityScrollEventFromIndex = firstVisiblePosition;
+                mLastAccessibilityScrollEventToIndex = lastVisiblePosition;
             }
         }
         super.sendAccessibilityEvent(eventType);
     }
 
-    @Override
-    public void onInitializeAccessibilityEvent(AccessibilityEvent event) {
-        super.onInitializeAccessibilityEvent(event);
-        event.setScrollable(true);
-        if (event.getEventType() == AccessibilityEvent.TYPE_VIEW_SCROLLED) {
-            event.setFromIndex(mFirstPosition);
-            event.setToIndex(mFirstPosition +  getChildCount());
-            event.setItemCount(mItemCount);
-        }
-    }
-
     /**
      * Indicates whether the children's drawing cache is used during a scroll.
      * By default, the drawing cache is enabled but this will consume more memory.
diff --git a/core/java/android/widget/AdapterView.java b/core/java/android/widget/AdapterView.java
index 61c5dd4..fd19b5f 100644
--- a/core/java/android/widget/AdapterView.java
+++ b/core/java/android/widget/AdapterView.java
@@ -29,6 +29,7 @@
 import android.view.ViewDebug;
 import android.view.ViewGroup;
 import android.view.accessibility.AccessibilityEvent;
+import android.view.accessibility.AccessibilityNodeInfo;
 
 
 /**
@@ -881,19 +882,10 @@
 
     @Override
     public boolean dispatchPopulateAccessibilityEvent(AccessibilityEvent event) {
-        if (event.getEventType() == AccessibilityEvent.TYPE_VIEW_FOCUSED) {
-            // This is an exceptional case which occurs when a window gets the
-            // focus and sends a focus event via its focused child to announce
-            // current focus/selection. AdapterView fires selection but not focus
-            // events so we change the event type here.
-            if (event.getEventType() == AccessibilityEvent.TYPE_VIEW_FOCUSED) {
-                event.setEventType(AccessibilityEvent.TYPE_VIEW_SELECTED);
-            }
-        }
-
         View selectedView = getSelectedView();
-        if (selectedView != null && selectedView.getVisibility() == VISIBLE) {
-            getSelectedView().dispatchPopulateAccessibilityEvent(event);
+        if (selectedView != null && selectedView.getVisibility() == VISIBLE
+                && selectedView.dispatchPopulateAccessibilityEvent(event)) {
+            return true;
         }
         return false;
     }
@@ -913,19 +905,32 @@
     }
 
     @Override
+    public void onInitializeAccessibilityNodeInfo(AccessibilityNodeInfo info) {
+        super.onInitializeAccessibilityNodeInfo(info);
+        info.setScrollable(isScrollableForAccessibility());
+        View selectedView = getSelectedView();
+        if (selectedView != null) {
+            info.setEnabled(selectedView.isEnabled());
+        }
+    }
+
+    @Override
     public void onInitializeAccessibilityEvent(AccessibilityEvent event) {
         super.onInitializeAccessibilityEvent(event);
-
+        event.setScrollable(isScrollableForAccessibility());
         View selectedView = getSelectedView();
         if (selectedView != null) {
             event.setEnabled(selectedView.isEnabled());
         }
-        event.setItemCount(getCount());
-        event.setCurrentItemIndex(getSelectedItemPosition());
-        if (getChildCount() > 0) {
-            event.setFromIndex(getFirstVisiblePosition());
-            event.setToIndex(getLastVisiblePosition());
-        }
+        event.setFromIndex(getFirstVisiblePosition());
+        event.setToIndex(getLastVisiblePosition());
+        event.setItemCount(getAdapter().getCount());
+    }
+
+    private boolean isScrollableForAccessibility() {
+        final int itemCount = getAdapter().getCount();
+        return itemCount > 0
+            && (getFirstVisiblePosition() > 0 || getLastVisiblePosition() < itemCount - 1);
     }
 
     @Override
diff --git a/core/java/android/widget/Gallery.java b/core/java/android/widget/Gallery.java
index a0eba9a..5e37fa8 100644
--- a/core/java/android/widget/Gallery.java
+++ b/core/java/android/widget/Gallery.java
@@ -32,8 +32,6 @@
 import android.view.View;
 import android.view.ViewConfiguration;
 import android.view.ViewGroup;
-import android.view.accessibility.AccessibilityEvent;
-import android.view.accessibility.AccessibilityNodeInfo;
 import android.view.animation.Transformation;
 
 import com.android.internal.R;
@@ -354,23 +352,6 @@
         return child.getMeasuredHeight();
     }
 
-    @Override
-    public void onInitializeAccessibilityNodeInfo(AccessibilityNodeInfo info) {
-        super.onInitializeAccessibilityNodeInfo(info);
-        info.setScrollable(true);
-    }
-
-    @Override
-    public void onInitializeAccessibilityEvent(AccessibilityEvent event) {
-        super.onInitializeAccessibilityEvent(event);
-        event.setScrollable(true);
-        if (event.getEventType() == AccessibilityEvent.TYPE_VIEW_SCROLLED) {
-            event.setFromIndex(mFirstPosition);
-            event.setToIndex(mFirstPosition +  getChildCount());
-            event.setItemCount(mItemCount);
-        }
-    }
-
     /**
      * Tracks a motion scroll. In reality, this is used to do just about any
      * movement to items (touch scroll, arrow-key scroll, set an item as selected).
diff --git a/core/java/android/widget/HorizontalScrollView.java b/core/java/android/widget/HorizontalScrollView.java
index 324dfd7..57701ae 100644
--- a/core/java/android/widget/HorizontalScrollView.java
+++ b/core/java/android/widget/HorizontalScrollView.java
@@ -716,13 +716,17 @@
     @Override
     public void onInitializeAccessibilityNodeInfo(AccessibilityNodeInfo info) {
         super.onInitializeAccessibilityNodeInfo(info);
-        info.setScrollable(true);
+        info.setScrollable(getScrollRange() > 0);
     }
 
     @Override
     public void onInitializeAccessibilityEvent(AccessibilityEvent event) {
         super.onInitializeAccessibilityEvent(event);
-        event.setScrollable(true);
+        event.setScrollable(getScrollRange() > 0);
+        event.setScrollX(mScrollX);
+        event.setScrollY(mScrollY);
+        event.setMaxScrollX(getScrollRange());
+        event.setMaxScrollY(mScrollY);
     }
 
     private int getScrollRange() {
diff --git a/core/java/android/widget/ListView.java b/core/java/android/widget/ListView.java
index 42e27b1..9ef1aa1 100644
--- a/core/java/android/widget/ListView.java
+++ b/core/java/android/widget/ListView.java
@@ -1997,31 +1997,6 @@
         }
     }
 
-    @Override
-    public void onInitializeAccessibilityEvent(AccessibilityEvent event) {
-        super.onInitializeAccessibilityEvent(event);
-
-        // If the item count is less than 15 then subtract disabled items from the count and
-        // position. Otherwise ignore disabled items.
-        int itemCount = 0;
-        int currentItemIndex = getSelectedItemPosition();
-
-        ListAdapter adapter = getAdapter();
-        if (adapter != null) {
-            final int count = adapter.getCount();
-            for (int i = 0; i < count; i++) {
-                if (adapter.isEnabled(i)) {
-                    itemCount++;
-                } else if (i <= currentItemIndex) {
-                    currentItemIndex--;
-                }
-            }
-        }
-
-        event.setItemCount(itemCount);
-        event.setCurrentItemIndex(currentItemIndex);
-    }
-
     /**
      * setSelectionAfterHeaderView set the selection to be the first list item
      * after the header views.
diff --git a/core/java/android/widget/ScrollView.java b/core/java/android/widget/ScrollView.java
index 3ac4e80..767eaee 100644
--- a/core/java/android/widget/ScrollView.java
+++ b/core/java/android/widget/ScrollView.java
@@ -721,13 +721,18 @@
     @Override
     public void onInitializeAccessibilityNodeInfo(AccessibilityNodeInfo info) {
         super.onInitializeAccessibilityNodeInfo(info);
-        info.setScrollable(true);
+        info.setScrollable(getScrollRange() > 0);
     }
 
     @Override
     public void onInitializeAccessibilityEvent(AccessibilityEvent event) {
         super.onInitializeAccessibilityEvent(event);
-        event.setScrollable(true);
+        final boolean scrollable = getScrollRange() > 0;
+        event.setScrollable(scrollable);
+        event.setScrollX(mScrollX);
+        event.setScrollY(mScrollY);
+        event.setMaxScrollX(mScrollX);
+        event.setMaxScrollY(getScrollRange());
     }
 
     private int getScrollRange() {