From 227034b863d6720a3fb1438efa52fd6a8fcf4c09 Mon Sep 17 00:00:00 2001 From: Mihai Popa Date: Fri, 27 Apr 2018 16:32:44 +0100 Subject: [PATCH] [Magnifier-42] Fix bug in window positioning 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 | 30 ++++++++++++++++++++----- 1 file changed, 25 insertions(+), 5 deletions(-) diff --git a/core/java/android/widget/Magnifier.java b/core/java/android/widget/Magnifier.java index 00632fbcb3fdb..08c4dc9c0c4d5 100644 --- a/core/java/android/widget/Magnifier.java +++ b/core/java/android/widget/Magnifier.java @@ -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,