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

Commit 80929628 authored by Peter_Liang's avatar Peter_Liang Committed by PETER LIANG
Browse files

Fixing the a11y floating menu could overlap the keyboard when rotated in a foldable device.

Root cause:
WindowInsets have different values depend on timing and when to call it.

Actions:
Updating the latest ime inset to the menu when onApplyWindowInsets was triggered, and then adjust the position.

Bug: 200759679
Test: atest AccessibilityFloatingMenuViewTest
Change-Id: I27530b154cb3c89650be69b0d0e2116dc88a7b39
parent 00867044
Loading
Loading
Loading
Loading
+17 −14
Original line number Diff line number Diff line
@@ -21,7 +21,6 @@ import static android.util.MathUtils.constrain;
import static android.util.MathUtils.sq;
import static android.view.WindowInsets.Type.displayCutout;
import static android.view.WindowInsets.Type.ime;
import static android.view.WindowInsets.Type.navigationBars;
import static android.view.WindowInsets.Type.systemBars;

import static java.util.Objects.requireNonNull;
@@ -96,7 +95,6 @@ public class AccessibilityFloatingMenuView extends FrameLayout
    private boolean mIsShowing;
    private boolean mIsDownInEnlargedTouchArea;
    private boolean mIsDragging = false;
    private boolean mImeVisibility;
    @Alignment
    private int mAlignment;
    @SizeType
@@ -122,6 +120,7 @@ public class AccessibilityFloatingMenuView extends FrameLayout
    private int mRelativeToPointerDownY;
    private float mRadius;
    private final Rect mDisplayInsetsRect = new Rect();
    private final Rect mImeInsetsRect = new Rect();
    private final Position mPosition;
    private float mSquareScaledTouchSlop;
    private final Configuration mLastConfiguration;
@@ -517,9 +516,14 @@ public class AccessibilityFloatingMenuView extends FrameLayout
            updateLocationWith(mPosition);
        }

        final boolean currentImeVisibility = insets.isVisible(ime());
        if (currentImeVisibility != mImeVisibility) {
            mImeVisibility = currentImeVisibility;
        final Rect imeInsetsRect = windowMetrics.getWindowInsets().getInsets(ime()).toRect();
        if (!imeInsetsRect.equals(mImeInsetsRect)) {
            if (isImeVisible(imeInsetsRect)) {
                mImeInsetsRect.set(imeInsetsRect);
            } else {
                mImeInsetsRect.setEmpty();
            }

            updateLocationWith(mPosition);
        }

@@ -531,6 +535,11 @@ public class AccessibilityFloatingMenuView extends FrameLayout
                || (side == Alignment.LEFT && downX > currentRawX);
    }

    private boolean isImeVisible(Rect imeInsetsRect) {
        return imeInsetsRect.left != 0 || imeInsetsRect.top != 0 || imeInsetsRect.right != 0
                || imeInsetsRect.bottom != 0;
    }

    private boolean hasExceededTouchSlop(int startX, int startY, int endX, int endY) {
        return (sq(endX - startX) + sq(endY - startY)) > mSquareScaledTouchSlop;
    }
@@ -741,15 +750,9 @@ public class AccessibilityFloatingMenuView extends FrameLayout
     * @return the moving interval if they overlap each other, otherwise 0.
     */
    private int getInterval() {
        if (!mImeVisibility) {
            return 0;
        }

        final WindowMetrics windowMetrics = mWindowManager.getCurrentWindowMetrics();
        final Insets imeInsets = windowMetrics.getWindowInsets().getInsets(
                ime() | navigationBars());
        final int imeY = mDisplayHeight - imeInsets.bottom;
        final int layoutBottomY = mCurrentLayoutParams.y + getWindowHeight();
        final int currentLayoutY = (int) (mPosition.getPercentageY() * getMaxWindowY());
        final int imeY = mDisplayHeight - mImeInsetsRect.bottom;
        final int layoutBottomY = currentLayoutY + getWindowHeight();

        return layoutBottomY > imeY ? (layoutBottomY - imeY) : 0;
    }
+2 −3
Original line number Diff line number Diff line
@@ -21,7 +21,6 @@ import static android.view.View.OVER_SCROLL_ALWAYS;
import static android.view.View.OVER_SCROLL_NEVER;
import static android.view.WindowInsets.Type.displayCutout;
import static android.view.WindowInsets.Type.ime;
import static android.view.WindowInsets.Type.navigationBars;
import static android.view.WindowInsets.Type.systemBars;

import static com.google.common.truth.Truth.assertThat;
@@ -483,8 +482,8 @@ public class AccessibilityFloatingMenuViewTest extends SysuiTestCase {
                mDisplayWindowHeight - (menuView.mCurrentLayoutParams.y + mMenuWindowHeight)
                        + offset;
        return new WindowInsets.Builder()
                .setVisible(ime() | navigationBars(), true)
                .setInsets(ime() | navigationBars(), Insets.of(0, 0, 0, fakeImeHeight))
                .setVisible(ime(), true)
                .setInsets(ime(), Insets.of(0, 0, 0, fakeImeHeight))
                .build();
    }