Magnification window should not block bottom navigation bar
To prevent a dragging gesture from misdetecting as a swipe up gesture when moving the magnification window from the bottom navigation bar, the magnification window should not overlapped the gesture-detection region of the bottom navigation bar. So we have to constrain the position of the magnification window if the navigation bar mode is NAV_BAR_MODE_2BUTTON or NAV_BAR_MODE_GESTURAL. Bug: 151394480 Test: atest com.android.systemui.accessibility Change-Id: If0e3b8bcdcde8ce218e6f5087922783be6ab80c3
This commit is contained in:
@@ -37,6 +37,7 @@ import com.android.internal.graphics.SfVsyncFrameCallbackProvider;
|
||||
import com.android.systemui.SystemUI;
|
||||
import com.android.systemui.dagger.SysUISingleton;
|
||||
import com.android.systemui.dagger.qualifiers.Main;
|
||||
import com.android.systemui.navigationbar.NavigationModeController;
|
||||
import com.android.systemui.statusbar.CommandQueue;
|
||||
|
||||
import javax.inject.Inject;
|
||||
@@ -66,7 +67,8 @@ public class WindowMagnification extends SystemUI implements WindowMagnifierCall
|
||||
|
||||
@Inject
|
||||
public WindowMagnification(Context context, @Main Handler mainHandler,
|
||||
CommandQueue commandQueue, ModeSwitchesController modeSwitchesController) {
|
||||
CommandQueue commandQueue, ModeSwitchesController modeSwitchesController,
|
||||
NavigationModeController navigationModeController) {
|
||||
super(context);
|
||||
mHandler = mainHandler;
|
||||
mLastConfiguration = new Configuration(context.getResources().getConfiguration());
|
||||
@@ -77,6 +79,9 @@ public class WindowMagnification extends SystemUI implements WindowMagnifierCall
|
||||
final WindowMagnificationController controller = new WindowMagnificationController(mContext,
|
||||
mHandler, new SfVsyncFrameCallbackProvider(), null,
|
||||
new SurfaceControl.Transaction(), this);
|
||||
final int navBarMode = navigationModeController.addListener(
|
||||
controller::onNavigationModeChanged);
|
||||
controller.onNavigationModeChanged(navBarMode);
|
||||
mWindowMagnificationAnimationController = new WindowMagnificationAnimationController(
|
||||
mContext, controller);
|
||||
}
|
||||
|
||||
@@ -17,6 +17,8 @@
|
||||
package com.android.systemui.accessibility;
|
||||
|
||||
import static android.view.WindowManager.LayoutParams.LAYOUT_IN_DISPLAY_CUTOUT_MODE_SHORT_EDGES;
|
||||
import static android.view.WindowManagerPolicyConstants.NAV_BAR_MODE_2BUTTON;
|
||||
import static android.view.WindowManagerPolicyConstants.NAV_BAR_MODE_GESTURAL;
|
||||
|
||||
import android.annotation.NonNull;
|
||||
import android.annotation.Nullable;
|
||||
@@ -117,6 +119,9 @@ class WindowMagnificationController implements View.OnTouchListener, SurfaceHold
|
||||
// The boundary of magnification frame.
|
||||
private final Rect mMagnificationFrameBoundary = new Rect();
|
||||
|
||||
private int mNavBarMode;
|
||||
private int mNavGestureHeight;
|
||||
|
||||
private final SfVsyncFrameCallbackProvider mSfVsyncFrameProvider;
|
||||
private Choreographer.FrameCallback mMirrorViewGeometryVsyncCallback;
|
||||
private Locale mLocale;
|
||||
@@ -195,6 +200,19 @@ class WindowMagnificationController implements View.OnTouchListener, SurfaceHold
|
||||
R.dimen.magnification_drag_view_size);
|
||||
mOuterBorderSize = mResources.getDimensionPixelSize(
|
||||
R.dimen.magnification_outer_border_margin);
|
||||
updateNavigationBarDimensions();
|
||||
}
|
||||
|
||||
private void updateNavigationBarDimensions() {
|
||||
if (!supportsSwipeUpGesture()) {
|
||||
mNavGestureHeight = 0;
|
||||
return;
|
||||
}
|
||||
mNavGestureHeight = (mDisplaySize.x > mDisplaySize.y)
|
||||
? mResources.getDimensionPixelSize(
|
||||
com.android.internal.R.dimen.navigation_bar_height_landscape)
|
||||
: mResources.getDimensionPixelSize(
|
||||
com.android.internal.R.dimen.navigation_bar_gesture_height);
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -239,6 +257,13 @@ class WindowMagnificationController implements View.OnTouchListener, SurfaceHold
|
||||
}
|
||||
}
|
||||
|
||||
/** Handles MirrorWindow position when the navigation bar mode changed. */
|
||||
public void onNavigationModeChanged(int mode) {
|
||||
mNavBarMode = mode;
|
||||
updateNavigationBarDimensions();
|
||||
updateMirrorViewLayout();
|
||||
}
|
||||
|
||||
/** Handles MirrorWindow position when the device rotation changed. */
|
||||
private void onRotate() {
|
||||
final Display display = mContext.getDisplay();
|
||||
@@ -246,6 +271,7 @@ class WindowMagnificationController implements View.OnTouchListener, SurfaceHold
|
||||
display.getRealSize(mDisplaySize);
|
||||
setMagnificationFrameBoundary();
|
||||
mRotation = display.getRotation();
|
||||
updateNavigationBarDimensions();
|
||||
|
||||
if (!isWindowVisible()) {
|
||||
return;
|
||||
@@ -401,15 +427,23 @@ class WindowMagnificationController implements View.OnTouchListener, SurfaceHold
|
||||
* moved close to the screen edges.
|
||||
*/
|
||||
private void updateMirrorViewLayout() {
|
||||
if (!isWindowVisible()) {
|
||||
return;
|
||||
}
|
||||
final int maxMirrorViewX = mDisplaySize.x - mMirrorView.getWidth();
|
||||
final int maxMirrorViewY = mDisplaySize.y - mMirrorView.getHeight() - mNavGestureHeight;
|
||||
WindowManager.LayoutParams params =
|
||||
(WindowManager.LayoutParams) mMirrorView.getLayoutParams();
|
||||
params.x = mMagnificationFrame.left - mMirrorSurfaceMargin;
|
||||
params.y = mMagnificationFrame.top - mMirrorSurfaceMargin;
|
||||
// If nav bar mode supports swipe-up gesture, the Y position of mirror view should not
|
||||
// overlap nav bar window to prevent window-dragging obscured.
|
||||
if (supportsSwipeUpGesture()) {
|
||||
params.y = Math.min(params.y, maxMirrorViewY);
|
||||
}
|
||||
|
||||
// Translates MirrorView position to make MirrorSurfaceView that is inside MirrorView
|
||||
// able to move close to the screen edges.
|
||||
final int maxMirrorViewX = mDisplaySize.x - mMirrorView.getWidth();
|
||||
final int maxMirrorViewY = mDisplaySize.y - mMirrorView.getHeight();
|
||||
final float translationX;
|
||||
final float translationY;
|
||||
if (params.x < 0) {
|
||||
@@ -621,6 +655,10 @@ class WindowMagnificationController implements View.OnTouchListener, SurfaceHold
|
||||
return mMirrorView != null;
|
||||
}
|
||||
|
||||
private boolean supportsSwipeUpGesture() {
|
||||
return mNavBarMode == NAV_BAR_MODE_2BUTTON || mNavBarMode == NAV_BAR_MODE_GESTURAL;
|
||||
}
|
||||
|
||||
private CharSequence formatStateDescription(float scale) {
|
||||
// Cache the locale-appropriate NumberFormat. Configuration locale is guaranteed
|
||||
// non-null, so the first time this is called we will always get the appropriate
|
||||
|
||||
@@ -36,6 +36,7 @@ import android.view.accessibility.IWindowMagnificationConnectionCallback;
|
||||
import androidx.test.filters.SmallTest;
|
||||
|
||||
import com.android.systemui.SysuiTestCase;
|
||||
import com.android.systemui.navigationbar.NavigationModeController;
|
||||
import com.android.systemui.statusbar.CommandQueue;
|
||||
|
||||
import org.junit.Before;
|
||||
@@ -65,6 +66,8 @@ public class IWindowMagnificationConnectionTest extends SysuiTestCase {
|
||||
@Mock
|
||||
private ModeSwitchesController mModeSwitchesController;
|
||||
@Mock
|
||||
private NavigationModeController mNavigationModeController;
|
||||
@Mock
|
||||
private IRemoteMagnificationAnimationCallback mAnimationCallback;
|
||||
private IWindowMagnificationConnection mIWindowMagnificationConnection;
|
||||
private WindowMagnification mWindowMagnification;
|
||||
@@ -79,7 +82,8 @@ public class IWindowMagnificationConnectionTest extends SysuiTestCase {
|
||||
}).when(mAccessibilityManager).setWindowMagnificationConnection(
|
||||
any(IWindowMagnificationConnection.class));
|
||||
mWindowMagnification = new WindowMagnification(getContext(),
|
||||
getContext().getMainThreadHandler(), mCommandQueue, mModeSwitchesController);
|
||||
getContext().getMainThreadHandler(), mCommandQueue, mModeSwitchesController,
|
||||
mNavigationModeController);
|
||||
mWindowMagnification.mWindowMagnificationAnimationController =
|
||||
mWindowMagnificationAnimationController;
|
||||
mWindowMagnification.requestWindowMagnificationConnection(true);
|
||||
|
||||
@@ -17,6 +17,7 @@
|
||||
package com.android.systemui.accessibility;
|
||||
|
||||
import static android.view.Choreographer.FrameCallback;
|
||||
import static android.view.WindowManagerPolicyConstants.NAV_BAR_MODE_GESTURAL;
|
||||
import static android.view.accessibility.AccessibilityNodeInfo.AccessibilityAction;
|
||||
|
||||
import static org.hamcrest.Matchers.containsString;
|
||||
@@ -28,6 +29,7 @@ import static org.junit.Assert.assertTrue;
|
||||
import static org.mockito.ArgumentMatchers.any;
|
||||
import static org.mockito.ArgumentMatchers.anyInt;
|
||||
import static org.mockito.ArgumentMatchers.anyLong;
|
||||
import static org.mockito.ArgumentMatchers.eq;
|
||||
import static org.mockito.Mockito.atLeastOnce;
|
||||
import static org.mockito.Mockito.doAnswer;
|
||||
import static org.mockito.Mockito.verify;
|
||||
@@ -294,4 +296,15 @@ public class WindowMagnificationControllerTest extends SysuiTestCase {
|
||||
assertTrue(
|
||||
mMirrorView.performAccessibilityAction(R.id.accessibility_action_move_left, null));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void onNavigationModeChanged_updateMirrorViewLayout() {
|
||||
mInstrumentation.runOnMainSync(() -> {
|
||||
mWindowMagnificationController.enableWindowMagnification(Float.NaN, Float.NaN,
|
||||
Float.NaN);
|
||||
mWindowMagnificationController.onNavigationModeChanged(NAV_BAR_MODE_GESTURAL);
|
||||
});
|
||||
|
||||
verify(mWindowManager).updateViewLayout(eq(mMirrorView), any());
|
||||
}
|
||||
}
|
||||
|
||||
@@ -35,6 +35,7 @@ import android.view.accessibility.IWindowMagnificationConnectionCallback;
|
||||
import androidx.test.filters.SmallTest;
|
||||
|
||||
import com.android.systemui.SysuiTestCase;
|
||||
import com.android.systemui.navigationbar.NavigationModeController;
|
||||
import com.android.systemui.statusbar.CommandQueue;
|
||||
|
||||
import org.junit.Before;
|
||||
@@ -53,6 +54,8 @@ public class WindowMagnificationTest extends SysuiTestCase {
|
||||
private AccessibilityManager mAccessibilityManager;
|
||||
@Mock
|
||||
private ModeSwitchesController mModeSwitchesController;
|
||||
@Mock
|
||||
private NavigationModeController mNavigationModeController;
|
||||
private CommandQueue mCommandQueue;
|
||||
private WindowMagnification mWindowMagnification;
|
||||
|
||||
@@ -63,7 +66,8 @@ public class WindowMagnificationTest extends SysuiTestCase {
|
||||
|
||||
mCommandQueue = new CommandQueue(getContext());
|
||||
mWindowMagnification = new WindowMagnification(getContext(),
|
||||
getContext().getMainThreadHandler(), mCommandQueue, mModeSwitchesController);
|
||||
getContext().getMainThreadHandler(), mCommandQueue, mModeSwitchesController,
|
||||
mNavigationModeController);
|
||||
mWindowMagnification.start();
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user