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

Commit 66c0adcf authored by Alan Viverette's avatar Alan Viverette Committed by Android (Google) Code Review
Browse files

Merge "Ensure accessibility focus rect is drawn correctly" into lmp-mr1-dev

parents 8785a56c 632af849
Loading
Loading
Loading
Loading
+0 −51
Original line number Diff line number Diff line
@@ -14062,7 +14062,6 @@ public class View implements Drawable.Callback, KeyEvent.Callback,
                    } else {
                        draw(canvas);
                    }
                    drawAccessibilityFocus(canvas);
                }
            } finally {
                renderNode.end(canvas);
@@ -14357,7 +14356,6 @@ public class View implements Drawable.Callback, KeyEvent.Callback,
            } else {
                draw(canvas);
            }
            drawAccessibilityFocus(canvas);
            canvas.restoreToCount(restoreCount);
            canvas.setBitmap(null);
@@ -14432,7 +14430,6 @@ public class View implements Drawable.Callback, KeyEvent.Callback,
        } else {
            draw(canvas);
        }
        drawAccessibilityFocus(canvas);
        mPrivateFlags = flags;
@@ -15030,13 +15027,9 @@ public class View implements Drawable.Callback, KeyEvent.Callback,
                    if ((mPrivateFlags & PFLAG_SKIP_DRAW) == PFLAG_SKIP_DRAW) {
                        mPrivateFlags &= ~PFLAG_DIRTY_MASK;
                        dispatchDraw(canvas);
                        if (mOverlay != null && !mOverlay.isEmpty()) {
                            mOverlay.getOverlayView().draw(canvas);
                        }
                    } else {
                        draw(canvas);
                    }
                    drawAccessibilityFocus(canvas);
                } else {
                    mPrivateFlags &= ~PFLAG_DIRTY_MASK;
                    ((HardwareCanvas) canvas).drawRenderNode(renderNode, null, flags);
@@ -15287,50 +15280,6 @@ public class View implements Drawable.Callback, KeyEvent.Callback,
        }
    }
    /**
     * Draws the accessibility focus rect onto the specified canvas.
     *
     * @param canvas Canvas on which to draw the focus rect
     */
    private void drawAccessibilityFocus(Canvas canvas) {
        if (mAttachInfo == null) {
            return;
        }
        final Rect bounds = mAttachInfo.mTmpInvalRect;
        final ViewRootImpl viewRoot = getViewRootImpl();
        if (viewRoot == null || viewRoot.getAccessibilityFocusedHost() != this) {
            return;
        }
        final AccessibilityManager manager = AccessibilityManager.getInstance(mContext);
        if (!manager.isEnabled() || !manager.isTouchExplorationEnabled()) {
            return;
        }
        final Drawable drawable = viewRoot.getAccessibilityFocusedDrawable();
        if (drawable == null) {
            return;
        }
        final AccessibilityNodeInfo virtualView = viewRoot.getAccessibilityFocusedVirtualView();
        if (virtualView != null) {
            virtualView.getBoundsInScreen(bounds);
            final int[] offset = mAttachInfo.mTmpLocation;
            getLocationOnScreen(offset);
            bounds.offset(-offset[0], -offset[1]);
        } else {
            bounds.set(0, 0, mRight - mLeft, mBottom - mTop);
        }
        canvas.save();
        canvas.translate(mScrollX, mScrollY);
        canvas.clipRect(bounds, Region.Op.REPLACE);
        drawable.setBounds(bounds);
        drawable.draw(canvas);
        canvas.restore();
    }
    /**
     * Draws the background onto the specified canvas.
     *
+3 −9
Original line number Diff line number Diff line
@@ -4250,9 +4250,7 @@ public abstract class ViewGroup extends View implements ViewParent, ViewManager
            clearChildFocus = true;
        }

        if (view.isAccessibilityFocused()) {
        view.clearAccessibilityFocus();
        }

        cancelTouchTarget(view);
        cancelHoverTarget(view);
@@ -4345,9 +4343,7 @@ public abstract class ViewGroup extends View implements ViewParent, ViewManager
                clearChildFocus = true;
            }

            if (view.isAccessibilityFocused()) {
            view.clearAccessibilityFocus();
            }

            cancelTouchTarget(view);
            cancelHoverTarget(view);
@@ -4432,9 +4428,7 @@ public abstract class ViewGroup extends View implements ViewParent, ViewManager
                clearChildFocus = true;
            }

            if (view.isAccessibilityFocused()) {
            view.clearAccessibilityFocus();
            }

            cancelTouchTarget(view);
            cancelHoverTarget(view);
+76 −4
Original line number Diff line number Diff line
@@ -2258,6 +2258,7 @@ public final class ViewRootImpl implements ViewParent,
            canvas.drawHardwareLayer(mResizeBuffer, mHardwareXOffset, mHardwareYOffset,
                    mResizePaint);
        }
        drawAccessibilityFocusedDrawableIfNeeded(canvas);
    }

    /**
@@ -2477,18 +2478,38 @@ public final class ViewRootImpl implements ViewParent,
            dirty.offset(surfaceInsets.left, surfaceInsets.right);
        }

        if (!dirty.isEmpty() || mIsAnimating) {
        boolean accessibilityFocusDirty = false;
        final Drawable drawable = mAttachInfo.mAccessibilityFocusDrawable;
        if (drawable != null) {
            final Rect bounds = mAttachInfo.mTmpInvalRect;
            final boolean hasFocus = getAccessibilityFocusedRect(bounds);
            if (!hasFocus) {
                bounds.setEmpty();
            }
            if (!bounds.equals(drawable.getBounds())) {
                accessibilityFocusDirty = true;
            }
        }

        if (!dirty.isEmpty() || mIsAnimating || accessibilityFocusDirty) {
            if (mAttachInfo.mHardwareRenderer != null && mAttachInfo.mHardwareRenderer.isEnabled()) {
                // If accessibility focus moved, always invalidate the root.
                boolean invalidateRoot = accessibilityFocusDirty;

                // Draw with hardware renderer.
                mIsAnimating = false;
                boolean invalidateRoot = false;

                if (mHardwareYOffset != yOffset || mHardwareXOffset != xOffset) {
                    mHardwareYOffset = yOffset;
                    mHardwareXOffset = xOffset;
                    mAttachInfo.mHardwareRenderer.invalidateRoot();
                    invalidateRoot = true;
                }
                mResizeAlpha = resizeAlpha;

                if (invalidateRoot) {
                    mAttachInfo.mHardwareRenderer.invalidateRoot();
                }

                dirty.setEmpty();

                mBlockResizeBuffer = false;
@@ -2607,6 +2628,8 @@ public final class ViewRootImpl implements ViewParent,
                attachInfo.mSetIgnoreDirtyState = false;

                mView.draw(canvas);

                drawAccessibilityFocusedDrawableIfNeeded(canvas);
            } finally {
                if (!attachInfo.mSetIgnoreDirtyState) {
                    // Only clear the flag if it was not set during the mView.draw() call
@@ -2630,7 +2653,56 @@ public final class ViewRootImpl implements ViewParent,
        return true;
    }

    Drawable getAccessibilityFocusedDrawable() {
    /**
     * We want to draw a highlight around the current accessibility focused.
     * Since adding a style for all possible view is not a viable option we
     * have this specialized drawing method.
     *
     * Note: We are doing this here to be able to draw the highlight for
     *       virtual views in addition to real ones.
     *
     * @param canvas The canvas on which to draw.
     */
    private void drawAccessibilityFocusedDrawableIfNeeded(Canvas canvas) {
        final Rect bounds = mAttachInfo.mTmpInvalRect;
        if (getAccessibilityFocusedRect(bounds)) {
            final Drawable drawable = getAccessibilityFocusedDrawable();
            if (drawable != null) {
                drawable.setBounds(bounds);
                drawable.draw(canvas);
            }
        } else if (mAttachInfo.mAccessibilityFocusDrawable != null) {
            mAttachInfo.mAccessibilityFocusDrawable.setBounds(0, 0, 0, 0);
        }
    }

    private boolean getAccessibilityFocusedRect(Rect bounds) {
        final AccessibilityManager manager = AccessibilityManager.getInstance(mView.mContext);
        if (!manager.isEnabled() || !manager.isTouchExplorationEnabled()) {
            return false;
        }

        final View host = mAccessibilityFocusedHost;
        if (host == null || host.mAttachInfo == null) {
            return false;
        }

        final AccessibilityNodeProvider provider = host.getAccessibilityNodeProvider();
        if (provider == null) {
            host.getBoundsOnScreen(bounds);
        } else if (mAccessibilityFocusedVirtualView != null) {
            mAccessibilityFocusedVirtualView.getBoundsInScreen(bounds);
        } else {
            return false;
        }

        final AttachInfo attachInfo = mAttachInfo;
        bounds.offset(-attachInfo.mWindowLeft, -attachInfo.mWindowTop);
        bounds.intersect(0, 0, attachInfo.mViewRootImpl.mWidth, attachInfo.mViewRootImpl.mHeight);
        return !bounds.isEmpty();
    }

    private Drawable getAccessibilityFocusedDrawable() {
        // Lazily load the accessibility focus drawable.
        if (mAttachInfo.mAccessibilityFocusDrawable == null) {
            final TypedValue value = new TypedValue();
+3 −9
Original line number Diff line number Diff line
@@ -4910,9 +4910,7 @@ public abstract class AbsListView extends AdapterView<ListAdapter> implements Te
                    if (position >= headerViewsCount && position < footerViewsStart) {
                        // The view will be rebound to new data, clear any
                        // system-managed transient state.
                        if (child.isAccessibilityFocused()) {
                        child.clearAccessibilityFocus();
                        }
                        mRecycler.addScrapView(child, position);
                    }
                }
@@ -4933,9 +4931,7 @@ public abstract class AbsListView extends AdapterView<ListAdapter> implements Te
                    if (position >= headerViewsCount && position < footerViewsStart) {
                        // The view will be rebound to new data, clear any
                        // system-managed transient state.
                        if (child.isAccessibilityFocused()) {
                        child.clearAccessibilityFocus();
                        }
                        mRecycler.addScrapView(child, position);
                    }
                }
@@ -6776,9 +6772,7 @@ public abstract class AbsListView extends AdapterView<ListAdapter> implements Te
        }

        private void clearAccessibilityFromScrap(View view) {
            if (view.isAccessibilityFocused()) {
            view.clearAccessibilityFocus();
            }
            view.setAccessibilityDelegate(null);
        }

+1 −3
Original line number Diff line number Diff line
@@ -18,9 +18,7 @@

    <stroke
        android:width="4dp"
        android:color="@color/accessibility_focus_highlight"
        android:dashWidth="4dp"
        android:dashGap="2dp" />
        android:color="@color/accessibility_focus_highlight" />

    <corners android:radius="2dp" />