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
This commit is contained in:
Peter_Liang
2021-09-09 15:30:17 +08:00
committed by PETER LIANG
parent 0086704424
commit 809296282a
2 changed files with 19 additions and 17 deletions

View File

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

View File

@@ -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();
}