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

Commit fd76567f authored by mincheli's avatar mincheli
Browse files

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
parent f2c9466e
Loading
Loading
Loading
Loading
+6 −1
Original line number Diff line number Diff line
@@ -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);
    }
+40 −2
Original line number Diff line number Diff line
@@ -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
+5 −1
Original line number Diff line number Diff line
@@ -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);
+13 −0
Original line number Diff line number Diff line
@@ -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());
    }
}
+5 −1
Original line number Diff line number Diff line
@@ -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();
    }