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

Commit 2b7842fc authored by Daniel Hsieh's avatar Daniel Hsieh
Browse files

Offsets an additional distance for requestRectangleOnScreen.

In previous, requestRectangleOnScreen would only apply the shortest
movement on the magnifier to the rectangle. However, it will make typing
words out of the screen. Therefore, we add an additional distance for
moving the magnifier to help a user know the surrounding context.

Bug: 148882866
Test: atest FullScreenMagnificationControllerTest
Change-Id: Iee7a4f13395ed8acf3ffa7df759542fcb08190f8
parent c515a0ae
Loading
Loading
Loading
Loading
+31 −4
Original line number Diff line number Diff line
@@ -18,6 +18,7 @@ package com.android.server.accessibility.magnification;

import static android.accessibilityservice.AccessibilityTrace.FLAGS_WINDOW_MANAGER_INTERNAL;
import static android.accessibilityservice.MagnificationConfig.MAGNIFICATION_MODE_FULLSCREEN;
import static android.util.TypedValue.COMPLEX_UNIT_DIP;
import static android.view.accessibility.MagnificationAnimationCallback.STUB_ANIMATION_CALLBACK;

import static com.android.server.accessibility.AccessibilityManagerService.INVALID_SERVICE_ID;
@@ -31,15 +32,20 @@ import android.content.BroadcastReceiver;
import android.content.Context;
import android.content.Intent;
import android.content.IntentFilter;
import android.content.res.CompatibilityInfo;
import android.graphics.Rect;
import android.graphics.Region;
import android.hardware.display.DisplayManagerInternal;
import android.os.Handler;
import android.os.Message;
import android.text.TextUtils;
import android.util.DisplayMetrics;
import android.util.MathUtils;
import android.util.Slog;
import android.util.SparseArray;
import android.util.TypedValue;
import android.view.Display;
import android.view.DisplayInfo;
import android.view.MagnificationSpec;
import android.view.View;
import android.view.accessibility.MagnificationAnimationCallback;
@@ -93,6 +99,8 @@ public class FullScreenMagnificationController implements
    // Whether the following typing focus feature for magnification is enabled.
    private boolean mMagnificationFollowTypingEnabled = true;

    private final DisplayManagerInternal mDisplayManagerInternal;

    /**
     * This class implements {@link WindowManagerInternal.MagnificationCallbacks} and holds
     * magnification information per display.
@@ -395,6 +403,18 @@ public class FullScreenMagnificationController implements
            outRegion.set(mMagnificationRegion);
        }

        private DisplayMetrics getDisplayMetricsForId() {
            final DisplayMetrics outMetrics = new DisplayMetrics();
            final DisplayInfo displayInfo = mDisplayManagerInternal.getDisplayInfo(mDisplayId);
            if (displayInfo != null) {
                displayInfo.getLogicalMetrics(outMetrics,
                        CompatibilityInfo.DEFAULT_COMPATIBILITY_INFO, null);
            } else {
                outMetrics.setToDefaults();
            }
            return outMetrics;
        }

        void requestRectangleOnScreen(int left, int top, int right, int bottom) {
            synchronized (mLock) {
                final Rect magnifiedFrame = mTempRect;
@@ -408,6 +428,12 @@ public class FullScreenMagnificationController implements

                final float scrollX;
                final float scrollY;
                // We offset an additional distance for a user to know the surrounding context.
                DisplayMetrics metrics = getDisplayMetricsForId();
                final float offsetViewportX = (float) magnifFrameInScreenCoords.width() / 4;
                final float offsetViewportY =
                        TypedValue.applyDimension(COMPLEX_UNIT_DIP, 10, metrics);

                if (right - left > magnifFrameInScreenCoords.width()) {
                    final int direction = TextUtils
                            .getLayoutDirectionFromLocale(Locale.getDefault());
@@ -417,9 +443,9 @@ public class FullScreenMagnificationController implements
                        scrollX = right - magnifFrameInScreenCoords.right;
                    }
                } else if (left < magnifFrameInScreenCoords.left) {
                    scrollX = left - magnifFrameInScreenCoords.left;
                    scrollX = left - magnifFrameInScreenCoords.left - offsetViewportX;
                } else if (right > magnifFrameInScreenCoords.right) {
                    scrollX = right - magnifFrameInScreenCoords.right;
                    scrollX = right - magnifFrameInScreenCoords.right + offsetViewportX;
                } else {
                    scrollX = 0;
                }
@@ -427,9 +453,9 @@ public class FullScreenMagnificationController implements
                if (bottom - top > magnifFrameInScreenCoords.height()) {
                    scrollY = top - magnifFrameInScreenCoords.top;
                } else if (top < magnifFrameInScreenCoords.top) {
                    scrollY = top - magnifFrameInScreenCoords.top;
                    scrollY = top - magnifFrameInScreenCoords.top - offsetViewportY;
                } else if (bottom > magnifFrameInScreenCoords.bottom) {
                    scrollY = bottom - magnifFrameInScreenCoords.bottom;
                    scrollY = bottom - magnifFrameInScreenCoords.bottom + offsetViewportY;
                } else {
                    scrollY = 0;
                }
@@ -687,6 +713,7 @@ public class FullScreenMagnificationController implements
        mScreenStateObserver = new ScreenStateObserver(mControllerCtx.getContext(), this);
        mMagnificationInfoChangedCallback = magnificationInfoChangedCallback;
        mScaleProvider = scaleProvider;
        mDisplayManagerInternal = LocalServices.getService(DisplayManagerInternal.class);
    }

    /**
+12 −0
Original line number Diff line number Diff line
@@ -28,6 +28,7 @@ import static org.mockito.ArgumentMatchers.any;
import static org.mockito.ArgumentMatchers.anyInt;
import static org.mockito.ArgumentMatchers.eq;
import static org.mockito.Mockito.doAnswer;
import static org.mockito.Mockito.doReturn;
import static org.mockito.Mockito.mock;
import static org.mockito.Mockito.never;
import static org.mockito.Mockito.reset;
@@ -45,13 +46,16 @@ import android.content.IntentFilter;
import android.graphics.PointF;
import android.graphics.Rect;
import android.graphics.Region;
import android.hardware.display.DisplayManagerInternal;
import android.os.Looper;
import android.view.DisplayInfo;
import android.view.MagnificationSpec;
import android.view.accessibility.MagnificationAnimationCallback;

import androidx.test.InstrumentationRegistry;
import androidx.test.runner.AndroidJUnit4;

import com.android.server.LocalServices;
import com.android.server.accessibility.AccessibilityTraceManager;
import com.android.server.accessibility.test.MessageCapturingHandler;
import com.android.server.wm.WindowManagerInternal;
@@ -113,6 +117,8 @@ public class FullScreenMagnificationControllerTest {

    FullScreenMagnificationController mFullScreenMagnificationController;

    public DisplayManagerInternal mDisplayManagerInternalMock = mock(DisplayManagerInternal.class);

    @Before
    public void setUp() {
        Looper looper = InstrumentationRegistry.getContext().getMainLooper();
@@ -125,6 +131,12 @@ public class FullScreenMagnificationControllerTest {
        when(mMockControllerCtx.getAnimationDuration()).thenReturn(1000L);
        initMockWindowManager();

        final DisplayInfo displayInfo = new DisplayInfo();
        displayInfo.logicalDensityDpi = 300;
        doReturn(displayInfo).when(mDisplayManagerInternalMock).getDisplayInfo(anyInt());
        LocalServices.removeServiceForTest(DisplayManagerInternal.class);
        LocalServices.addService(DisplayManagerInternal.class, mDisplayManagerInternalMock);

        mFullScreenMagnificationController = new FullScreenMagnificationController(
                mMockControllerCtx, new Object(), mRequestObserver, mScaleProvider);
    }