@@ -489,7 +489,7 @@ public void setView(View view, WindowManager.LayoutParams attrs, View panelParen
489489 // Keep track of the actual window flags supplied by the client.
490490 mClientWindowLayoutFlags = attrs .flags ;
491491
492- setAccessibilityFocusedHost ( null );
492+ setAccessibilityFocus ( null , null );
493493
494494 if (view instanceof RootViewSurfaceTaker ) {
495495 mSurfaceHolderCallback =
@@ -558,7 +558,7 @@ public void setView(View view, WindowManager.LayoutParams attrs, View panelParen
558558 mInputChannel = null ;
559559 mFallbackEventHandler .setView (null );
560560 unscheduleTraversals ();
561- setAccessibilityFocusedHost ( null );
561+ setAccessibilityFocus ( null , null );
562562 throw new RuntimeException ("Adding window failed" , e );
563563 } finally {
564564 if (restore ) {
@@ -578,7 +578,7 @@ public void setView(View view, WindowManager.LayoutParams attrs, View panelParen
578578 mAdded = false ;
579579 mFallbackEventHandler .setView (null );
580580 unscheduleTraversals ();
581- setAccessibilityFocusedHost ( null );
581+ setAccessibilityFocus ( null , null );
582582 switch (res ) {
583583 case WindowManagerImpl .ADD_BAD_APP_TOKEN :
584584 case WindowManagerImpl .ADD_BAD_SUBWINDOW_TOKEN :
@@ -2319,9 +2319,6 @@ private void drawAccessibilityFocusedDrawableIfNeeded(Canvas canvas) {
23192319 viewGroup .offsetDescendantRectToMyCoords (mAccessibilityFocusedHost , bounds );
23202320 }
23212321 } else {
2322- if (mAccessibilityFocusedVirtualView == null ) {
2323- mAccessibilityFocusedVirtualView = provider .findAccessibilityFocus (View .NO_ID );
2324- }
23252322 if (mAccessibilityFocusedVirtualView == null ) {
23262323 return ;
23272324 }
@@ -2498,7 +2495,7 @@ public AccessibilityNodeInfo getAccessibilityFocusedVirtualView() {
24982495 return mAccessibilityFocusedVirtualView ;
24992496 }
25002497
2501- void setAccessibilityFocusedHost (View host ) {
2498+ void setAccessibilityFocus (View view , AccessibilityNodeInfo node ) {
25022499 // If we have a virtual view with accessibility focus we need
25032500 // to clear the focus and invalidate the virtual view bounds.
25042501 if (mAccessibilityFocusedVirtualView != null ) {
@@ -2526,24 +2523,16 @@ void setAccessibilityFocusedHost(View host) {
25262523 provider .performAction (virtualNodeId ,
25272524 AccessibilityNodeInfo .ACTION_CLEAR_ACCESSIBILITY_FOCUS , null );
25282525 }
2526+ focusNode .recycle ();
25292527 }
25302528 if (mAccessibilityFocusedHost != null ) {
25312529 // Clear accessibility focus in the view.
25322530 mAccessibilityFocusedHost .clearAccessibilityFocusNoCallbacks ();
25332531 }
25342532
2535- // Set the new focus host.
2536- mAccessibilityFocusedHost = host ;
2537-
2538- // If the host has a provide find the virtual descendant that has focus.
2539- if (mAccessibilityFocusedHost != null ) {
2540- AccessibilityNodeProvider provider =
2541- mAccessibilityFocusedHost .getAccessibilityNodeProvider ();
2542- if (provider != null ) {
2543- mAccessibilityFocusedVirtualView = provider .findAccessibilityFocus (View .NO_ID );
2544- return ;
2545- }
2546- }
2533+ // Set the new focus host and node.
2534+ mAccessibilityFocusedHost = view ;
2535+ mAccessibilityFocusedVirtualView = node ;
25472536 }
25482537
25492538 public void requestChildFocus (View child , View focused ) {
@@ -2629,7 +2618,7 @@ void dispatchDetachedFromWindow() {
26292618
26302619 destroyHardwareRenderer ();
26312620
2632- setAccessibilityFocusedHost ( null );
2621+ setAccessibilityFocus ( null , null );
26332622
26342623 mView = null ;
26352624 mAttachInfo .mRootView = null ;
@@ -2910,7 +2899,7 @@ public void handleMessage(Message msg) {
29102899 mHasHadWindowFocus = true ;
29112900 }
29122901
2913- setAccessibilityFocusedHost ( null );
2902+ setAccessibilityFocus ( null , null );
29142903
29152904 if (mView != null && mAccessibilityManager .isEnabled ()) {
29162905 if (hasWindowFocus ) {
@@ -2982,7 +2971,7 @@ public void handleMessage(Message msg) {
29822971 invalidateDisplayLists ();
29832972 } break ;
29842973 case MSG_CLEAR_ACCESSIBILITY_FOCUS_HOST : {
2985- setAccessibilityFocusedHost ( null );
2974+ setAccessibilityFocus ( null , null );
29862975 } break ;
29872976 case MSG_DISPATCH_DONE_ANIMATING : {
29882977 handleDispatchDoneAnimating ();
@@ -4538,29 +4527,35 @@ public boolean requestSendAccessibilityEvent(View child, AccessibilityEvent even
45384527 if (mView == null ) {
45394528 return false ;
45404529 }
4541- // Watch for accessibility focus change events from virtual nodes
4542- // to keep track of accessibility focus being on a virtual node .
4530+ // Intercept accessibility focus events fired by virtual nodes to keep
4531+ // track of accessibility focus position in such nodes .
45434532 final int eventType = event .getEventType ();
45444533 switch (eventType ) {
45454534 case AccessibilityEvent .TYPE_VIEW_ACCESSIBILITY_FOCUSED : {
4546- final long sourceId = event .getSourceNodeId ();
4547- // If the event is not from a virtual node we are not interested.
4548- final int virtualViewId = AccessibilityNodeInfo .getVirtualDescendantId (sourceId );
4549- if (virtualViewId == AccessibilityNodeInfo .UNDEFINED ) {
4550- break ;
4535+ final long sourceNodeId = event .getSourceNodeId ();
4536+ final int accessibilityViewId = AccessibilityNodeInfo .getAccessibilityViewId (
4537+ sourceNodeId );
4538+ View source = mView .findViewByAccessibilityId (accessibilityViewId );
4539+ if (source != null ) {
4540+ AccessibilityNodeProvider provider = source .getAccessibilityNodeProvider ();
4541+ if (provider != null ) {
4542+ AccessibilityNodeInfo node = provider .createAccessibilityNodeInfo (
4543+ AccessibilityNodeInfo .getVirtualDescendantId (sourceNodeId ));
4544+ setAccessibilityFocus (source , node );
4545+ }
45514546 }
4552- final int realViewId = AccessibilityNodeInfo .getAccessibilityViewId (sourceId );
4553- View focusHost = mView .findViewByAccessibilityId (realViewId );
4554- setAccessibilityFocusedHost (focusHost );
45554547 } break ;
45564548 case AccessibilityEvent .TYPE_VIEW_ACCESSIBILITY_FOCUS_CLEARED : {
4557- final long sourceId = event .getSourceNodeId ();
4558- // If the event is not from a virtual node we are not interested.
4559- final int virtualViewId = AccessibilityNodeInfo .getVirtualDescendantId (sourceId );
4560- if (virtualViewId == AccessibilityNodeInfo .UNDEFINED ) {
4561- break ;
4549+ final long sourceNodeId = event .getSourceNodeId ();
4550+ final int accessibilityViewId = AccessibilityNodeInfo .getAccessibilityViewId (
4551+ sourceNodeId );
4552+ View source = mView .findViewByAccessibilityId (accessibilityViewId );
4553+ if (source != null ) {
4554+ AccessibilityNodeProvider provider = source .getAccessibilityNodeProvider ();
4555+ if (provider != null ) {
4556+ setAccessibilityFocus (null , null );
4557+ }
45624558 }
4563- setAccessibilityFocusedHost (null );
45644559 } break ;
45654560 }
45664561 mAccessibilityManager .sendAccessibilityEvent (event );
0 commit comments