Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit dac9591e authored by Phil Weaver's avatar Phil Weaver Committed by android-build-merger
Browse files

Merge "Improve a11y ordering" into pi-dev am: 3789bbc4

am: fbcae9d7

Change-Id: I0c234b9e3f2778951c729ed6daed96bcc3b394d2
parents 73a86d1d fbcae9d7
Loading
Loading
Loading
Loading
+69 −13
Original line number Original line Diff line number Diff line
@@ -8567,6 +8567,8 @@ public abstract class ViewGroup extends View implements ViewParent, ViewManager


        private final Rect mLocation = new Rect();
        private final Rect mLocation = new Rect();


        private ViewGroup mRoot;

        public View mView;
        public View mView;


        private int mLayoutDirection;
        private int mLayoutDirection;
@@ -8596,47 +8598,100 @@ public abstract class ViewGroup extends View implements ViewParent, ViewManager
                return 1;
                return 1;
            }
            }


            int boundsResult = compareBoundsOfTree(this, another);
            if (boundsResult != 0) {
                return boundsResult;
            }

            // Just break the tie somehow. The accessibility ids are unique
            // and stable, hence this is deterministic tie breaking.
            return mView.getAccessibilityViewId() - another.mView.getAccessibilityViewId();
        }

        /**
         * Compare two views based on their bounds. Use the bounds of their children to break ties.
         *
         * @param holder1 Holder of first view to compare
         * @param holder2 Holder of second view to compare. Must have the same root at holder1.
         * @return The compare result, with equality if no good comparison was found.
         */
        private static int compareBoundsOfTree(
                ViewLocationHolder holder1, ViewLocationHolder holder2) {
            if (sComparisonStrategy == COMPARISON_STRATEGY_STRIPE) {
            if (sComparisonStrategy == COMPARISON_STRATEGY_STRIPE) {
                // First is above second.
                // First is above second.
                if (mLocation.bottom - another.mLocation.top <= 0) {
                if (holder1.mLocation.bottom - holder2.mLocation.top <= 0) {
                    return -1;
                    return -1;
                }
                }
                // First is below second.
                // First is below second.
                if (mLocation.top - another.mLocation.bottom >= 0) {
                if (holder1.mLocation.top - holder2.mLocation.bottom >= 0) {
                    return 1;
                    return 1;
                }
                }
            }
            }


            // We are ordering left-to-right, top-to-bottom.
            // We are ordering left-to-right, top-to-bottom.
            if (mLayoutDirection == LAYOUT_DIRECTION_LTR) {
            if (holder1.mLayoutDirection == LAYOUT_DIRECTION_LTR) {
                final int leftDifference = mLocation.left - another.mLocation.left;
                final int leftDifference = holder1.mLocation.left - holder2.mLocation.left;
                if (leftDifference != 0) {
                if (leftDifference != 0) {
                    return leftDifference;
                    return leftDifference;
                }
                }
            } else { // RTL
            } else { // RTL
                final int rightDifference = mLocation.right - another.mLocation.right;
                final int rightDifference = holder1.mLocation.right - holder2.mLocation.right;
                if (rightDifference != 0) {
                if (rightDifference != 0) {
                    return -rightDifference;
                    return -rightDifference;
                }
                }
            }
            }
            // We are ordering left-to-right, top-to-bottom.
            // We are ordering left-to-right, top-to-bottom.
            final int topDifference = mLocation.top - another.mLocation.top;
            final int topDifference = holder1.mLocation.top - holder2.mLocation.top;
            if (topDifference != 0) {
            if (topDifference != 0) {
                return topDifference;
                return topDifference;
            }
            }
            // Break tie by height.
            // Break tie by height.
            final int heightDiference = mLocation.height() - another.mLocation.height();
            final int heightDiference = holder1.mLocation.height() - holder2.mLocation.height();
            if (heightDiference != 0) {
            if (heightDiference != 0) {
                return -heightDiference;
                return -heightDiference;
            }
            }
            // Break tie by width.
            // Break tie by width.
            final int widthDiference = mLocation.width() - another.mLocation.width();
            final int widthDifference = holder1.mLocation.width() - holder2.mLocation.width();
            if (widthDiference != 0) {
            if (widthDifference != 0) {
                return -widthDiference;
                return -widthDifference;
            }

            // Find a child of each view with different screen bounds.
            final Rect view1Bounds = new Rect();
            final Rect view2Bounds = new Rect();
            final Rect tempRect = new Rect();
            holder1.mView.getBoundsOnScreen(view1Bounds, true);
            holder2.mView.getBoundsOnScreen(view2Bounds, true);
            final View child1 = holder1.mView.findViewByPredicateTraversal((view) -> {
                view.getBoundsOnScreen(tempRect, true);
                return !tempRect.equals(view1Bounds);
            }, null);
            final View child2 = holder2.mView.findViewByPredicateTraversal((view) -> {
                view.getBoundsOnScreen(tempRect, true);
                return !tempRect.equals(view2Bounds);
            }, null);


            // Compare the children recursively
            if ((child1 != null) && (child2 != null)) {
                final ViewLocationHolder childHolder1 =
                        ViewLocationHolder.obtain(holder1.mRoot, child1);
                final ViewLocationHolder childHolder2 =
                        ViewLocationHolder.obtain(holder1.mRoot, child2);
                return compareBoundsOfTree(childHolder1, childHolder2);
            }

            // If only one has a child, use that one
            if (child1 != null) {
                return 1;
            }
            }
            // Just break the tie somehow. The accessibliity ids are unique

            // and stable, hence this is deterministic tie breaking.
            if (child2 != null) {
            return mView.getAccessibilityViewId() - another.mView.getAccessibilityViewId();
                return -1;
            }

            // Give up
            return 0;
        }
        }


        private void init(ViewGroup root, View view) {
        private void init(ViewGroup root, View view) {
@@ -8644,6 +8699,7 @@ public abstract class ViewGroup extends View implements ViewParent, ViewManager
            view.getDrawingRect(viewLocation);
            view.getDrawingRect(viewLocation);
            root.offsetDescendantRectToMyCoords(view, viewLocation);
            root.offsetDescendantRectToMyCoords(view, viewLocation);
            mView = view;
            mView = view;
            mRoot = root;
            mLayoutDirection = root.getLayoutDirection();
            mLayoutDirection = root.getLayoutDirection();
        }
        }