Removing hierarchical accessibility focus directions.

1. The accessibility focus directions are not needed since an
   accessibility service just get the root, first child, next
   sibling, previous sibling and call execute the action to
   give it accessibility focus. Now the accessibility node
   info tree is properly ordered taking into account layout
   manager directions for both layout manager that we report
   and ones that we have determined as not important for
   accessibility. Also the position of a node info are ordered
   properly based on their coordinates after all transformations
   as opposed to child index.

bug:5932640

Change-Id: I994a8297cb1e57c829ecbac73a937c2bcbe0bac7
diff --git a/api/current.txt b/api/current.txt
index 2025aa7..981d465 100644
--- a/api/current.txt
+++ b/api/current.txt
@@ -24080,11 +24080,7 @@
     field public static final int ACCESSIBILITY_FOCUS_BACKWARD = 4097; // 0x1001
     field public static final int ACCESSIBILITY_FOCUS_DOWN = 4226; // 0x1082
     field public static final int ACCESSIBILITY_FOCUS_FORWARD = 4098; // 0x1002
-    field public static final int ACCESSIBILITY_FOCUS_IN = 4100; // 0x1004
     field public static final int ACCESSIBILITY_FOCUS_LEFT = 4113; // 0x1011
-    field public static final int ACCESSIBILITY_FOCUS_NEXT = 4112; // 0x1010
-    field public static final int ACCESSIBILITY_FOCUS_OUT = 4104; // 0x1008
-    field public static final int ACCESSIBILITY_FOCUS_PREVIOUS = 4128; // 0x1020
     field public static final int ACCESSIBILITY_FOCUS_RIGHT = 4162; // 0x1042
     field public static final int ACCESSIBILITY_FOCUS_UP = 4129; // 0x1021
     field public static final android.util.Property ALPHA;
diff --git a/core/java/android/view/AccessibilityInteractionController.java b/core/java/android/view/AccessibilityInteractionController.java
index 7d569ad..6387148 100644
--- a/core/java/android/view/AccessibilityInteractionController.java
+++ b/core/java/android/view/AccessibilityInteractionController.java
@@ -662,29 +662,31 @@
                 ViewGroup parentGroup = (ViewGroup) parent;
                 ChildListForAccessibility children = ChildListForAccessibility.obtain(parentGroup,
                         false);
-                final int childCount = children.getChildCount();
-                for (int i = 0; i < childCount; i++) {
-                    if (outInfos.size() >= MAX_ACCESSIBILITY_NODE_INFO_BATCH_SIZE) {
-                        children.recycle();
-                        return;
-                    }
-                    View child = children.getChildAt(i);
-                    if (child.getAccessibilityViewId() != current.getAccessibilityViewId()
-                            &&  child.isDisplayedOnScreen()) {
-                        AccessibilityNodeInfo info = null;
-                        AccessibilityNodeProvider provider = child.getAccessibilityNodeProvider();
-                        if (provider == null) {
-                            info = child.createAccessibilityNodeInfo();
-                        } else {
-                            info = provider.createAccessibilityNodeInfo(
-                                    AccessibilityNodeInfo.UNDEFINED);
+                try {
+                    final int childCount = children.getChildCount();
+                    for (int i = 0; i < childCount; i++) {
+                        if (outInfos.size() >= MAX_ACCESSIBILITY_NODE_INFO_BATCH_SIZE) {
+                            return;
                         }
-                        if (info != null) {
-                            outInfos.add(info);
+                        View child = children.getChildAt(i);
+                        if (child.getAccessibilityViewId() != current.getAccessibilityViewId()
+                                &&  child.isDisplayedOnScreen()) {
+                            AccessibilityNodeInfo info = null;
+                            AccessibilityNodeProvider provider = child.getAccessibilityNodeProvider();
+                            if (provider == null) {
+                                info = child.createAccessibilityNodeInfo();
+                            } else {
+                                info = provider.createAccessibilityNodeInfo(
+                                        AccessibilityNodeInfo.UNDEFINED);
+                            }
+                            if (info != null) {
+                                outInfos.add(info);
+                            }
                         }
                     }
+                } finally {
+                    children.recycle();
                 }
-                children.recycle();
             }
         }
 
@@ -697,32 +699,34 @@
             HashMap<View, AccessibilityNodeInfo> addedChildren =
                 new HashMap<View, AccessibilityNodeInfo>();
             ChildListForAccessibility children = ChildListForAccessibility.obtain(rootGroup, false);
-            final int childCount = children.getChildCount();
-            for (int i = 0; i < childCount; i++) {
-                if (outInfos.size() >= MAX_ACCESSIBILITY_NODE_INFO_BATCH_SIZE) {
-                    children.recycle();
-                    return;
-                }
-                View child = children.getChildAt(i);
-                if (child.isDisplayedOnScreen()) {
-                    AccessibilityNodeProvider provider = child.getAccessibilityNodeProvider();
-                    if (provider == null) {
-                        AccessibilityNodeInfo info = child.createAccessibilityNodeInfo();
-                        if (info != null) {
-                            outInfos.add(info);
-                            addedChildren.put(child, null);
-                        }
-                    } else {
-                        AccessibilityNodeInfo info = provider.createAccessibilityNodeInfo(
-                               AccessibilityNodeInfo.UNDEFINED);
-                        if (info != null) {
-                            outInfos.add(info);
-                            addedChildren.put(child, info);
+            try {
+                final int childCount = children.getChildCount();
+                for (int i = 0; i < childCount; i++) {
+                    if (outInfos.size() >= MAX_ACCESSIBILITY_NODE_INFO_BATCH_SIZE) {
+                        return;
+                    }
+                    View child = children.getChildAt(i);
+                    if (child.isDisplayedOnScreen()) {
+                        AccessibilityNodeProvider provider = child.getAccessibilityNodeProvider();
+                        if (provider == null) {
+                            AccessibilityNodeInfo info = child.createAccessibilityNodeInfo();
+                            if (info != null) {
+                                outInfos.add(info);
+                                addedChildren.put(child, null);
+                            }
+                        } else {
+                            AccessibilityNodeInfo info = provider.createAccessibilityNodeInfo(
+                                   AccessibilityNodeInfo.UNDEFINED);
+                            if (info != null) {
+                                outInfos.add(info);
+                                addedChildren.put(child, info);
+                            }
                         }
                     }
                 }
+            } finally {
+                children.recycle();
             }
-            children.recycle();
             if (outInfos.size() < MAX_ACCESSIBILITY_NODE_INFO_BATCH_SIZE) {
                 for (Map.Entry<View, AccessibilityNodeInfo> entry : addedChildren.entrySet()) {
                     View addedChild = entry.getKey();
diff --git a/core/java/android/view/FocusFinder.java b/core/java/android/view/FocusFinder.java
index 8a01c15..98375ae 100644
--- a/core/java/android/view/FocusFinder.java
+++ b/core/java/android/view/FocusFinder.java
@@ -17,12 +17,10 @@
 package android.view;
 
 import android.graphics.Rect;
-import android.view.ViewGroup.ChildListForAccessibility;
 
 import java.util.ArrayList;
 import java.util.Collections;
 import java.util.Comparator;
-import java.util.Stack;
 
 /**
  * The algorithm used for finding the next focusable view in a given direction
@@ -30,7 +28,7 @@
  */
 public class FocusFinder {
 
-    private static ThreadLocal<FocusFinder> tlFocusFinder =
+    private static final ThreadLocal<FocusFinder> tlFocusFinder =
             new ThreadLocal<FocusFinder>() {
                 @Override
                 protected FocusFinder initialValue() {
@@ -45,15 +43,13 @@
         return tlFocusFinder.get();
     }
 
-    Rect mFocusedRect = new Rect();
-    Rect mOtherRect = new Rect();
-    Rect mBestCandidateRect = new Rect();
-    SequentialFocusComparator mSequentialFocusComparator = new SequentialFocusComparator();
+    final Rect mFocusedRect = new Rect();
+    final Rect mOtherRect = new Rect();
+    final Rect mBestCandidateRect = new Rect();
+    final SequentialFocusComparator mSequentialFocusComparator = new SequentialFocusComparator();
 
     private final ArrayList<View> mTempList = new ArrayList<View>();
 
-    private Stack<View> mTempStack;
-
     // enforce thread local access
     private FocusFinder() {}
 
@@ -78,149 +74,116 @@
      * @return The next focusable view, or null if none exists.
      */
     public View findNextFocusFromRect(ViewGroup root, Rect focusedRect, int direction) {
-        return findNextFocus(root, null, focusedRect, direction);
+        mFocusedRect.set(focusedRect);
+        return findNextFocus(root, null, mFocusedRect, direction);
     }
 
     private View findNextFocus(ViewGroup root, View focused, Rect focusedRect, int direction) {
         if ((direction & View.FOCUS_ACCESSIBILITY) != View.FOCUS_ACCESSIBILITY) {
             return findNextInputFocus(root, focused, focusedRect, direction);
         } else {
-            return findNextAccessibilityFocus(root, focused, direction);
+            return findNextAccessibilityFocus(root, focused, focusedRect, direction);
         }
     }
 
     private View findNextInputFocus(ViewGroup root, View focused, Rect focusedRect, int direction) {
+        View next = null;
         if (focused != null) {
-            // check for user specified next focus
-            View userSetNextFocus = focused.findUserSetNextFocus(root, direction);
-            if (userSetNextFocus != null &&
-                userSetNextFocus.isFocusable() &&
-                (!userSetNextFocus.isInTouchMode() ||
-                 userSetNextFocus.isFocusableInTouchMode())) {
-                return userSetNextFocus;
+            next = findNextUserSpecifiedInputFocus(root, focused, direction);
+        }
+        if (next != null) {
+            return next;
+        }
+        ArrayList<View> focusables = mTempList;
+        try {
+            focusables.clear();
+            root.addFocusables(focusables, direction);
+            if (!focusables.isEmpty()) {
+                next = findNextFocus(root, focused, focusedRect, direction, focusables);
             }
+        } finally {
+            focusables.clear();
+        }
+        return next;
+    }
 
+    private View findNextUserSpecifiedInputFocus(ViewGroup root, View focused, int direction) {
+        // check for user specified next focus
+        View userSetNextFocus = focused.findUserSetNextFocus(root, direction);
+        if (userSetNextFocus != null && userSetNextFocus.isFocusable()
+                && (!userSetNextFocus.isInTouchMode()
+                        || userSetNextFocus.isFocusableInTouchMode())) {
+            return userSetNextFocus;
+        }
+        return null;
+    }
+
+    private View findNextFocus(ViewGroup root, View focused, Rect focusedRect,
+            int direction, ArrayList<View> focusables) {
+        final int directionMasked = (direction & ~View.FOCUS_ACCESSIBILITY);
+        if (focused != null) {
             // fill in interesting rect from focused
-            focused.getFocusedRect(mFocusedRect);
-            root.offsetDescendantRectToMyCoords(focused, mFocusedRect);
+            focused.getFocusedRect(focusedRect);
+            root.offsetDescendantRectToMyCoords(focused, focusedRect);
         } else {
             // make up a rect at top left or bottom right of root
-            switch (direction) {
+            switch (directionMasked) {
                 case View.FOCUS_RIGHT:
                 case View.FOCUS_DOWN:
-                    setFocusTopLeft(root);
+                    setFocusTopLeft(root, focusedRect);
                     break;
                 case View.FOCUS_FORWARD:
                     if (root.isLayoutRtl()) {
-                        setFocusBottomRight(root);
+                        setFocusBottomRight(root, focusedRect);
                     } else {
-                        setFocusTopLeft(root);
+                        setFocusTopLeft(root, focusedRect);
                     }
                     break;
 
                 case View.FOCUS_LEFT:
                 case View.FOCUS_UP:
-                    setFocusBottomRight(root);
+                    setFocusBottomRight(root, focusedRect);
                     break;
                 case View.FOCUS_BACKWARD:
                     if (root.isLayoutRtl()) {
-                        setFocusTopLeft(root);
+                        setFocusTopLeft(root, focusedRect);
                     } else {
-                        setFocusBottomRight(root);
+                        setFocusBottomRight(root, focusedRect);
                     break;
                 }
             }
         }
 
-        ArrayList<View> focusables = mTempList;
-        focusables.clear();
-        root.addFocusables(focusables, direction);
-        if (focusables.isEmpty()) {
-            // The focus cannot change.
-            return null;
+        switch (directionMasked) {
+            case View.FOCUS_FORWARD:
+            case View.FOCUS_BACKWARD:
+                return findNextInputFocusInRelativeDirection(focusables, root, focused, focusedRect,
+                        directionMasked);
+            case View.FOCUS_UP:
+            case View.FOCUS_DOWN:
+            case View.FOCUS_LEFT:
+            case View.FOCUS_RIGHT:
+                return findNextInputFocusInAbsoluteDirection(focusables, root, focused,
+                        focusedRect, directionMasked);
+            default:
+                throw new IllegalArgumentException("Unknown direction: " + directionMasked);
         }
+    }
 
+    private View findNextAccessibilityFocus(ViewGroup root, View focused,
+            Rect focusedRect, int direction) {
+        ArrayList<View> focusables = mTempList;
         try {
-            switch (direction) {
-                case View.FOCUS_FORWARD:
-                case View.FOCUS_BACKWARD:
-                    return findNextInputFocusInRelativeDirection(focusables, root, focused,
-                            focusedRect, direction);
-                case View.FOCUS_UP:
-                case View.FOCUS_DOWN:
-                case View.FOCUS_LEFT:
-                case View.FOCUS_RIGHT:
-                    return findNextInputFocusInAbsoluteDirection(focusables, root, focused,
-                            focusedRect, direction);
-                default:
-                    throw new IllegalArgumentException("Unknown direction: " + direction);
-            }
+            focusables.clear();
+            root.addFocusables(focusables, direction, View.FOCUSABLES_ACCESSIBILITY);
+            View next = findNextFocus(root, focused, focusedRect, direction,
+                    focusables);
+            return next;
         } finally {
             focusables.clear();
         }
     }
 
-    /**
-     * Find the next view to take accessibility focus in root's descendants,
-     * starting from the view that currently is accessibility focused.
-     *
-     * @param root The root which also contains the focused view.
-     * @param focused The current accessibility focused view.
-     * @param direction Direction to look.
-     * @return The next focusable view, or null if none exists.
-     */
-    private View findNextAccessibilityFocus(ViewGroup root, View focused, int direction) {
-        switch (direction) {
-            case View.ACCESSIBILITY_FOCUS_IN:
-            case View.ACCESSIBILITY_FOCUS_OUT:
-            case View.ACCESSIBILITY_FOCUS_FORWARD:
-            case View.ACCESSIBILITY_FOCUS_BACKWARD: {
-                return findNextHierarchicalAcessibilityFocus(root, focused, direction);
-            }
-            case View.ACCESSIBILITY_FOCUS_LEFT:
-            case View.ACCESSIBILITY_FOCUS_RIGHT:
-            case View.ACCESSIBILITY_FOCUS_UP:
-            case View.ACCESSIBILITY_FOCUS_DOWN: {
-                return findNextDirectionalAccessibilityFocus(root, focused, direction);
-            }
-            default:
-                throw new IllegalArgumentException("Unknown direction: " + direction);
-        }
-    }
-
-    private View findNextHierarchicalAcessibilityFocus(ViewGroup root, View focused,
-            int direction) {
-        View current = (focused != null) ? focused : root;
-        switch (direction) {
-            case View.ACCESSIBILITY_FOCUS_IN: {
-                return findNextAccessibilityFocusIn(current);
-            }
-            case View.ACCESSIBILITY_FOCUS_OUT: {
-                return findNextAccessibilityFocusOut(current);
-            }
-            case View.ACCESSIBILITY_FOCUS_FORWARD: {
-                return findNextAccessibilityFocusForward(current);
-            }
-            case View.ACCESSIBILITY_FOCUS_BACKWARD: {
-                return findNextAccessibilityFocusBackward(current);
-            }
-        }
-        return null;
-    }
-
-    private View findNextDirectionalAccessibilityFocus(ViewGroup root, View focused,
-            int direction) {
-        ArrayList<View> focusables = mTempList;
-        focusables.clear();
-        root.addFocusables(focusables, direction, View.FOCUSABLES_ACCESSIBILITY);
-        Rect focusedRect = getFocusedRect(root, focused, direction);
-        final int inputFocusDirection = getCorrespondingInputFocusDirection(direction);
-        View next = findNextInputFocusInAbsoluteDirection(focusables, root,
-                focused, focusedRect, inputFocusDirection);
-        focusables.clear();
-        return next;
-    }
-
     private View findNextInputFocusInRelativeDirection(ArrayList<View> focusables, ViewGroup root,
             View focused, Rect focusedRect, int direction) {
         try {
@@ -241,17 +204,16 @@
         return focusables.get(count - 1);
     }
 
-    private void setFocusBottomRight(ViewGroup root) {
+    private void setFocusBottomRight(ViewGroup root, Rect focusedRect) {
         final int rootBottom = root.getScrollY() + root.getHeight();
         final int rootRight = root.getScrollX() + root.getWidth();
-        mFocusedRect.set(rootRight, rootBottom,
-                rootRight, rootBottom);
+        focusedRect.set(rootRight, rootBottom, rootRight, rootBottom);
     }
 
-    private void setFocusTopLeft(ViewGroup root) {
+    private void setFocusTopLeft(ViewGroup root, Rect focusedRect) {
         final int rootTop = root.getScrollY();
         final int rootLeft = root.getScrollX();
-        mFocusedRect.set(rootLeft, rootTop, rootLeft, rootTop);
+        focusedRect.set(rootLeft, rootTop, rootLeft, rootTop);
     }
 
     View findNextInputFocusInAbsoluteDirection(ArrayList<View> focusables, ViewGroup root, View focused,
@@ -294,140 +256,6 @@
         return closest;
     }
 
-    private View findNextAccessibilityFocusIn(View view) {
-        // We have to traverse the full view tree to make sure
-        // we consider views in the order specified by their
-        // parent layout managers since some managers could be
-        // LTR while some could be RTL.
-        if (mTempStack == null) {
-            mTempStack = new Stack<View>();
-        }
-        Stack<View> fringe = mTempStack;
-        fringe.clear();
-        fringe.add(view);
-        while (!fringe.isEmpty()) {
-            View current = fringe.pop();
-            if (current.getAccessibilityNodeProvider() != null) {
-                fringe.clear();
-                return current;
-            }
-            if (current != view && current.includeForAccessibility()) {
-                fringe.clear();
-                return current;
-            }
-            if (current instanceof ViewGroup) {
-                ViewGroup currentGroup = (ViewGroup) current;
-                ChildListForAccessibility children = ChildListForAccessibility.obtain(
-                        currentGroup, true);
-                final int childCount = children.getChildCount();
-                for (int i = childCount - 1; i >= 0; i--) {
-                    fringe.push(children.getChildAt(i));
-                }
-                children.recycle();
-            }
-        }
-        return null;
-    }
-
-    private View findNextAccessibilityFocusOut(View view) {
-        ViewParent parent = view.getParentForAccessibility();
-        if (parent instanceof View) {
-            return (View) parent;
-        }
-        return null;
-    }
-
-    private View findNextAccessibilityFocusForward(View view) {
-        // We have to traverse the full view tree to make sure
-        // we consider views in the order specified by their
-        // parent layout managers since some managers could be
-        // LTR while some could be RTL.
-        View current = view;
-        while (current != null) {
-            ViewParent parent = current.getParent();
-            if (!(parent instanceof ViewGroup)) {
-                return null;
-            }
-            ViewGroup parentGroup = (ViewGroup) parent;
-            // Ask the parent to find a sibling after the current view
-            // that can take accessibility focus.
-            ChildListForAccessibility children = ChildListForAccessibility.obtain(
-                    parentGroup, true);
-            final int fromIndex = children.getChildIndex(current) + 1;
-            final int childCount = children.getChildCount();
-            for (int i = fromIndex; i < childCount; i++) {
-                View child = children.getChildAt(i);
-                View next = null;
-                if (child.getAccessibilityNodeProvider() != null) {
-                    next = child;
-                } else if (child.includeForAccessibility()) {
-                    next = child;
-                } else {
-                    next = findNextAccessibilityFocusIn(child);
-                }
-                if (next != null) {
-                    children.recycle();
-                    return next;
-                }
-            }
-            children.recycle();
-            // Reaching a regarded for accessibility predecessor without
-            // finding a next view to take focus means that at this level
-            // there is no next accessibility focusable sibling.
-            if (parentGroup.includeForAccessibility()) {
-                return null;
-            }
-            // Try asking a predecessor to find a focusable.
-            current = parentGroup;
-        }
-        return null;
-    }
-
-    private View findNextAccessibilityFocusBackward(View view) {
-        // We have to traverse the full view tree to make sure
-        // we consider views in the order specified by their
-        // parent layout managers since some managers could be
-        // LTR while some could be RTL.
-        View current = view;
-        while (current != null) {
-            ViewParent parent = current.getParent();
-            if (!(parent instanceof ViewGroup)) {
-                return null;
-            }
-            ViewGroup parentGroup = (ViewGroup) parent;
-            // Ask the parent to find a sibling after the current view
-            // to take accessibility focus
-            ChildListForAccessibility children = ChildListForAccessibility.obtain(
-                    parentGroup, true);
-            final int fromIndex = children.getChildIndex(current) - 1;
-            for (int i = fromIndex; i >= 0; i--) {
-                View child = children.getChildAt(i);
-                View next = null;
-                if (child.getAccessibilityNodeProvider() != null) {
-                    next = child;
-                } else if (child.includeForAccessibility()) {
-                    next = child;
-                } else {
-                    next = findNextAccessibilityFocusIn(child);
-                }
-                if (next != null) {
-                    children.recycle();
-                    return next;
-                }
-            }
-            children.recycle();
-            // Reaching a regarded for accessibility predecessor without
-            // finding a previous view to take focus means that at this level
-            // there is no previous accessibility focusable sibling.
-            if (parentGroup.includeForAccessibility()) {
-                return null;
-            }
-            // Try asking a predecessor to find a focusable.
-            current = parentGroup;
-        }
-        return null;
-    }
-
     private static View getForwardFocusable(ViewGroup root, View focused,
                                             ArrayList<View> focusables, int count) {
         return (root.isLayoutRtl()) ?
@@ -462,47 +290,6 @@
         return focusables.get(count - 1);
     }
 
-    private Rect getFocusedRect(ViewGroup root, View focused, int direction) {
-        Rect focusedRect = mFocusedRect;
-        if (focused != null) {
-            focused.getFocusedRect(focusedRect);
-            root.offsetDescendantRectToMyCoords(focused, focusedRect);
-        } else {
-            switch (direction) {
-                case View.FOCUS_RIGHT:
-                case View.FOCUS_DOWN:
-                    final int rootTop = root.getScrollY();
-                    final int rootLeft = root.getScrollX();
-                    focusedRect.set(rootLeft, rootTop, rootLeft, rootTop);
-                    break;
-
-                case View.FOCUS_LEFT:
-                case View.FOCUS_UP:
-                    final int rootBottom = root.getScrollY() + root.getHeight();
-                    final int rootRight = root.getScrollX() + root.getWidth();
-                    focusedRect.set(rootRight, rootBottom, rootRight, rootBottom);
-                    break;
-            }
-        }
-        return focusedRect;
-    }
-
-    private int getCorrespondingInputFocusDirection(int accessFocusDirection) {
-        switch (accessFocusDirection) {
-            case View.ACCESSIBILITY_FOCUS_LEFT:
-                return View.FOCUS_LEFT;
-            case View.ACCESSIBILITY_FOCUS_RIGHT:
-                return View.FOCUS_RIGHT;
-            case View.ACCESSIBILITY_FOCUS_UP:
-                return View.FOCUS_UP;
-            case View.ACCESSIBILITY_FOCUS_DOWN:
-                return View.FOCUS_DOWN;
-            default:
-                throw new IllegalArgumentException("Cannot map accessiblity focus"
-                        + " direction: " + accessFocusDirection);
-        }
-    }
-
     /**
      * Is rect1 a better candidate than rect2 for a focus search in a particular
      * direction from a source rect?  This is the core routine that determines
diff --git a/core/java/android/view/View.java b/core/java/android/view/View.java
index a833cbe..39f5129 100644
--- a/core/java/android/view/View.java
+++ b/core/java/android/view/View.java
@@ -1055,26 +1055,6 @@
     public static final int ACCESSIBILITY_FOCUS_BACKWARD = FOCUS_BACKWARD | FOCUS_ACCESSIBILITY;
 
     /**
-     * Use with {@link #focusSearch(int)}. Move acessibility focus in a view.
-     */
-    public static final int ACCESSIBILITY_FOCUS_IN = 0x00000004 | FOCUS_ACCESSIBILITY;
-
-    /**
-     * Use with {@link #focusSearch(int)}. Move acessibility focus out of a view.
-     */
-    public static final int ACCESSIBILITY_FOCUS_OUT = 0x00000008 | FOCUS_ACCESSIBILITY;
-
-    /**
-     * Use with {@link #focusSearch(int)}. Move acessibility focus to the next view.
-     */
-    public static final int ACCESSIBILITY_FOCUS_NEXT = 0x00000010 | FOCUS_ACCESSIBILITY;
-
-    /**
-     * Use with {@link #focusSearch(int)}. Move acessibility focus to the previous view.
-     */
-    public static final int ACCESSIBILITY_FOCUS_PREVIOUS = 0x00000020 | FOCUS_ACCESSIBILITY;
-
-    /**
      * Bits of {@link #getMeasuredWidthAndState()} and
      * {@link #getMeasuredWidthAndState()} that provide the actual measured size.
      */
diff --git a/core/java/android/view/ViewGroup.java b/core/java/android/view/ViewGroup.java
index 8c8711c..267e3b3 100644
--- a/core/java/android/view/ViewGroup.java
+++ b/core/java/android/view/ViewGroup.java
@@ -1614,18 +1614,22 @@
 
     @Override
     public void addChildrenForAccessibility(ArrayList<View> childrenForAccessibility) {
-        View[] children = mChildren;
-        final int childrenCount = mChildrenCount;
-        for (int i = 0; i < childrenCount; i++) {
-            View child = children[i];
-            if ((child.mViewFlags & VISIBILITY_MASK) == VISIBLE
-                    && (child.mPrivateFlags & IS_ROOT_NAMESPACE) == 0) {
-                if (child.includeForAccessibility()) {
-                    childrenForAccessibility.add(child);
-                } else {
-                    child.addChildrenForAccessibility(childrenForAccessibility);
+        ChildListForAccessibility children = ChildListForAccessibility.obtain(this, true);
+        try {
+            final int childrenCount = children.getChildCount();
+            for (int i = 0; i < childrenCount; i++) {
+                View child = children.getChildAt(i);
+                if ((child.mViewFlags & VISIBILITY_MASK) == VISIBLE
+                        && (child.mPrivateFlags & IS_ROOT_NAMESPACE) == 0) {
+                    if (child.includeForAccessibility()) {
+                        childrenForAccessibility.add(child);
+                    } else {
+                        child.addChildrenForAccessibility(childrenForAccessibility);
+                    }
                 }
             }
+        } finally {
+            children.recycle();
         }
     }
 
@@ -2416,18 +2420,21 @@
         }
         // Let our children have a shot in populating the event.
         ChildListForAccessibility children = ChildListForAccessibility.obtain(this, true);
-        final int childCount = children.getChildCount();
-        for (int i = 0; i < childCount; i++) {
-            View child = children.getChildAt(i);
-            if ((child.mViewFlags & VISIBILITY_MASK) == VISIBLE) {
-                handled = child.dispatchPopulateAccessibilityEvent(event);
-                if (handled) {
-                    children.recycle();
-                    return handled;
+        try {
+            final int childCount = children.getChildCount();
+            for (int i = 0; i < childCount; i++) {
+                View child = children.getChildAt(i);
+                if ((child.mViewFlags & VISIBILITY_MASK) == VISIBLE) {
+                    handled = child.dispatchPopulateAccessibilityEvent(event);
+                    if (handled) {
+                        children.recycle();
+                        return handled;
+                    }
                 }
             }
+        } finally {
+            children.recycle();
         }
-        children.recycle();
         return false;
     }
 
diff --git a/core/java/android/view/accessibility/AccessibilityNodeInfo.java b/core/java/android/view/accessibility/AccessibilityNodeInfo.java
index cdb9e77..3cb3b54 100644
--- a/core/java/android/view/accessibility/AccessibilityNodeInfo.java
+++ b/core/java/android/view/accessibility/AccessibilityNodeInfo.java
@@ -391,8 +391,6 @@
      *     {@link View#FOCUS_RIGHT},
      *     {@link View#FOCUS_FORWARD},
      *     {@link View#FOCUS_BACKWARD},
-     *     {@link View#ACCESSIBILITY_FOCUS_IN},
-     *     {@link View#ACCESSIBILITY_FOCUS_OUT},
      *     {@link View#ACCESSIBILITY_FOCUS_FORWARD},
      *     {@link View#ACCESSIBILITY_FOCUS_BACKWARD},
      *     {@link View#ACCESSIBILITY_FOCUS_UP},
diff --git a/core/java/android/view/accessibility/AccessibilityNodeProvider.java b/core/java/android/view/accessibility/AccessibilityNodeProvider.java
index ba6433f..a2e0d88 100644
--- a/core/java/android/view/accessibility/AccessibilityNodeProvider.java
+++ b/core/java/android/view/accessibility/AccessibilityNodeProvider.java
@@ -168,8 +168,6 @@
      *
      * @param direction The direction in which to search for a focus candidate.
      *     Values are
-     *     {@link View#ACCESSIBILITY_FOCUS_IN},
-     *     {@link View#ACCESSIBILITY_FOCUS_OUT},
      *     {@link View#ACCESSIBILITY_FOCUS_FORWARD},
      *     {@link View#ACCESSIBILITY_FOCUS_BACKWARD},
      *     {@link View#ACCESSIBILITY_FOCUS_UP},
diff --git a/services/java/com/android/server/accessibility/AccessibilityManagerService.java b/services/java/com/android/server/accessibility/AccessibilityManagerService.java
index e980ccc..b9404f3 100644
--- a/services/java/com/android/server/accessibility/AccessibilityManagerService.java
+++ b/services/java/com/android/server/accessibility/AccessibilityManagerService.java
@@ -1149,10 +1149,10 @@
             AccessibilityNodeInfo next = null;
             switch (gestureId) {
                 case AccessibilityService.GESTURE_SWIPE_UP: {
-                    next = current.focusSearch(View.ACCESSIBILITY_FOCUS_OUT);
+                    // TODO:
                 } break;
                 case AccessibilityService.GESTURE_SWIPE_DOWN: {
-                    next = current.focusSearch(View.ACCESSIBILITY_FOCUS_IN);
+                    // TODO:
                 } break;
                 case AccessibilityService.GESTURE_SWIPE_LEFT: {
                     // TODO: Implement the RTL support.
@@ -1694,6 +1694,7 @@
     final class SecurityPolicy {
         private static final int VALID_ACTIONS =
             AccessibilityNodeInfo.ACTION_CLICK
+            | AccessibilityNodeInfo.ACTION_LONG_CLICK
             | AccessibilityNodeInfo.ACTION_FOCUS
             | AccessibilityNodeInfo.ACTION_CLEAR_FOCUS
             | AccessibilityNodeInfo.ACTION_SELECT