diff --git a/packages/SystemUI/res/drawable/accessibility_window_magnification_button_bg.xml b/packages/SystemUI/res/drawable/accessibility_window_magnification_button_bg.xml
new file mode 100644
index 0000000000000..eefe36459f9cd
--- /dev/null
+++ b/packages/SystemUI/res/drawable/accessibility_window_magnification_button_bg.xml
@@ -0,0 +1,26 @@
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/packages/SystemUI/res/drawable/ic_magnification_corner_bottom_left.xml b/packages/SystemUI/res/drawable/ic_magnification_corner_bottom_left.xml
new file mode 100644
index 0000000000000..d25cd65581165
--- /dev/null
+++ b/packages/SystemUI/res/drawable/ic_magnification_corner_bottom_left.xml
@@ -0,0 +1,33 @@
+
+
+
+
+
diff --git a/packages/SystemUI/res/drawable/ic_magnification_corner_bottom_right.xml b/packages/SystemUI/res/drawable/ic_magnification_corner_bottom_right.xml
new file mode 100644
index 0000000000000..bb6df3ac1b32c
--- /dev/null
+++ b/packages/SystemUI/res/drawable/ic_magnification_corner_bottom_right.xml
@@ -0,0 +1,33 @@
+
+
+
+
+
diff --git a/packages/SystemUI/res/drawable/ic_magnification_corner_top_left.xml b/packages/SystemUI/res/drawable/ic_magnification_corner_top_left.xml
new file mode 100644
index 0000000000000..8f259309b7473
--- /dev/null
+++ b/packages/SystemUI/res/drawable/ic_magnification_corner_top_left.xml
@@ -0,0 +1,33 @@
+
+
+
+
+
diff --git a/packages/SystemUI/res/drawable/ic_magnification_corner_top_right.xml b/packages/SystemUI/res/drawable/ic_magnification_corner_top_right.xml
new file mode 100644
index 0000000000000..291db44ba8ba4
--- /dev/null
+++ b/packages/SystemUI/res/drawable/ic_magnification_corner_top_right.xml
@@ -0,0 +1,33 @@
+
+
+
+
+
diff --git a/packages/SystemUI/res/layout/window_magnifier_view.xml b/packages/SystemUI/res/layout/window_magnifier_view.xml
index 0bff47ccf722a..0be732855deeb 100644
--- a/packages/SystemUI/res/layout/window_magnifier_view.xml
+++ b/packages/SystemUI/res/layout/window_magnifier_view.xml
@@ -40,19 +40,22 @@
android:id="@+id/top_handle"
android:layout_width="match_parent"
android:layout_height="@dimen/magnification_border_drag_size"
- android:layout_alignParentTop="true"/>
+ android:layout_alignParentTop="true"
+ android:accessibilityTraversalAfter="@id/left_handle"/>
+ android:layout_alignParentEnd="true"
+ android:accessibilityTraversalAfter="@id/top_handle"/>
+ android:layout_alignParentBottom="true"
+ android:accessibilityTraversalAfter="@id/right_handle"/>
+
+
+
+
+
+
+
+
#FCFCFC
#E0E0E0
#252525
+ #0680FD
+ #FAFAFA
+ #252525
+ #0680FD
@android:color/transparent
diff --git a/packages/SystemUI/res/values/strings.xml b/packages/SystemUI/res/values/strings.xml
index 9324e8f3babb2..8c1ffb2920ab5 100644
--- a/packages/SystemUI/res/values/strings.xml
+++ b/packages/SystemUI/res/values/strings.xml
@@ -2118,6 +2118,8 @@
Magnify part of screen
Switch
+
+ Drag corner to resize
Allow diagonal scrolling
diff --git a/packages/SystemUI/src/com/android/systemui/accessibility/WindowMagnificationController.java b/packages/SystemUI/src/com/android/systemui/accessibility/WindowMagnificationController.java
index e3c04a379fe44..25462a2bc9e90 100644
--- a/packages/SystemUI/src/com/android/systemui/accessibility/WindowMagnificationController.java
+++ b/packages/SystemUI/src/com/android/systemui/accessibility/WindowMagnificationController.java
@@ -158,6 +158,10 @@ class WindowMagnificationController implements View.OnTouchListener, SurfaceHold
private View mTopDrag;
private View mRightDrag;
private View mBottomDrag;
+ private ImageView mTopLeftCornerView;
+ private ImageView mTopRightCornerView;
+ private ImageView mBottomLeftCornerView;
+ private ImageView mBottomRightCornerView;
private final Configuration mConfiguration;
@NonNull
@@ -357,13 +361,15 @@ class WindowMagnificationController implements View.OnTouchListener, SurfaceHold
return false;
}
- private void changeMagnificationSize(@MagnificationSize int index) {
+ @VisibleForTesting
+ void changeMagnificationSize(@MagnificationSize int index) {
final int initSize = Math.min(mWindowBounds.width(), mWindowBounds.height()) / 3;
int size = (int) (initSize * MAGNIFICATION_SCALE_OPTIONS[index]);
setWindowSize(size, size);
}
- private void setEditMagnifierSizeMode(boolean enable) {
+ @VisibleForTesting
+ void setEditMagnifierSizeMode(boolean enable) {
mEditSizeEnable = enable;
applyResourcesValues();
@@ -641,10 +647,37 @@ class WindowMagnificationController implements View.OnTouchListener, SurfaceHold
Region regionInsideDragBorder = new Region(mBorderDragSize, mBorderDragSize,
mMirrorView.getWidth() - mBorderDragSize,
mMirrorView.getHeight() - mBorderDragSize);
+
+ Region tapExcludeRegion = new Region();
+
Rect dragArea = new Rect();
mDragView.getHitRect(dragArea);
- regionInsideDragBorder.op(dragArea, Region.Op.DIFFERENCE);
+ Rect topLeftArea = new Rect();
+ mTopLeftCornerView.getHitRect(topLeftArea);
+
+ Rect topRightArea = new Rect();
+ mTopRightCornerView.getHitRect(topRightArea);
+
+ Rect bottomLeftArea = new Rect();
+ mBottomLeftCornerView.getHitRect(bottomLeftArea);
+
+ Rect bottomRightArea = new Rect();
+ mBottomRightCornerView.getHitRect(bottomRightArea);
+
+ Rect closeArea = new Rect();
+ mCloseView.getHitRect(closeArea);
+
+ // add tapExcludeRegion for Drag or close
+ tapExcludeRegion.op(dragArea, Region.Op.UNION);
+ tapExcludeRegion.op(topLeftArea, Region.Op.UNION);
+ tapExcludeRegion.op(topRightArea, Region.Op.UNION);
+ tapExcludeRegion.op(bottomLeftArea, Region.Op.UNION);
+ tapExcludeRegion.op(bottomRightArea, Region.Op.UNION);
+ tapExcludeRegion.op(closeArea, Region.Op.UNION);
+
+ regionInsideDragBorder.op(tapExcludeRegion, Region.Op.DIFFERENCE);
+
return regionInsideDragBorder;
}
@@ -758,6 +791,10 @@ class WindowMagnificationController implements View.OnTouchListener, SurfaceHold
mRightDrag = mMirrorView.findViewById(R.id.right_handle);
mBottomDrag = mMirrorView.findViewById(R.id.bottom_handle);
mCloseView = mMirrorView.findViewById(R.id.close_button);
+ mTopRightCornerView = mMirrorView.findViewById(R.id.top_right_corner);
+ mTopLeftCornerView = mMirrorView.findViewById(R.id.top_left_corner);
+ mBottomRightCornerView = mMirrorView.findViewById(R.id.bottom_right_corner);
+ mBottomLeftCornerView = mMirrorView.findViewById(R.id.bottom_left_corner);
mDragView.setOnTouchListener(this);
mLeftDrag.setOnTouchListener(this);
@@ -765,6 +802,10 @@ class WindowMagnificationController implements View.OnTouchListener, SurfaceHold
mRightDrag.setOnTouchListener(this);
mBottomDrag.setOnTouchListener(this);
mCloseView.setOnTouchListener(this);
+ mTopLeftCornerView.setOnTouchListener(this);
+ mTopRightCornerView.setOnTouchListener(this);
+ mBottomLeftCornerView.setOnTouchListener(this);
+ mBottomRightCornerView.setOnTouchListener(this);
}
/**
@@ -833,8 +874,16 @@ class WindowMagnificationController implements View.OnTouchListener, SurfaceHold
@Override
public boolean onTouch(View v, MotionEvent event) {
- if (v == mDragView || v == mLeftDrag || v == mTopDrag || v == mRightDrag
- || v == mBottomDrag || v == mCloseView) {
+ if (v == mDragView
+ || v == mLeftDrag
+ || v == mTopDrag
+ || v == mRightDrag
+ || v == mBottomDrag
+ || v == mTopLeftCornerView
+ || v == mTopRightCornerView
+ || v == mBottomLeftCornerView
+ || v == mBottomRightCornerView
+ || v == mCloseView) {
return mGestureDetector.onTouch(v, event);
}
return false;
@@ -1197,7 +1246,7 @@ class WindowMagnificationController implements View.OnTouchListener, SurfaceHold
@Override
public boolean onDrag(View view, float offsetX, float offsetY) {
if (mEditSizeEnable) {
- changeWindowSize(view, offsetX, offsetY);
+ return changeWindowSize(view, offsetX, offsetY);
} else {
move((int) offsetX, (int) offsetY);
}
@@ -1222,13 +1271,47 @@ class WindowMagnificationController implements View.OnTouchListener, SurfaceHold
if (mEditSizeEnable) {
mDragView.setVisibility(View.GONE);
mCloseView.setVisibility(View.VISIBLE);
+ mTopRightCornerView.setVisibility(View.VISIBLE);
+ mTopLeftCornerView.setVisibility(View.VISIBLE);
+ mBottomRightCornerView.setVisibility(View.VISIBLE);
+ mBottomLeftCornerView.setVisibility(View.VISIBLE);
} else {
mDragView.setVisibility(View.VISIBLE);
mCloseView.setVisibility(View.GONE);
+ mTopRightCornerView.setVisibility(View.GONE);
+ mTopLeftCornerView.setVisibility(View.GONE);
+ mBottomRightCornerView.setVisibility(View.GONE);
+ mBottomLeftCornerView.setVisibility(View.GONE);
}
}
- public boolean changeWindowSize(View view, float offsetX, float offsetY) {
+ private boolean changeWindowSize(View view, float offsetX, float offsetY) {
+ if (view == mLeftDrag) {
+ changeMagnificationFrameSize(offsetX, 0, 0, 0);
+ } else if (view == mRightDrag) {
+ changeMagnificationFrameSize(0, 0, offsetX, 0);
+ } else if (view == mTopDrag) {
+ changeMagnificationFrameSize(0, offsetY, 0, 0);
+ } else if (view == mBottomDrag) {
+ changeMagnificationFrameSize(0, 0, 0, offsetY);
+ } else if (view == mTopLeftCornerView) {
+ changeMagnificationFrameSize(offsetX, offsetY, 0, 0);
+ } else if (view == mTopRightCornerView) {
+ changeMagnificationFrameSize(0, offsetY, offsetX, 0);
+ } else if (view == mBottomLeftCornerView) {
+ changeMagnificationFrameSize(offsetX, 0, 0, offsetY);
+ } else if (view == mBottomRightCornerView) {
+ changeMagnificationFrameSize(0, 0, offsetX, offsetY);
+ } else {
+ return false;
+ }
+
+ return true;
+ }
+
+ private void changeMagnificationFrameSize(
+ float leftOffset, float topOffset, float rightOffset,
+ float bottomOffset) {
boolean bRTL = isRTL(mContext);
final int initSize = Math.min(mWindowBounds.width(), mWindowBounds.height()) / 3;
@@ -1238,54 +1321,26 @@ class WindowMagnificationController implements View.OnTouchListener, SurfaceHold
Rect tempRect = new Rect();
tempRect.set(mMagnificationFrame);
- if (view == mLeftDrag) {
- if (bRTL) {
- tempRect.right += offsetX;
- if (tempRect.right > mWindowBounds.width()) {
- return false;
- }
- } else {
- tempRect.left += offsetX;
- if (tempRect.left < 0) {
- return false;
- }
- }
- } else if (view == mRightDrag) {
- if (bRTL) {
- tempRect.left += offsetX;
- if (tempRect.left < 0) {
- return false;
- }
- } else {
- tempRect.right += offsetX;
- if (tempRect.right > mWindowBounds.width()) {
- return false;
- }
- }
- } else if (view == mTopDrag) {
- tempRect.top += offsetY;
- if (tempRect.top < 0) {
- return false;
- }
- } else if (view == mBottomDrag) {
- tempRect.bottom += offsetY;
- if (tempRect.bottom > mWindowBounds.height()) {
- return false;
- }
+ if (bRTL) {
+ tempRect.left += (int) (rightOffset);
+ tempRect.right += (int) (leftOffset);
+ } else {
+ tempRect.right += (int) (rightOffset);
+ tempRect.left += (int) (leftOffset);
}
+ tempRect.top += (int) (topOffset);
+ tempRect.bottom += (int) (bottomOffset);
if (tempRect.width() < initSize || tempRect.height() < initSize
|| tempRect.width() > maxWidthSize || tempRect.height() > maxHeightSize) {
- return false;
+ return;
}
-
mMagnificationFrame.set(tempRect);
computeBounceAnimationScale();
calculateMagnificationFrameBoundary();
modifyWindowMagnification(true);
- return true;
}
private static boolean isRTL(Context context) {
diff --git a/packages/SystemUI/src/com/android/systemui/accessibility/WindowMagnificationSettings.java b/packages/SystemUI/src/com/android/systemui/accessibility/WindowMagnificationSettings.java
index 9cffd5d609a72..069c0f656d7bd 100644
--- a/packages/SystemUI/src/com/android/systemui/accessibility/WindowMagnificationSettings.java
+++ b/packages/SystemUI/src/com/android/systemui/accessibility/WindowMagnificationSettings.java
@@ -103,7 +103,7 @@ class WindowMagnificationSettings implements MagnificationGestureDetector.OnGest
MagnificationSize.LARGE,
})
/** Denotes the Magnification size type. */
- @interface MagnificationSize {
+ public @interface MagnificationSize {
int NONE = 0;
int SMALL = 1;
int MEDIUM = 2;
diff --git a/packages/SystemUI/tests/src/com/android/systemui/accessibility/WindowMagnificationControllerTest.java b/packages/SystemUI/tests/src/com/android/systemui/accessibility/WindowMagnificationControllerTest.java
index 69ccc8b88bd8a..57ca9c0642243 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/accessibility/WindowMagnificationControllerTest.java
+++ b/packages/SystemUI/tests/src/com/android/systemui/accessibility/WindowMagnificationControllerTest.java
@@ -902,6 +902,97 @@ public class WindowMagnificationControllerTest extends SysuiTestCase {
assertEquals(bounds.width(), actualWindowWidth.get());
}
+ @Test
+ public void changeMagnificationSize_expectedWindowSize() {
+ final Rect bounds = mWindowManager.getCurrentWindowMetrics().getBounds();
+
+ final float magnificationScaleLarge = 2.5f;
+ final int initSize = Math.min(bounds.width(), bounds.height()) / 3;
+ final int magnificationSize = (int) (initSize * magnificationScaleLarge);
+
+ final int expectedWindowHeight = magnificationSize;
+ final int expectedWindowWidth = magnificationSize;
+
+ mInstrumentation.runOnMainSync(
+ () ->
+ mWindowMagnificationController.enableWindowMagnificationInternal(
+ Float.NaN, Float.NaN, Float.NaN));
+
+ final AtomicInteger actualWindowHeight = new AtomicInteger();
+ final AtomicInteger actualWindowWidth = new AtomicInteger();
+ mInstrumentation.runOnMainSync(
+ () -> {
+ mWindowMagnificationController.changeMagnificationSize(
+ WindowMagnificationSettings.MagnificationSize.LARGE);
+ actualWindowHeight.set(mWindowManager.getLayoutParamsFromAttachedView().height);
+ actualWindowWidth.set(mWindowManager.getLayoutParamsFromAttachedView().width);
+ });
+
+ assertEquals(expectedWindowHeight, actualWindowHeight.get());
+ assertEquals(expectedWindowWidth, actualWindowWidth.get());
+ }
+
+ @Test
+ public void editModeOnDragCorner_resizesWindow() {
+ final Rect bounds = mWindowManager.getCurrentWindowMetrics().getBounds();
+
+ final int startingSize = (int) (bounds.width() / 2);
+
+ mInstrumentation.runOnMainSync(
+ () ->
+ mWindowMagnificationController.enableWindowMagnificationInternal(
+ Float.NaN, Float.NaN, Float.NaN));
+
+ final AtomicInteger actualWindowHeight = new AtomicInteger();
+ final AtomicInteger actualWindowWidth = new AtomicInteger();
+
+ mInstrumentation.runOnMainSync(
+ () -> {
+ mWindowMagnificationController.setWindowSize(startingSize, startingSize);
+ mWindowMagnificationController.setEditMagnifierSizeMode(true);
+ });
+
+ waitForIdleSync();
+
+ mInstrumentation.runOnMainSync(
+ () -> {
+ mWindowMagnificationController
+ .onDrag(getInternalView(R.id.bottom_right_corner), 2f, 1f);
+ actualWindowHeight.set(mWindowManager.getLayoutParamsFromAttachedView().height);
+ actualWindowWidth.set(mWindowManager.getLayoutParamsFromAttachedView().width);
+ });
+
+ assertEquals(startingSize + 1, actualWindowHeight.get());
+ assertEquals(startingSize + 2, actualWindowWidth.get());
+ }
+
+ @Test
+ public void editModeOnDragEdge_resizesWindowInOnlyOneDirection() {
+ final Rect bounds = mWindowManager.getCurrentWindowMetrics().getBounds();
+
+ final int startingSize = (int) (bounds.width() / 2f);
+
+ mInstrumentation.runOnMainSync(
+ () ->
+ mWindowMagnificationController.enableWindowMagnificationInternal(
+ Float.NaN, Float.NaN, Float.NaN));
+
+ final AtomicInteger actualWindowHeight = new AtomicInteger();
+ final AtomicInteger actualWindowWidth = new AtomicInteger();
+
+ mInstrumentation.runOnMainSync(
+ () -> {
+ mWindowMagnificationController.setWindowSize(startingSize, startingSize);
+ mWindowMagnificationController.setEditMagnifierSizeMode(true);
+ mWindowMagnificationController
+ .onDrag(getInternalView(R.id.bottom_handle), 2f, 1f);
+ actualWindowHeight.set(mWindowManager.getLayoutParamsFromAttachedView().height);
+ actualWindowWidth.set(mWindowManager.getLayoutParamsFromAttachedView().width);
+ });
+ assertEquals(startingSize + 1, actualWindowHeight.get());
+ assertEquals(startingSize, actualWindowWidth.get());
+ }
+
@Test
public void setWindowCenterOutOfScreen_enabled_magnificationCenterIsInsideTheScreen() {