Merge "Include important native processes in watchdog stacks." into jb-dev
diff --git a/core/java/android/view/accessibility/AccessibilityNodeInfo.java b/core/java/android/view/accessibility/AccessibilityNodeInfo.java
index 0daf78b..3834fd6 100644
--- a/core/java/android/view/accessibility/AccessibilityNodeInfo.java
+++ b/core/java/android/view/accessibility/AccessibilityNodeInfo.java
@@ -432,8 +432,10 @@
         final int rootAccessibilityViewId =
             (root != null) ? root.getAccessibilityViewId() : UNDEFINED;
         mSourceNodeId = makeNodeId(rootAccessibilityViewId, virtualDescendantId);
-        mActualAndReportedWindowLeftDelta = root.getActualAndReportedWindowLeftDelta();
-        mActualAndReportedWindowTopDelta = root.getActualAndReportedWindowTopDelta();
+        if (root != null) {
+            mActualAndReportedWindowLeftDelta = root.getActualAndReportedWindowLeftDelta();
+            mActualAndReportedWindowTopDelta = root.getActualAndReportedWindowTopDelta();
+        }
     }
 
     /**
diff --git a/core/java/android/widget/AbsListView.java b/core/java/android/widget/AbsListView.java
index c7d0569..19aef8e 100644
--- a/core/java/android/widget/AbsListView.java
+++ b/core/java/android/widget/AbsListView.java
@@ -4305,14 +4305,15 @@
             final int lastPos = firstPos + childCount - 1;
 
             int viewTravelCount;
-            if (position < firstPos) {
-                viewTravelCount = firstPos - position + 1;
+            int clampedPosition = Math.max(0, Math.min(getCount() - 1, position));
+            if (clampedPosition < firstPos) {
+                viewTravelCount = firstPos - clampedPosition + 1;
                 mMode = MOVE_UP_POS;
-            } else if (position > lastPos) {
-                viewTravelCount = position - lastPos + 1;
+            } else if (clampedPosition > lastPos) {
+                viewTravelCount = clampedPosition - lastPos + 1;
                 mMode = MOVE_DOWN_POS;
             } else {
-                scrollToVisible(position, INVALID_POSITION, SCROLL_DURATION);
+                scrollToVisible(clampedPosition, INVALID_POSITION, SCROLL_DURATION);
                 return;
             }
 
@@ -4321,7 +4322,7 @@
             } else {
                 mScrollDuration = SCROLL_DURATION;
             }
-            mTargetPos = position;
+            mTargetPos = clampedPosition;
             mBoundPos = INVALID_POSITION;
             mLastSeenPos = INVALID_POSITION;
 
@@ -4356,14 +4357,15 @@
             final int lastPos = firstPos + childCount - 1;
 
             int viewTravelCount;
-            if (position < firstPos) {
+            int clampedPosition = Math.max(0, Math.min(getCount() - 1, position));
+            if (clampedPosition < firstPos) {
                 final int boundPosFromLast = lastPos - boundPosition;
                 if (boundPosFromLast < 1) {
                     // Moving would shift our bound position off the screen. Abort.
                     return;
                 }
 
-                final int posTravel = firstPos - position + 1;
+                final int posTravel = firstPos - clampedPosition + 1;
                 final int boundTravel = boundPosFromLast - 1;
                 if (boundTravel < posTravel) {
                     viewTravelCount = boundTravel;
@@ -4372,14 +4374,14 @@
                     viewTravelCount = posTravel;
                     mMode = MOVE_UP_POS;
                 }
-            } else if (position > lastPos) {
+            } else if (clampedPosition > lastPos) {
                 final int boundPosFromFirst = boundPosition - firstPos;
                 if (boundPosFromFirst < 1) {
                     // Moving would shift our bound position off the screen. Abort.
                     return;
                 }
 
-                final int posTravel = position - lastPos + 1;
+                final int posTravel = clampedPosition - lastPos + 1;
                 final int boundTravel = boundPosFromFirst - 1;
                 if (boundTravel < posTravel) {
                     viewTravelCount = boundTravel;
@@ -4389,7 +4391,7 @@
                     mMode = MOVE_DOWN_POS;
                 }
             } else {
-                scrollToVisible(position, boundPosition, SCROLL_DURATION);
+                scrollToVisible(clampedPosition, boundPosition, SCROLL_DURATION);
                 return;
             }
 
@@ -4398,7 +4400,7 @@
             } else {
                 mScrollDuration = SCROLL_DURATION;
             }
-            mTargetPos = position;
+            mTargetPos = clampedPosition;
             mBoundPos = boundPosition;
             mLastSeenPos = INVALID_POSITION;
 
@@ -4431,7 +4433,7 @@
 
             offset += getPaddingTop();
 
-            mTargetPos = position;
+            mTargetPos = Math.max(0, Math.min(getCount() - 1, position));
             mOffsetFromTop = offset;
             mBoundPos = INVALID_POSITION;
             mLastSeenPos = INVALID_POSITION;
@@ -4441,13 +4443,13 @@
             final int lastPos = firstPos + childCount - 1;
 
             int viewTravelCount;
-            if (position < firstPos) {
-                viewTravelCount = firstPos - position;
-            } else if (position > lastPos) {
-                viewTravelCount = position - lastPos;
+            if (mTargetPos < firstPos) {
+                viewTravelCount = firstPos - mTargetPos;
+            } else if (mTargetPos > lastPos) {
+                viewTravelCount = mTargetPos - lastPos;
             } else {
                 // On-screen, just scroll.
-                final int targetTop = getChildAt(position - firstPos).getTop();
+                final int targetTop = getChildAt(mTargetPos - firstPos).getTop();
                 smoothScrollBy(targetTop - offset, duration, true);
                 return;
             }
diff --git a/services/java/com/android/server/accessibility/AccessibilityInputFilter.java b/services/java/com/android/server/accessibility/AccessibilityInputFilter.java
index baa2f54..8fa6722 100644
--- a/services/java/com/android/server/accessibility/AccessibilityInputFilter.java
+++ b/services/java/com/android/server/accessibility/AccessibilityInputFilter.java
@@ -123,6 +123,8 @@
     }
 
     public void onAccessibilityEvent(AccessibilityEvent event) {
-        mTouchExplorer.onAccessibilityEvent(event);
+        if (mTouchExplorer != null) {
+            mTouchExplorer.onAccessibilityEvent(event);
+        }
     }
 }
diff --git a/services/java/com/android/server/accessibility/AccessibilityManagerService.java b/services/java/com/android/server/accessibility/AccessibilityManagerService.java
index 9399fe9..e42ec84 100644
--- a/services/java/com/android/server/accessibility/AccessibilityManagerService.java
+++ b/services/java/com/android/server/accessibility/AccessibilityManagerService.java
@@ -113,6 +113,8 @@
 
     private static final int MSG_TOGGLE_TOUCH_EXPLORATION = 2;
 
+    private static final int MSG_SEND_ACCESSIBILITY_EVENT_TO_INPUT_FILTER = 3;
+
     private static int sIdCounter = 0;
 
     private static int sNextWindowId;
@@ -402,7 +404,9 @@
                 notifyAccessibilityServicesDelayedLocked(event, true);
             }
             if (mHasInputFilter && mInputFilter != null) {
-                mInputFilter.onAccessibilityEvent(event);
+                mMainHandler.obtainMessage(MSG_SEND_ACCESSIBILITY_EVENT_TO_INPUT_FILTER,
+                        AccessibilityEvent.obtain(event)).sendToTarget();
+
             }
             event.recycle();
             mHandledFeedbackTypes = 0;
@@ -1104,7 +1108,14 @@
                         mEnableTouchExplorationDialog.setCanceledOnTouchOutside(true);
                         mEnableTouchExplorationDialog.show();
                     }
-                }
+                } break;
+                case MSG_SEND_ACCESSIBILITY_EVENT_TO_INPUT_FILTER: {
+                    AccessibilityEvent event = (AccessibilityEvent) msg.obj;
+                    if (mHasInputFilter && mInputFilter != null) {
+                        mInputFilter.onAccessibilityEvent(event);
+                    }
+                    event.recycle();
+                } break;
             }
         }
     }