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
This commit is contained in:
@@ -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);
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
@@ -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);
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user