OSDN Git Service

[Magnifier-42] Fix bug in window positioning
authorMihai Popa <popam@google.com>
Fri, 27 Apr 2018 15:32:44 +0000 (16:32 +0100)
committerMihai Popa <popam@google.com>
Wed, 2 May 2018 10:30:29 +0000 (10:30 +0000)
The position of the magnifier surface is always clamped inside its
parent surface. As of Ic5b5f6ca687db8b5d842f0ab20eac70f1fd2f85e, we are
always trying to make the magnifier surface a child of the main
application window, if possible (before, if the magnified view was a
SurfaceView, we were making the magnifier a child of the SurfaceView's
surface). However, the CL did not also update the clamping, continuing
to clamp to the SurfaceView space when the magnified view was a
SurfaceView (even if the magnifier was child of the main window). This
was making the magnifier window to be wrongly positioned on the screen
when the magnified view is a SurfaceView. The current CL fixes this.

Bug: 78876353
Test: manual testing
Test: atest CtsWidgetTestCases:android.widget.cts.MagnifierTest
Change-Id: I63f2b185f58e62e8ad6eadf788e641fb1de07b04

core/java/android/widget/Magnifier.java

index 00632fb..08c4dc9 100644 (file)
@@ -342,11 +342,31 @@ public final class Magnifier {
 
         // Clamp window coordinates inside the parent surface, to avoid displaying
         // the magnifier out of screen or overlapping with system insets.
-        final Rect insets = mView.getRootWindowInsets().getSystemWindowInsets();
-        final int windowCoordsX = Math.max(insets.left,
-                Math.min(surfaceWidth - mWindowWidth - insets.right, mWindowCoords.x));
-        final int windowCoordsY = Math.max(insets.top,
-                Math.min(surfaceHeight - mWindowHeight - insets.bottom, mWindowCoords.y));
+        Rect windowBounds = null;
+        if (mView.getViewRootImpl() != null) {
+            // TODO: deduplicate against the first part of #getValidParentSurfaceForMagnifier()
+            // TODO: deduplicate against the first part of the current method
+            final ViewRootImpl viewRootImpl = mView.getViewRootImpl();
+            final Surface parentSurface = viewRootImpl.mSurface;
+            final Rect surfaceInsets = viewRootImpl.mWindowAttributes.surfaceInsets;
+            final int parentWidth =
+                    viewRootImpl.getWidth() + surfaceInsets.left + surfaceInsets.right;
+            final int parentHeight =
+                    viewRootImpl.getHeight() + surfaceInsets.top + surfaceInsets.bottom;
+            if (parentSurface != null && parentSurface.isValid()) {
+                final Rect systemInsets = mView.getRootWindowInsets().getSystemWindowInsets();
+                windowBounds = new Rect(systemInsets.left, systemInsets.top,
+                         parentWidth - systemInsets.right, parentHeight - systemInsets.bottom);
+            }
+        }
+        if (windowBounds == null && mView instanceof SurfaceView) {
+            windowBounds = ((SurfaceView) mView).getHolder().getSurfaceFrame();
+        }
+
+        final int windowCoordsX = Math.max(windowBounds.left,
+                Math.min(windowBounds.right - mWindowWidth, mWindowCoords.x));
+        final int windowCoordsY = Math.max(windowBounds.top,
+                Math.min(windowBounds.bottom - mWindowHeight, mWindowCoords.y));
 
         // Perform the pixel copy.
         mPixelCopyRequestRect.set(clampedStartXInSurface,