Change window magnifier UI and enhance the touch area for dragging

1. In the new UX, the new drag handle icon is on the right-bottom of
   window magnifier above the mirror SurfaceView. And it would make
   the mirror SurfaceView unable to recieve tap events.
   To allow taps to go through to the mirror SurfaceView below,
   we apply the patch by ag/9987117, applyTapExcludeRegion.
2. Expand the touch area for dragging by adjusting layout.

Bug: 146402201
Test: adb shell settings put secure window_magnification 1
Change-Id: Id59bf8583cf229a5c7292f31a7d04b470793c3f2
diff --git a/packages/SystemUI/res/drawable/ic_move.xml b/packages/SystemUI/res/drawable/ic_move.xml
new file mode 100644
index 0000000..e82c9d0
--- /dev/null
+++ b/packages/SystemUI/res/drawable/ic_move.xml
@@ -0,0 +1,34 @@
+<!--
+  ~ Copyright (C) 2020 The Android Open Source Project
+  ~
+  ~ Licensed under the Apache License, Version 2.0 (the "License");
+  ~ you may not use this file except in compliance with the License.
+  ~ You may obtain a copy of the License at
+  ~
+  ~      http://www.apache.org/licenses/LICENSE-2.0
+  ~
+  ~ Unless required by applicable law or agreed to in writing, software
+  ~ distributed under the License is distributed on an "AS IS" BASIS,
+  ~ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+  ~ See the License for the specific language governing permissions and
+  ~ limitations under the License.
+  -->
+
+<layer-list xmlns:android="http://schemas.android.com/apk/res/android">
+    <item>
+        <shape android:shape="oval">
+            <solid
+                android:color="@android:color/black" />
+            <size
+                android:height="@dimen/magnification_drag_view_size"
+                android:width="@dimen/magnification_drag_view_size"/>
+        </shape>
+    </item>
+    <item
+        android:gravity="center">
+        <vector android:height="28dp" android:viewportHeight="512"
+            android:viewportWidth="512" android:width="28dp">
+            <path android:fillColor="#FFFFFF" android:pathData="M506.528,243.712l-96.224,-80c-4.8,-4 -11.456,-4.832 -17.056,-2.208C387.616,164.16 384,169.792 384,176v48h-96v-96h48c6.208,0 11.84,-3.616 14.496,-9.248c2.624,-5.632 1.792,-12.288 -2.208,-17.056l-80,-96.224c-6.08,-7.296 -18.496,-7.296 -24.608,0l-80,96.224c-3.968,4.8 -4.832,11.456 -2.176,17.056C164.128,124.384 169.792,128 176,128h48v96h-96v-48c0,-6.208 -3.616,-11.84 -9.248,-14.496c-5.6,-2.624 -12.256,-1.792 -17.056,2.208l-96.224,80c-7.296,6.08 -7.296,18.496 0,24.608l96.224,80c4.8,3.968 11.456,4.832 17.056,2.176C124.416,347.872 128,342.208 128,336v-48h96v96h-48c-6.208,0 -11.872,3.616 -14.496,9.248c-2.656,5.632 -1.792,12.288 2.176,17.056l80,96.224c6.08,7.296 18.496,7.296 24.608,0l80,-96.224c4,-4.8 4.832,-11.456 2.208,-17.056C347.84,387.616 342.208,384 336,384h-48v-96h96v48c0,6.208 3.616,11.872 9.248,14.496c5.632,2.656 12.288,1.792 17.056,-2.176l96.224,-80C513.824,262.208 513.824,249.792 506.528,243.712z"/>
+        </vector>
+    </item>
+</layer-list>
diff --git a/packages/SystemUI/res/layout/window_magnifier_view.xml b/packages/SystemUI/res/layout/window_magnifier_view.xml
index f818612..25d63e3 100644
--- a/packages/SystemUI/res/layout/window_magnifier_view.xml
+++ b/packages/SystemUI/res/layout/window_magnifier_view.xml
@@ -16,15 +16,20 @@
   -->
 
 <FrameLayout xmlns:android="http://schemas.android.com/apk/res/android"
-    android:layout_width="wrap_content"
-    android:layout_height="wrap_content">
+             android:layout_width="wrap_content"
+             android:layout_height="wrap_content">
 
-    <SurfaceView
-        android:layout_marginStart="@dimen/magnification_border_size"
-        android:layout_marginTop="@dimen/magnification_border_size"
-        android:id="@+id/surface_view"
+    <View
         android:layout_width="match_parent"
-        android:layout_height="match_parent" />
+        android:layout_height="match_parent"
+        android:layout_margin="@dimen/magnification_outer_border_margin"
+        android:background="@android:color/black" />
+
+    <View
+        android:layout_width="match_parent"
+        android:layout_height="match_parent"
+        android:layout_margin="@dimen/magnification_inner_border_margin"
+        android:background="@color/magnification_border_color" />
 
     <RelativeLayout
         android:layout_width="match_parent"
@@ -33,39 +38,43 @@
 
         <View
             android:id="@+id/left_handle"
-            android:layout_width="@dimen/magnification_border_size"
+            android:layout_width="@dimen/magnification_border_drag_size"
             android:layout_height="match_parent"
-            android:layout_above="@+id/drag_handle"
-            android:background="@color/magnification_border_color" />
+            android:layout_above="@+id/bottom_handle" />
 
         <View
             android:id="@+id/top_handle"
             android:layout_width="match_parent"
-            android:layout_height="@dimen/magnification_border_size"
-            android:background="@color/magnification_border_color" />
+            android:layout_height="@dimen/magnification_border_drag_size"
+            android:layout_alignParentTop="true" />
 
         <View
             android:id="@+id/right_handle"
-            android:layout_width="@dimen/magnification_border_size"
+            android:layout_width="@dimen/magnification_border_drag_size"
             android:layout_height="match_parent"
-            android:layout_above="@+id/drag_handle"
-            android:layout_alignParentEnd="true"
-            android:background="@color/magnification_border_color" />
+            android:layout_above="@+id/bottom_handle"
+            android:layout_alignParentEnd="true" />
 
         <View
             android:id="@+id/bottom_handle"
             android:layout_width="match_parent"
-            android:layout_height="@dimen/magnification_border_size"
-            android:layout_above="@+id/drag_handle"
-            android:background="@color/magnification_border_color" />
+            android:layout_height="@dimen/magnification_border_drag_size"
+            android:layout_alignParentBottom="true" />
 
-        <View
-            android:id="@+id/drag_handle"
-            android:layout_width="@dimen/magnification_drag_view_width"
-            android:layout_height="@dimen/magnification_drag_view_height"
-            android:layout_alignParentBottom="true"
-            android:layout_centerHorizontal="true"
-            android:background="@color/magnification_border_color" />
+        <SurfaceView
+            android:id="@+id/surface_view"
+            android:layout_width="match_parent"
+            android:layout_height="match_parent"
+            android:layout_margin="@dimen/magnification_mirror_surface_margin" />
 
     </RelativeLayout>
+
+    <ImageView
+        android:id="@+id/drag_handle"
+        android:layout_width="@dimen/magnification_drag_view_size"
+        android:layout_height="@dimen/magnification_drag_view_size"
+        android:layout_gravity="right|bottom"
+        android:scaleType="center"
+        android:src="@drawable/ic_move" />
+
 </FrameLayout>
\ No newline at end of file
diff --git a/packages/SystemUI/res/values/dimens.xml b/packages/SystemUI/res/values/dimens.xml
index 15575a4..aca1569 100644
--- a/packages/SystemUI/res/values/dimens.xml
+++ b/packages/SystemUI/res/values/dimens.xml
@@ -1187,11 +1187,13 @@
     <dimen name="qs_seamless_icon_size">20dp</dimen>
     <dimen name="qqs_media_spacing">8dp</dimen>
 
-    <dimen name="magnification_border_size">5dp</dimen>
+    <dimen name="magnification_border_drag_size">35dp</dimen>
+    <dimen name="magnification_outer_border_margin">15dp</dimen>
+    <dimen name="magnification_inner_border_margin">17dp</dimen>
+    <dimen name="magnification_mirror_surface_margin">20dp</dimen>
     <dimen name="magnification_frame_move_short">5dp</dimen>
     <dimen name="magnification_frame_move_long">25dp</dimen>
-    <dimen name="magnification_drag_view_width">100dp</dimen>
-    <dimen name="magnification_drag_view_height">35dp</dimen>
+    <dimen name="magnification_drag_view_size">38dp</dimen>
     <dimen name="magnification_controls_size">90dp</dimen>
     <dimen name="magnifier_left_right_controls_width">35dp</dimen>
     <dimen name="magnifier_left_right_controls_height">45dp</dimen>
diff --git a/packages/SystemUI/src/com/android/systemui/accessibility/WindowMagnificationController.java b/packages/SystemUI/src/com/android/systemui/accessibility/WindowMagnificationController.java
index 7176490..226834d 100644
--- a/packages/SystemUI/src/com/android/systemui/accessibility/WindowMagnificationController.java
+++ b/packages/SystemUI/src/com/android/systemui/accessibility/WindowMagnificationController.java
@@ -25,9 +25,13 @@
 import android.graphics.Point;
 import android.graphics.PointF;
 import android.graphics.Rect;
+import android.graphics.Region;
 import android.os.Binder;
+import android.os.RemoteException;
 import android.view.Display;
 import android.view.Gravity;
+import android.view.IWindow;
+import android.view.IWindowSession;
 import android.view.LayoutInflater;
 import android.view.MotionEvent;
 import android.view.Surface;
@@ -37,6 +41,7 @@
 import android.view.View;
 import android.view.ViewTreeObserver;
 import android.view.WindowManager;
+import android.view.WindowManagerGlobal;
 
 import com.android.systemui.R;
 import com.android.systemui.shared.system.WindowManagerWrapper;
@@ -46,7 +51,6 @@
  */
 public class WindowMagnificationController implements View.OnTouchListener, SurfaceHolder.Callback,
         MirrorWindowControl.MirrorWindowDelegate {
-    private final int mBorderSize;
 
     private final Context mContext;
     private final Point mDisplaySize = new Point();
@@ -73,6 +77,7 @@
 
     private View mMirrorView;
     private SurfaceView mMirrorSurfaceView;
+    private int mMirrorSurfaceMargin;
     private View mOverlayView;
     // The boundary of magnification frame.
     private final Rect mMagnificationFrameBoundary = new Rect();
@@ -89,7 +94,7 @@
         mWm = (WindowManager) context.getSystemService(Context.WINDOW_SERVICE);
 
         Resources r = context.getResources();
-        mBorderSize = (int) r.getDimension(R.dimen.magnification_border_size);
+        mMirrorSurfaceMargin = r.getDimensionPixelSize(R.dimen.magnification_mirror_surface_margin);
 
         mScale = r.getInteger(R.integer.magnification_default_scale);
         mMirrorWindowControl = mirrorWindowControl;
@@ -187,10 +192,8 @@
     private void createMirrorWindow() {
         // The window should be the size the mirrored surface will be but also add room for the
         // border and the drag handle.
-        int dragViewHeight = (int) mContext.getResources().getDimension(
-                R.dimen.magnification_drag_view_height);
-        int windowWidth = mMagnificationFrame.width() + 2 * mBorderSize;
-        int windowHeight = mMagnificationFrame.height() + dragViewHeight + 2 * mBorderSize;
+        int windowWidth = mMagnificationFrame.width() + 2 * mMirrorSurfaceMargin;
+        int windowHeight = mMagnificationFrame.height() + 2 * mMirrorSurfaceMargin;
 
         WindowManager.LayoutParams params = new WindowManager.LayoutParams(
                 windowWidth, windowHeight,
@@ -207,9 +210,14 @@
 
         mMirrorView = LayoutInflater.from(mContext).inflate(R.layout.window_magnifier_view, null);
         mMirrorSurfaceView = mMirrorView.findViewById(R.id.surface_view);
-        // This places the SurfaceView's SurfaceControl above the ViewRootImpl's SurfaceControl to
-        // ensure the mirrored area can get touch instead of going to the window
-        mMirrorSurfaceView.setZOrderOnTop(true);
+
+        // Allow taps to go through to the mirror SurfaceView below.
+        mMirrorSurfaceView.addOnLayoutChangeListener(
+                (View v, int left, int top, int right, int bottom, int oldLeft, int oldTop,
+                        int oldRight, int oldBottom)
+                        -> {
+                    applyTapExcludeRegion();
+                });
 
         mMirrorView.setSystemUiVisibility(View.SYSTEM_UI_FLAG_LAYOUT_STABLE
                 | View.SYSTEM_UI_FLAG_LAYOUT_HIDE_NAVIGATION
@@ -226,6 +234,24 @@
         addDragTouchListeners();
     }
 
+    private void applyTapExcludeRegion() {
+        final Region tapExcludeRegion = calculateTapExclude();
+        final IWindow window = IWindow.Stub.asInterface(mMirrorView.getWindowToken());
+        try {
+            IWindowSession session = WindowManagerGlobal.getWindowSession();
+            session.updateTapExcludeRegion(window, tapExcludeRegion);
+        } catch (RemoteException e) {
+        }
+    }
+
+    private Region calculateTapExclude() {
+        final int borderDragSize = mContext.getResources().getDimensionPixelSize(
+                R.dimen.magnification_border_drag_size);
+        Region regionInsideDragBorder = new Region(borderDragSize, borderDragSize,
+                mMirrorView.getWidth() - borderDragSize, mMirrorView.getHeight() - borderDragSize);
+        return regionInsideDragBorder;
+    }
+
     private void createControls() {
         if (mMirrorWindowControl != null) {
             mMirrorWindowControl.showControl(mOverlayView.getWindowToken());
@@ -234,9 +260,9 @@
 
     private void setInitialStartBounds() {
         // Sets the initial frame area for the mirror and places it in the center of the display.
-        int initSize = Math.min(mDisplaySize.x, mDisplaySize.y) / 2;
-        int initX = mDisplaySize.x / 2 - initSize / 2;
-        int initY = mDisplaySize.y / 2 - initSize / 2;
+        int initSize = Math.min(mDisplaySize.x, mDisplaySize.y) / 2 + 2 * mMirrorSurfaceMargin;
+        int initX = mDisplaySize.x / 2 - initSize / 2 - mMirrorSurfaceMargin;
+        int initY = mDisplaySize.y / 2 - initSize / 2 - mMirrorSurfaceMargin;
         mMagnificationFrame.set(initX, initY, initX + initSize, initY + initSize);
     }