am ec7c7ebf: Merge "API for finding accessibility focus in virtual tree not needed." into jb-dev

* commit 'ec7c7ebf01121d17f7a12e827bd77c024eab54e8':
  API for finding accessibility focus in virtual tree not needed.
diff --git a/api/16.txt b/api/16.txt
index e67292e..70c4032 100644
--- a/api/16.txt
+++ b/api/16.txt
@@ -25344,7 +25344,6 @@
   public abstract class AccessibilityNodeProvider {
     ctor public AccessibilityNodeProvider();
     method public android.view.accessibility.AccessibilityNodeInfo createAccessibilityNodeInfo(int);
-    method public android.view.accessibility.AccessibilityNodeInfo findAccessibilityFocus(int);
     method public java.util.List<android.view.accessibility.AccessibilityNodeInfo> findAccessibilityNodeInfosByText(java.lang.String, int);
     method public boolean performAction(int, int, android.os.Bundle);
   }
diff --git a/api/current.txt b/api/current.txt
index 1ee52b8..308e4d4 100644
--- a/api/current.txt
+++ b/api/current.txt
@@ -25354,7 +25354,6 @@
   public abstract class AccessibilityNodeProvider {
     ctor public AccessibilityNodeProvider();
     method public android.view.accessibility.AccessibilityNodeInfo createAccessibilityNodeInfo(int);
-    method public android.view.accessibility.AccessibilityNodeInfo findAccessibilityFocus(int);
     method public java.util.List<android.view.accessibility.AccessibilityNodeInfo> findAccessibilityNodeInfosByText(java.lang.String, int);
     method public boolean performAction(int, int, android.os.Bundle);
   }
diff --git a/core/java/android/view/AccessibilityInteractionController.java b/core/java/android/view/AccessibilityInteractionController.java
index 29926ca..0aabc44 100644
--- a/core/java/android/view/AccessibilityInteractionController.java
+++ b/core/java/android/view/AccessibilityInteractionController.java
@@ -480,7 +480,10 @@
                         // focus instead fetching all provider nodes to do the search here.
                         AccessibilityNodeProvider provider = host.getAccessibilityNodeProvider();
                         if (provider != null) {
-                            focused = provider.findAccessibilityFocus(virtualDescendantId);
+                            if (mViewRootImpl.mAccessibilityFocusedVirtualView != null) {
+                                focused = AccessibilityNodeInfo.obtain(
+                                        mViewRootImpl.mAccessibilityFocusedVirtualView);
+                            }
                         } else if (virtualDescendantId == View.NO_ID) {
                             focused = host.createAccessibilityNodeInfo();
                         }
@@ -804,7 +807,6 @@
             if (!(root instanceof ViewGroup)) {
                 return;
             }
-            ViewGroup rootGroup = (ViewGroup) root;
             HashMap<View, AccessibilityNodeInfo> addedChildren =
                 new HashMap<View, AccessibilityNodeInfo>();
             ArrayList<View> children = mTempViewList;
diff --git a/core/java/android/view/View.java b/core/java/android/view/View.java
index db3ba40..b1caa2f 100644
--- a/core/java/android/view/View.java
+++ b/core/java/android/view/View.java
@@ -4558,31 +4558,6 @@
         if ((event.getEventType() & POPULATING_ACCESSIBILITY_EVENT_TYPES) != 0) {
             dispatchPopulateAccessibilityEvent(event);
         }
-        // Intercept accessibility focus events fired by virtual nodes to keep
-        // track of accessibility focus position in such nodes.
-        final int eventType = event.getEventType();
-        switch (eventType) {
-            case AccessibilityEvent.TYPE_VIEW_ACCESSIBILITY_FOCUSED: {
-                final long virtualNodeId = AccessibilityNodeInfo.getVirtualDescendantId(
-                        event.getSourceNodeId());
-                if (virtualNodeId != AccessibilityNodeInfo.UNDEFINED) {
-                    ViewRootImpl viewRootImpl = getViewRootImpl();
-                    if (viewRootImpl != null) {
-                        viewRootImpl.setAccessibilityFocusedHost(this);
-                    }
-                }
-            } break;
-            case AccessibilityEvent.TYPE_VIEW_ACCESSIBILITY_FOCUS_CLEARED: {
-                final long virtualNodeId = AccessibilityNodeInfo.getVirtualDescendantId(
-                        event.getSourceNodeId());
-                if (virtualNodeId != AccessibilityNodeInfo.UNDEFINED) {
-                    ViewRootImpl viewRootImpl = getViewRootImpl();
-                    if (viewRootImpl != null) {
-                        viewRootImpl.setAccessibilityFocusedHost(null);
-                    }
-                }
-            } break;
-        }
         // In the beginning we called #isShown(), so we know that getParent() is not null.
         getParent().requestSendAccessibilityEvent(this, event);
     }
@@ -6311,7 +6286,7 @@
             mPrivateFlags2 |= ACCESSIBILITY_FOCUSED;
             ViewRootImpl viewRootImpl = getViewRootImpl();
             if (viewRootImpl != null) {
-                viewRootImpl.setAccessibilityFocusedHost(this);
+                viewRootImpl.setAccessibilityFocus(this, null);
             }
             invalidate();
             sendAccessibilityEvent(AccessibilityEvent.TYPE_VIEW_ACCESSIBILITY_FOCUSED);
@@ -6342,7 +6317,7 @@
         if (viewRootImpl != null) {
             View focusHost = viewRootImpl.getAccessibilityFocusedHost();
             if (focusHost != null && ViewRootImpl.isViewDescendantOf(focusHost, this)) {
-                viewRootImpl.setAccessibilityFocusedHost(null);
+                viewRootImpl.setAccessibilityFocus(null, null);
             }
         }
     }
@@ -7953,7 +7928,7 @@
                 // If the window does not have input focus we take away accessibility
                 // focus as soon as the user stop hovering over the view.
                 if (mAttachInfo != null && !mAttachInfo.mHasWindowFocus) {
-                    getViewRootImpl().setAccessibilityFocusedHost(null);
+                    getViewRootImpl().setAccessibilityFocus(null, null);
                 }
             }
         }
diff --git a/core/java/android/view/ViewRootImpl.java b/core/java/android/view/ViewRootImpl.java
index 51fd346..6959b84 100644
--- a/core/java/android/view/ViewRootImpl.java
+++ b/core/java/android/view/ViewRootImpl.java
@@ -489,7 +489,7 @@
                 // Keep track of the actual window flags supplied by the client.
                 mClientWindowLayoutFlags = attrs.flags;
 
-                setAccessibilityFocusedHost(null);
+                setAccessibilityFocus(null, null);
 
                 if (view instanceof RootViewSurfaceTaker) {
                     mSurfaceHolderCallback =
@@ -558,7 +558,7 @@
                     mInputChannel = null;
                     mFallbackEventHandler.setView(null);
                     unscheduleTraversals();
-                    setAccessibilityFocusedHost(null);
+                    setAccessibilityFocus(null, null);
                     throw new RuntimeException("Adding window failed", e);
                 } finally {
                     if (restore) {
@@ -578,7 +578,7 @@
                     mAdded = false;
                     mFallbackEventHandler.setView(null);
                     unscheduleTraversals();
-                    setAccessibilityFocusedHost(null);
+                    setAccessibilityFocus(null, null);
                     switch (res) {
                         case WindowManagerImpl.ADD_BAD_APP_TOKEN:
                         case WindowManagerImpl.ADD_BAD_SUBWINDOW_TOKEN:
@@ -2320,9 +2320,6 @@
             }
         } else {
             if (mAccessibilityFocusedVirtualView == null) {
-                mAccessibilityFocusedVirtualView = provider.findAccessibilityFocus(View.NO_ID);
-            }
-            if (mAccessibilityFocusedVirtualView == null) {
                 return;
             }
             mAccessibilityFocusedVirtualView.getBoundsInScreen(bounds);
@@ -2498,7 +2495,7 @@
         return mAccessibilityFocusedVirtualView;
     }
 
-    void setAccessibilityFocusedHost(View host) {
+    void setAccessibilityFocus(View view, AccessibilityNodeInfo node) {
         // If we have a virtual view with accessibility focus we need
         // to clear the focus and invalidate the virtual view bounds.
         if (mAccessibilityFocusedVirtualView != null) {
@@ -2526,24 +2523,16 @@
                 provider.performAction(virtualNodeId,
                         AccessibilityNodeInfo.ACTION_CLEAR_ACCESSIBILITY_FOCUS, null);
             }
+            focusNode.recycle();
         }
         if (mAccessibilityFocusedHost != null) {
             // Clear accessibility focus in the view.
             mAccessibilityFocusedHost.clearAccessibilityFocusNoCallbacks();
         }
 
-        // Set the new focus host.
-        mAccessibilityFocusedHost = host;
-
-        // If the host has a provide find the virtual descendant that has focus.
-        if (mAccessibilityFocusedHost != null) {
-            AccessibilityNodeProvider provider =
-                mAccessibilityFocusedHost.getAccessibilityNodeProvider();
-            if (provider != null) {
-                mAccessibilityFocusedVirtualView = provider.findAccessibilityFocus(View.NO_ID);
-                return;
-            }
-        }
+        // Set the new focus host and node.
+        mAccessibilityFocusedHost = view;
+        mAccessibilityFocusedVirtualView = node;
     }
 
     public void requestChildFocus(View child, View focused) {
@@ -2629,7 +2618,7 @@
 
         destroyHardwareRenderer();
 
-        setAccessibilityFocusedHost(null);
+        setAccessibilityFocus(null, null);
 
         mView = null;
         mAttachInfo.mRootView = null;
@@ -2910,7 +2899,7 @@
                         mHasHadWindowFocus = true;
                     }
 
-                    setAccessibilityFocusedHost(null);
+                    setAccessibilityFocus(null, null);
 
                     if (mView != null && mAccessibilityManager.isEnabled()) {
                         if (hasWindowFocus) {
@@ -2982,7 +2971,7 @@
                 invalidateDisplayLists();
             } break;
             case MSG_CLEAR_ACCESSIBILITY_FOCUS_HOST: {
-                setAccessibilityFocusedHost(null);
+                setAccessibilityFocus(null, null);
             } break;
             case MSG_DISPATCH_DONE_ANIMATING: {
                 handleDispatchDoneAnimating();
@@ -4538,29 +4527,35 @@
         if (mView == null) {
             return false;
         }
-        // Watch for accessibility focus change events from virtual nodes
-        // to keep track of accessibility focus being on a virtual node.
+        // Intercept accessibility focus events fired by virtual nodes to keep
+        // track of accessibility focus position in such nodes.
         final int eventType = event.getEventType();
         switch (eventType) {
             case AccessibilityEvent.TYPE_VIEW_ACCESSIBILITY_FOCUSED: {
-                final long sourceId = event.getSourceNodeId();
-                // If the event is not from a virtual node we are not interested.
-                final int virtualViewId = AccessibilityNodeInfo.getVirtualDescendantId(sourceId);
-                if (virtualViewId == AccessibilityNodeInfo.UNDEFINED) {
-                    break;
+                final long sourceNodeId = event.getSourceNodeId();
+                final int accessibilityViewId = AccessibilityNodeInfo.getAccessibilityViewId(
+                        sourceNodeId);
+                View source = mView.findViewByAccessibilityId(accessibilityViewId);
+                if (source != null) {
+                    AccessibilityNodeProvider provider = source.getAccessibilityNodeProvider();
+                    if (provider != null) {
+                        AccessibilityNodeInfo node = provider.createAccessibilityNodeInfo(
+                                AccessibilityNodeInfo.getVirtualDescendantId(sourceNodeId));
+                        setAccessibilityFocus(source, node);
+                    }
                 }
-                final int realViewId = AccessibilityNodeInfo.getAccessibilityViewId(sourceId);
-                View focusHost = mView.findViewByAccessibilityId(realViewId);
-                setAccessibilityFocusedHost(focusHost);
             } break;
             case AccessibilityEvent.TYPE_VIEW_ACCESSIBILITY_FOCUS_CLEARED: {
-                final long sourceId = event.getSourceNodeId();
-                // If the event is not from a virtual node we are not interested.
-                final int virtualViewId = AccessibilityNodeInfo.getVirtualDescendantId(sourceId);
-                if (virtualViewId == AccessibilityNodeInfo.UNDEFINED) {
-                    break;
+                final long sourceNodeId = event.getSourceNodeId();
+                final int accessibilityViewId = AccessibilityNodeInfo.getAccessibilityViewId(
+                        sourceNodeId);
+                View source = mView.findViewByAccessibilityId(accessibilityViewId);
+                if (source != null) {
+                    AccessibilityNodeProvider provider = source.getAccessibilityNodeProvider();
+                    if (provider != null) {
+                        setAccessibilityFocus(null, null);
+                    }
                 }
-                setAccessibilityFocusedHost(null);
             } break;
         }
         mAccessibilityManager.sendAccessibilityEvent(event);
diff --git a/core/java/android/view/accessibility/AccessibilityNodeProvider.java b/core/java/android/view/accessibility/AccessibilityNodeProvider.java
index c17cb8a..b3f3cee 100644
--- a/core/java/android/view/accessibility/AccessibilityNodeProvider.java
+++ b/core/java/android/view/accessibility/AccessibilityNodeProvider.java
@@ -150,6 +150,8 @@
      *
      * @see #createAccessibilityNodeInfo(int)
      * @see AccessibilityNodeInfo
+     *
+     * @hide
      */
     public AccessibilityNodeInfo findAccessibilityFocus(int virtualViewId) {
         return null;