Loading core/java/android/view/View.java +2 −0 Original line number Diff line number Diff line Loading @@ -9959,6 +9959,8 @@ public class View implements Drawable.Callback, KeyEvent.Callback, * @param oldt Previous vertical scroll origin. */ protected void onScrollChanged(int l, int t, int oldl, int oldt) { notifySubtreeAccessibilityStateChangedIfNeeded(); if (AccessibilityManager.getInstance(mContext).isEnabled()) { postSendViewScrolledAccessibilityEventCallback(); } Loading core/java/android/view/ViewRootImpl.java +67 −29 Original line number Diff line number Diff line Loading @@ -6268,39 +6268,77 @@ public final class ViewRootImpl implements ViewParent, case AccessibilityEvent.TYPE_WINDOW_CONTENT_CHANGED: { if (mAccessibilityFocusedHost != null && mAccessibilityFocusedVirtualView != null) { // We care only for changes rooted in the focused host. final long eventSourceId = event.getSourceNodeId(); final int hostViewId = AccessibilityNodeInfo.getAccessibilityViewId( eventSourceId); if (hostViewId != mAccessibilityFocusedHost.getAccessibilityViewId()) { break; handleWindowContentChangedEvent(event); } break; } mAccessibilityManager.sendAccessibilityEvent(event); return true; } /** * Updates the focused virtual view, when necessary, in response to a * content changed event. * <p> * This is necessary to get updated bounds after a position change. * * @param event an accessibility event of type * {@link AccessibilityEvent#TYPE_WINDOW_CONTENT_CHANGED} */ private void handleWindowContentChangedEvent(AccessibilityEvent event) { // No virtual view focused, nothing to do here. if (mAccessibilityFocusedHost == null || mAccessibilityFocusedVirtualView == null) { return; } // If we have a node but no provider, abort. final AccessibilityNodeProvider provider = mAccessibilityFocusedHost.getAccessibilityNodeProvider(); if (provider == null) { // TODO: Should we clear the focused virtual view? return; } // We only care about changes that may change the virtual focused view bounds. // We only care about change types that may affect the bounds of the // focused virtual view. final int changes = event.getContentChangeTypes(); if ((changes & AccessibilityEvent.CONTENT_CHANGE_TYPE_SUBTREE) != 0 || changes == AccessibilityEvent.CONTENT_CHANGE_TYPE_UNDEFINED) { AccessibilityNodeProvider provider = mAccessibilityFocusedHost .getAccessibilityNodeProvider(); if (provider != null) { final int virtualChildId = AccessibilityNodeInfo.getVirtualDescendantId( mAccessibilityFocusedVirtualView.getSourceNodeId()); if (virtualChildId == AccessibilityNodeInfo.UNDEFINED_ITEM_ID) { mAccessibilityFocusedVirtualView = provider .createAccessibilityNodeInfo( AccessibilityNodeProvider.HOST_VIEW_ID); if ((changes & AccessibilityEvent.CONTENT_CHANGE_TYPE_SUBTREE) == 0 && changes != AccessibilityEvent.CONTENT_CHANGE_TYPE_UNDEFINED) { return; } final long eventSourceNodeId = event.getSourceNodeId(); final int changedViewId = AccessibilityNodeInfo.getAccessibilityViewId(eventSourceNodeId); // Search up the tree for subtree containment. boolean hostInSubtree = false; View root = mAccessibilityFocusedHost; while (root != null && !hostInSubtree) { if (changedViewId == root.getAccessibilityViewId()) { hostInSubtree = true; } else { final ViewParent parent = root.getParent(); if (parent instanceof View) { root = (View) parent; } else { mAccessibilityFocusedVirtualView = provider .createAccessibilityNodeInfo(virtualChildId); root = null; } } } // We care only about changes in subtrees containing the host view. if (!hostInSubtree) { return; } } break; final long focusedSourceNodeId = mAccessibilityFocusedVirtualView.getSourceNodeId(); int focusedChildId = AccessibilityNodeInfo.getVirtualDescendantId(focusedSourceNodeId); if (focusedChildId == AccessibilityNodeInfo.UNDEFINED_ITEM_ID) { // TODO: Should we clear the focused virtual view? focusedChildId = AccessibilityNodeProvider.HOST_VIEW_ID; } mAccessibilityManager.sendAccessibilityEvent(event); return true; // Refresh the node for the focused virtual view. mAccessibilityFocusedVirtualView = provider.createAccessibilityNodeInfo(focusedChildId); } @Override Loading core/java/com/android/internal/widget/ViewPager.java +50 −71 Original line number Diff line number Diff line Loading @@ -42,6 +42,7 @@ import android.view.ViewGroup; import android.view.ViewParent; import android.view.accessibility.AccessibilityEvent; import android.view.accessibility.AccessibilityNodeInfo; import android.view.accessibility.AccessibilityNodeInfo.AccessibilityAction; import android.view.accessibility.AccessibilityRecord; import android.view.animation.Interpolator; import android.widget.EdgeEffect; Loading Loading @@ -371,8 +372,6 @@ public class ViewPager extends ViewGroup { mCloseEnough = (int) (CLOSE_ENOUGH * density); mDefaultGutterSize = (int) (DEFAULT_GUTTER_SIZE * density); setAccessibilityDelegate(new MyAccessibilityDelegate()); if (getImportantForAccessibility() == IMPORTANT_FOR_ACCESSIBILITY_AUTO) { setImportantForAccessibility(IMPORTANT_FOR_ACCESSIBILITY_YES); } Loading Loading @@ -2694,29 +2693,6 @@ public class ViewPager extends ViewGroup { return false; } @Override public boolean dispatchPopulateAccessibilityEvent(AccessibilityEvent event) { // Dispatch scroll events from this ViewPager. if (event.getEventType() == AccessibilityEvent.TYPE_VIEW_SCROLLED) { return super.dispatchPopulateAccessibilityEvent(event); } // Dispatch all other accessibility events from the current page. final int childCount = getChildCount(); for (int i = 0; i < childCount; i++) { final View child = getChildAt(i); if (child.getVisibility() == VISIBLE) { final ItemInfo ii = infoForChild(child); if (ii != null && ii.position == mCurItem && child.dispatchPopulateAccessibilityEvent(event)) { return true; } } } return false; } @Override protected ViewGroup.LayoutParams generateDefaultLayoutParams() { return new LayoutParams(); Loading @@ -2737,60 +2713,63 @@ public class ViewPager extends ViewGroup { return new LayoutParams(getContext(), attrs); } class MyAccessibilityDelegate extends AccessibilityDelegate { @Override public void onInitializeAccessibilityEvent(View host, AccessibilityEvent event) { super.onInitializeAccessibilityEvent(host, event); public void onInitializeAccessibilityEvent(AccessibilityEvent event) { super.onInitializeAccessibilityEvent(event); event.setClassName(ViewPager.class.getName()); final AccessibilityRecord record = AccessibilityRecord.obtain(); record.setScrollable(canScroll()); if (event.getEventType() == AccessibilityEvent.TYPE_VIEW_SCROLLED && mAdapter != null) { record.setItemCount(mAdapter.getCount()); record.setFromIndex(mCurItem); record.setToIndex(mCurItem); event.setScrollable(canScroll()); if (event.getEventType() == AccessibilityEvent.TYPE_VIEW_SCROLLED && mAdapter != null) { event.setItemCount(mAdapter.getCount()); event.setFromIndex(mCurItem); event.setToIndex(mCurItem); } } @Override public void onInitializeAccessibilityNodeInfo(View host, AccessibilityNodeInfo info) { super.onInitializeAccessibilityNodeInfo(host, info); public void onInitializeAccessibilityNodeInfo(AccessibilityNodeInfo info) { super.onInitializeAccessibilityNodeInfo(info); info.setClassName(ViewPager.class.getName()); info.setScrollable(canScroll()); if (canScrollHorizontally(1)) { info.addAction(AccessibilityNodeInfo.ACTION_SCROLL_FORWARD); info.addAction(AccessibilityAction.ACTION_SCROLL_FORWARD); } if (canScrollHorizontally(-1)) { info.addAction(AccessibilityNodeInfo.ACTION_SCROLL_BACKWARD); info.addAction(AccessibilityAction.ACTION_SCROLL_BACKWARD); } } @Override public boolean performAccessibilityAction(View host, int action, Bundle args) { if (super.performAccessibilityAction(host, action, args)) { public boolean performAccessibilityAction(int action, Bundle args) { if (super.performAccessibilityAction(action, args)) { return true; } switch (action) { case AccessibilityNodeInfo.ACTION_SCROLL_FORWARD: { case AccessibilityNodeInfo.ACTION_SCROLL_FORWARD: if (canScrollHorizontally(1)) { setCurrentItem(mCurItem + 1); return true; } } return false; case AccessibilityNodeInfo.ACTION_SCROLL_BACKWARD: { return false; case AccessibilityNodeInfo.ACTION_SCROLL_BACKWARD: if (canScrollHorizontally(-1)) { setCurrentItem(mCurItem - 1); return true; } } return false; return false; } return false; } private boolean canScroll() { return (mAdapter != null) && (mAdapter.getCount() > 1); } return mAdapter != null && mAdapter.getCount() > 1; } private class PagerObserver extends DataSetObserver { Loading Loading
core/java/android/view/View.java +2 −0 Original line number Diff line number Diff line Loading @@ -9959,6 +9959,8 @@ public class View implements Drawable.Callback, KeyEvent.Callback, * @param oldt Previous vertical scroll origin. */ protected void onScrollChanged(int l, int t, int oldl, int oldt) { notifySubtreeAccessibilityStateChangedIfNeeded(); if (AccessibilityManager.getInstance(mContext).isEnabled()) { postSendViewScrolledAccessibilityEventCallback(); } Loading
core/java/android/view/ViewRootImpl.java +67 −29 Original line number Diff line number Diff line Loading @@ -6268,39 +6268,77 @@ public final class ViewRootImpl implements ViewParent, case AccessibilityEvent.TYPE_WINDOW_CONTENT_CHANGED: { if (mAccessibilityFocusedHost != null && mAccessibilityFocusedVirtualView != null) { // We care only for changes rooted in the focused host. final long eventSourceId = event.getSourceNodeId(); final int hostViewId = AccessibilityNodeInfo.getAccessibilityViewId( eventSourceId); if (hostViewId != mAccessibilityFocusedHost.getAccessibilityViewId()) { break; handleWindowContentChangedEvent(event); } break; } mAccessibilityManager.sendAccessibilityEvent(event); return true; } /** * Updates the focused virtual view, when necessary, in response to a * content changed event. * <p> * This is necessary to get updated bounds after a position change. * * @param event an accessibility event of type * {@link AccessibilityEvent#TYPE_WINDOW_CONTENT_CHANGED} */ private void handleWindowContentChangedEvent(AccessibilityEvent event) { // No virtual view focused, nothing to do here. if (mAccessibilityFocusedHost == null || mAccessibilityFocusedVirtualView == null) { return; } // If we have a node but no provider, abort. final AccessibilityNodeProvider provider = mAccessibilityFocusedHost.getAccessibilityNodeProvider(); if (provider == null) { // TODO: Should we clear the focused virtual view? return; } // We only care about changes that may change the virtual focused view bounds. // We only care about change types that may affect the bounds of the // focused virtual view. final int changes = event.getContentChangeTypes(); if ((changes & AccessibilityEvent.CONTENT_CHANGE_TYPE_SUBTREE) != 0 || changes == AccessibilityEvent.CONTENT_CHANGE_TYPE_UNDEFINED) { AccessibilityNodeProvider provider = mAccessibilityFocusedHost .getAccessibilityNodeProvider(); if (provider != null) { final int virtualChildId = AccessibilityNodeInfo.getVirtualDescendantId( mAccessibilityFocusedVirtualView.getSourceNodeId()); if (virtualChildId == AccessibilityNodeInfo.UNDEFINED_ITEM_ID) { mAccessibilityFocusedVirtualView = provider .createAccessibilityNodeInfo( AccessibilityNodeProvider.HOST_VIEW_ID); if ((changes & AccessibilityEvent.CONTENT_CHANGE_TYPE_SUBTREE) == 0 && changes != AccessibilityEvent.CONTENT_CHANGE_TYPE_UNDEFINED) { return; } final long eventSourceNodeId = event.getSourceNodeId(); final int changedViewId = AccessibilityNodeInfo.getAccessibilityViewId(eventSourceNodeId); // Search up the tree for subtree containment. boolean hostInSubtree = false; View root = mAccessibilityFocusedHost; while (root != null && !hostInSubtree) { if (changedViewId == root.getAccessibilityViewId()) { hostInSubtree = true; } else { final ViewParent parent = root.getParent(); if (parent instanceof View) { root = (View) parent; } else { mAccessibilityFocusedVirtualView = provider .createAccessibilityNodeInfo(virtualChildId); root = null; } } } // We care only about changes in subtrees containing the host view. if (!hostInSubtree) { return; } } break; final long focusedSourceNodeId = mAccessibilityFocusedVirtualView.getSourceNodeId(); int focusedChildId = AccessibilityNodeInfo.getVirtualDescendantId(focusedSourceNodeId); if (focusedChildId == AccessibilityNodeInfo.UNDEFINED_ITEM_ID) { // TODO: Should we clear the focused virtual view? focusedChildId = AccessibilityNodeProvider.HOST_VIEW_ID; } mAccessibilityManager.sendAccessibilityEvent(event); return true; // Refresh the node for the focused virtual view. mAccessibilityFocusedVirtualView = provider.createAccessibilityNodeInfo(focusedChildId); } @Override Loading
core/java/com/android/internal/widget/ViewPager.java +50 −71 Original line number Diff line number Diff line Loading @@ -42,6 +42,7 @@ import android.view.ViewGroup; import android.view.ViewParent; import android.view.accessibility.AccessibilityEvent; import android.view.accessibility.AccessibilityNodeInfo; import android.view.accessibility.AccessibilityNodeInfo.AccessibilityAction; import android.view.accessibility.AccessibilityRecord; import android.view.animation.Interpolator; import android.widget.EdgeEffect; Loading Loading @@ -371,8 +372,6 @@ public class ViewPager extends ViewGroup { mCloseEnough = (int) (CLOSE_ENOUGH * density); mDefaultGutterSize = (int) (DEFAULT_GUTTER_SIZE * density); setAccessibilityDelegate(new MyAccessibilityDelegate()); if (getImportantForAccessibility() == IMPORTANT_FOR_ACCESSIBILITY_AUTO) { setImportantForAccessibility(IMPORTANT_FOR_ACCESSIBILITY_YES); } Loading Loading @@ -2694,29 +2693,6 @@ public class ViewPager extends ViewGroup { return false; } @Override public boolean dispatchPopulateAccessibilityEvent(AccessibilityEvent event) { // Dispatch scroll events from this ViewPager. if (event.getEventType() == AccessibilityEvent.TYPE_VIEW_SCROLLED) { return super.dispatchPopulateAccessibilityEvent(event); } // Dispatch all other accessibility events from the current page. final int childCount = getChildCount(); for (int i = 0; i < childCount; i++) { final View child = getChildAt(i); if (child.getVisibility() == VISIBLE) { final ItemInfo ii = infoForChild(child); if (ii != null && ii.position == mCurItem && child.dispatchPopulateAccessibilityEvent(event)) { return true; } } } return false; } @Override protected ViewGroup.LayoutParams generateDefaultLayoutParams() { return new LayoutParams(); Loading @@ -2737,60 +2713,63 @@ public class ViewPager extends ViewGroup { return new LayoutParams(getContext(), attrs); } class MyAccessibilityDelegate extends AccessibilityDelegate { @Override public void onInitializeAccessibilityEvent(View host, AccessibilityEvent event) { super.onInitializeAccessibilityEvent(host, event); public void onInitializeAccessibilityEvent(AccessibilityEvent event) { super.onInitializeAccessibilityEvent(event); event.setClassName(ViewPager.class.getName()); final AccessibilityRecord record = AccessibilityRecord.obtain(); record.setScrollable(canScroll()); if (event.getEventType() == AccessibilityEvent.TYPE_VIEW_SCROLLED && mAdapter != null) { record.setItemCount(mAdapter.getCount()); record.setFromIndex(mCurItem); record.setToIndex(mCurItem); event.setScrollable(canScroll()); if (event.getEventType() == AccessibilityEvent.TYPE_VIEW_SCROLLED && mAdapter != null) { event.setItemCount(mAdapter.getCount()); event.setFromIndex(mCurItem); event.setToIndex(mCurItem); } } @Override public void onInitializeAccessibilityNodeInfo(View host, AccessibilityNodeInfo info) { super.onInitializeAccessibilityNodeInfo(host, info); public void onInitializeAccessibilityNodeInfo(AccessibilityNodeInfo info) { super.onInitializeAccessibilityNodeInfo(info); info.setClassName(ViewPager.class.getName()); info.setScrollable(canScroll()); if (canScrollHorizontally(1)) { info.addAction(AccessibilityNodeInfo.ACTION_SCROLL_FORWARD); info.addAction(AccessibilityAction.ACTION_SCROLL_FORWARD); } if (canScrollHorizontally(-1)) { info.addAction(AccessibilityNodeInfo.ACTION_SCROLL_BACKWARD); info.addAction(AccessibilityAction.ACTION_SCROLL_BACKWARD); } } @Override public boolean performAccessibilityAction(View host, int action, Bundle args) { if (super.performAccessibilityAction(host, action, args)) { public boolean performAccessibilityAction(int action, Bundle args) { if (super.performAccessibilityAction(action, args)) { return true; } switch (action) { case AccessibilityNodeInfo.ACTION_SCROLL_FORWARD: { case AccessibilityNodeInfo.ACTION_SCROLL_FORWARD: if (canScrollHorizontally(1)) { setCurrentItem(mCurItem + 1); return true; } } return false; case AccessibilityNodeInfo.ACTION_SCROLL_BACKWARD: { return false; case AccessibilityNodeInfo.ACTION_SCROLL_BACKWARD: if (canScrollHorizontally(-1)) { setCurrentItem(mCurItem - 1); return true; } } return false; return false; } return false; } private boolean canScroll() { return (mAdapter != null) && (mAdapter.getCount() > 1); } return mAdapter != null && mAdapter.getCount() > 1; } private class PagerObserver extends DataSetObserver { Loading