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

Commit 997aa406 authored by Alan Viverette's avatar Alan Viverette
Browse files

Draw accessibility focus in View rather than ViewRootImpl

This ensures that the focus rect position is correct when running in
render thread accelerated mode. Also adds a missing call to draw the
overlay.

BUG: 16796647
BUG: 17063342
Change-Id: I377e5eaea89d3f20c8c7e82c264a0f106021d58b
parent 6825368d
Loading
Loading
Loading
Loading
+46 −0
Original line number Original line Diff line number Diff line
@@ -13831,6 +13831,7 @@ public class View implements Drawable.Callback, KeyEvent.Callback,
                    } else {
                    } else {
                        draw(canvas);
                        draw(canvas);
                    }
                    }
                    drawAccessibilityFocus(canvas);
                }
                }
            } finally {
            } finally {
                renderNode.end(canvas);
                renderNode.end(canvas);
@@ -14125,6 +14126,7 @@ public class View implements Drawable.Callback, KeyEvent.Callback,
            } else {
            } else {
                draw(canvas);
                draw(canvas);
            }
            }
            drawAccessibilityFocus(canvas);
            canvas.restoreToCount(restoreCount);
            canvas.restoreToCount(restoreCount);
            canvas.setBitmap(null);
            canvas.setBitmap(null);
@@ -14199,6 +14201,7 @@ public class View implements Drawable.Callback, KeyEvent.Callback,
        } else {
        } else {
            draw(canvas);
            draw(canvas);
        }
        }
        drawAccessibilityFocus(canvas);
        mPrivateFlags = flags;
        mPrivateFlags = flags;
@@ -14792,9 +14795,13 @@ public class View implements Drawable.Callback, KeyEvent.Callback,
                    if ((mPrivateFlags & PFLAG_SKIP_DRAW) == PFLAG_SKIP_DRAW) {
                    if ((mPrivateFlags & PFLAG_SKIP_DRAW) == PFLAG_SKIP_DRAW) {
                        mPrivateFlags &= ~PFLAG_DIRTY_MASK;
                        mPrivateFlags &= ~PFLAG_DIRTY_MASK;
                        dispatchDraw(canvas);
                        dispatchDraw(canvas);
                        if (mOverlay != null && !mOverlay.isEmpty()) {
                            mOverlay.getOverlayView().draw(canvas);
                        }
                    } else {
                    } else {
                        draw(canvas);
                        draw(canvas);
                    }
                    }
                    drawAccessibilityFocus(canvas);
                } else {
                } else {
                    mPrivateFlags &= ~PFLAG_DIRTY_MASK;
                    mPrivateFlags &= ~PFLAG_DIRTY_MASK;
                    ((HardwareCanvas) canvas).drawRenderNode(renderNode, null, flags);
                    ((HardwareCanvas) canvas).drawRenderNode(renderNode, null, flags);
@@ -15045,6 +15052,45 @@ 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.getBoundsInParent(bounds);
        } else {
            bounds.set(0, 0, mRight - mLeft, mBottom - mTop);
        }
        canvas.translate(mScrollX, mScrollY);
        drawable.setBounds(bounds);
        drawable.draw(canvas);
        canvas.translate(-mScrollX, -mScrollY);
    }
    /**
    /**
     * Draws the background onto the specified canvas.
     * Draws the background onto the specified canvas.
     *
     *
+2 −68
Original line number Original line Diff line number Diff line
@@ -2244,7 +2244,6 @@ public final class ViewRootImpl implements ViewParent,
            canvas.drawHardwareLayer(mResizeBuffer, mHardwareXOffset, mHardwareYOffset,
            canvas.drawHardwareLayer(mResizeBuffer, mHardwareXOffset, mHardwareYOffset,
                    mResizePaint);
                    mResizePaint);
        }
        }
        drawAccessibilityFocusedDrawableIfNeeded(canvas);
    }
    }


    /**
    /**
@@ -2462,25 +2461,9 @@ public final class ViewRootImpl implements ViewParent,
                if (mHardwareYOffset != yOffset || mHardwareXOffset != xOffset) {
                if (mHardwareYOffset != yOffset || mHardwareXOffset != xOffset) {
                    mHardwareYOffset = yOffset;
                    mHardwareYOffset = yOffset;
                    mHardwareXOffset = xOffset;
                    mHardwareXOffset = xOffset;
                    invalidateRoot = true;
                }
                mResizeAlpha = resizeAlpha;

                if (!invalidateRoot) {
                    // If accessibility focus moved, invalidate the root.
                    final Drawable drawable = mAttachInfo.mAccessibilityFocusDrawable;
                    if (drawable != null) {
                        final Rect bounds = mAttachInfo.mTmpInvalRect;
                        if (getAccessibilityFocusedRect(bounds)
                                && !bounds.equals(drawable.getBounds())) {
                            invalidateRoot = true;
                        }
                    }
                }

                if (invalidateRoot) {
                    mAttachInfo.mHardwareRenderer.invalidateRoot();
                    mAttachInfo.mHardwareRenderer.invalidateRoot();
                }
                }
                mResizeAlpha = resizeAlpha;


                dirty.setEmpty();
                dirty.setEmpty();


@@ -2600,8 +2583,6 @@ public final class ViewRootImpl implements ViewParent,
                attachInfo.mSetIgnoreDirtyState = false;
                attachInfo.mSetIgnoreDirtyState = false;


                mView.draw(canvas);
                mView.draw(canvas);

                drawAccessibilityFocusedDrawableIfNeeded(canvas);
            } finally {
            } finally {
                if (!attachInfo.mSetIgnoreDirtyState) {
                if (!attachInfo.mSetIgnoreDirtyState) {
                    // Only clear the flag if it was not set during the mView.draw() call
                    // Only clear the flag if it was not set during the mView.draw() call
@@ -2625,54 +2606,7 @@ public final class ViewRootImpl implements ViewParent,
        return true;
        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);
            }
        }
    }

    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 true;
    }

    private Drawable getAccessibilityFocusedDrawable() {
        // Lazily load the accessibility focus drawable.
        // Lazily load the accessibility focus drawable.
        if (mAttachInfo.mAccessibilityFocusDrawable == null) {
        if (mAttachInfo.mAccessibilityFocusDrawable == null) {
            final TypedValue value = new TypedValue();
            final TypedValue value = new TypedValue();