Merge "Compute surface position of scaled child window"

This commit is contained in:
TreeHugger Robot
2021-10-19 06:18:43 +00:00
committed by Android (Google) Code Review
3 changed files with 36 additions and 58 deletions

View File

@@ -259,7 +259,6 @@ import com.android.internal.util.ToBooleanFunction;
import com.android.server.policy.WindowManagerPolicy;
import com.android.server.wm.LocalAnimationAdapter.AnimationSpec;
import com.android.server.wm.SurfaceAnimator.AnimationType;
import com.android.server.wm.utils.CoordinateTransforms;
import java.io.PrintWriter;
import java.lang.ref.WeakReference;
@@ -1177,14 +1176,13 @@ class WindowState extends WindowContainer<WindowState> implements WindowManagerP
/**
* @return {@code true} if the application runs in size compatibility mode or has an app level
* scaling override set. This method always returns {@code false} on child window because it
* should follow parent's scale.
* scaling override set.
* @see CompatModePackages#getCompatScale
* @see android.content.res.CompatibilityInfo#supportsScreen
* @see ActivityRecord#hasSizeCompatBounds()
*/
boolean hasCompatScale() {
return (mOverrideScale != 1f || hasCompatScale(mAttrs, mActivityRecord)) && !mIsChildWindow;
return mOverrideScale != 1f || hasCompatScale(mAttrs, mActivityRecord);
}
/**
@@ -4478,22 +4476,6 @@ class WindowState extends WindowContainer<WindowState> implements WindowManagerP
h = Math.min(h, ph);
}
if (mIsChildWindow) {
final WindowState parent = getTopParentWindow();
if (parent.hasCompatScale()) {
// Scale the containing and display frames because they are in screen coordinates.
// The position of frames are already relative to parent so only size is scaled.
mTmpRect.set(containingFrame);
containingFrame = mTmpRect;
CoordinateTransforms.scaleRectSize(containingFrame, parent.mInvGlobalScale);
if (fitToDisplay) {
mTmpRect2.set(displayFrame);
displayFrame = mTmpRect2;
CoordinateTransforms.scaleRectSize(displayFrame, parent.mInvGlobalScale);
}
}
}
// Set mFrame
Gravity.apply(attrs.gravity, w, h, containingFrame,
(int) (x + attrs.horizontalMargin * pw),
@@ -5124,19 +5106,6 @@ class WindowState extends WindowContainer<WindowState> implements WindowManagerP
}
}
/**
* Expand the given rectangle by this windows surface insets. This
* takes you from the 'window size' to the 'surface size'.
* The surface insets are positive in each direction, so we inset by
* the inverse.
*/
void expandForSurfaceInsets(Rect r) {
r.inset(-mAttrs.surfaceInsets.left,
-mAttrs.surfaceInsets.top,
-mAttrs.surfaceInsets.right,
-mAttrs.surfaceInsets.bottom);
}
boolean surfaceInsetsChanging() {
return !mLastSurfaceInsets.equals(mAttrs.surfaceInsets);
}
@@ -5454,6 +5423,10 @@ class WindowState extends WindowContainer<WindowState> implements WindowManagerP
}
private void updateScaleIfNeeded() {
if (mIsChildWindow) {
// Child window follows parent's scale.
return;
}
float newHScale = mHScale * mGlobalScale * mWallpaperScale;
float newVScale = mVScale * mGlobalScale * mWallpaperScale;
if (mLastHScale != newHScale ||
@@ -5537,15 +5510,18 @@ class WindowState extends WindowContainer<WindowState> implements WindowManagerP
// If changed, also adjust getTransformationMatrix
final WindowContainer parentWindowContainer = getParent();
if (isChildWindow()) {
// TODO: This probably falls apart at some point and we should
// actually compute relative coordinates.
final WindowState parent = getParentWindow();
outPoint.offset(-parent.mWindowFrames.mFrame.left, -parent.mWindowFrames.mFrame.top);
// Undo the scale of window position because the relative coordinates for child are
// based on the scaled parent.
if (mInvGlobalScale != 1f) {
outPoint.x = (int) (outPoint.x * mInvGlobalScale + 0.5f);
outPoint.y = (int) (outPoint.y * mInvGlobalScale + 0.5f);
}
// Since the parent was outset by its surface insets, we need to undo the outsetting
// with insetting by the same amount.
final WindowState parent = getParentWindow();
transformSurfaceInsetsPosition(mTmpPoint, parent.mAttrs.surfaceInsets);
outPoint.offset(-parent.mWindowFrames.mFrame.left + mTmpPoint.x,
-parent.mWindowFrames.mFrame.top + mTmpPoint.y);
outPoint.offset(mTmpPoint.x, mTmpPoint.y);
} else if (parentWindowContainer != null) {
final Rect parentBounds = isStartingWindowAssociatedToTask()
? mStartingData.mAssociatedTask.getBounds()
@@ -5564,7 +5540,7 @@ class WindowState extends WindowContainer<WindowState> implements WindowManagerP
outPoint.offset(outset, outset);
}
// Expand for surface insets. See WindowState.expandForSurfaceInsets.
// The surface size is larger than the window if the window has positive surface insets.
transformSurfaceInsetsPosition(mTmpPoint, mAttrs.surfaceInsets);
outPoint.offset(-mTmpPoint.x, -mTmpPoint.y);
@@ -5576,7 +5552,9 @@ class WindowState extends WindowContainer<WindowState> implements WindowManagerP
* scaled, the insets also need to be scaled for surface position in global coordinate.
*/
private void transformSurfaceInsetsPosition(Point outPos, Rect surfaceInsets) {
if (!hasCompatScale()) {
// Ignore the scale for child window because its insets have been scaled with the
// parent surface.
if (mGlobalScale == 1f || mIsChildWindow) {
outPos.x = surfaceInsets.left;
outPos.y = surfaceInsets.top;
return;

View File

@@ -152,10 +152,4 @@ public class CoordinateTransforms {
transform.mapRect(tmp);
inOutRect.set((int) tmp.left, (int) tmp.top, (int) tmp.right, (int) tmp.bottom);
}
/** Scales the rect without changing its position. */
public static void scaleRectSize(Rect inOutRect, float scale) {
inOutRect.right = inOutRect.left + (int) (inOutRect.width() * scale + .5f);
inOutRect.bottom = inOutRect.top + (int) (inOutRect.height() * scale + .5f);
}
}

View File

@@ -78,6 +78,7 @@ import static org.mockito.Mockito.when;
import android.content.res.CompatibilityInfo;
import android.content.res.Configuration;
import android.graphics.Matrix;
import android.graphics.Point;
import android.graphics.Rect;
import android.os.IBinder;
import android.os.RemoteException;
@@ -563,7 +564,7 @@ public class WindowStateTests extends WindowTestsBase {
final WindowState child = createWindow(w, TYPE_APPLICATION_PANEL, "child");
assertTrue(w.hasCompatScale());
assertFalse(child.hasCompatScale());
assertTrue(child.hasCompatScale());
makeWindowVisible(w, child);
w.setRequestedSize(100, 200);
@@ -574,21 +575,26 @@ public class WindowStateTests extends WindowTestsBase {
w.mAttrs.gravity = Gravity.TOP | Gravity.LEFT;
child.mAttrs.gravity = Gravity.CENTER;
DisplayContentTests.performLayout(mDisplayContent);
final Rect parentFrame = w.getFrame();
final Rect childFrame = child.getFrame();
// Frame on screen = 200x400 (200, 200 - 400, 600). Compat frame on client = 100x200.
final Rect unscaledCompatFrame = new Rect(w.getWindowFrames().mCompatFrame);
unscaledCompatFrame.scale(overrideScale);
final Rect parentFrame = w.getFrame();
assertEquals(w.getWindowFrames().mFrame, unscaledCompatFrame);
assertEquals(parentFrame, unscaledCompatFrame);
final Rect childFrame = child.getFrame();
assertEquals(childFrame, child.getWindowFrames().mCompatFrame);
// Child frame = 50x100 (225, 250 - 275, 350) according to Gravity.CENTER.
final int childX = parentFrame.left + child.mRequestedWidth / 2;
final int childY = parentFrame.top + child.mRequestedHeight / 2;
final Rect expectedChildFrame = new Rect(childX, childY, childX + child.mRequestedWidth,
childY + child.mRequestedHeight);
assertEquals(expectedChildFrame, childFrame);
// Frame on screen = 100x200 (250, 300 - 350, 500). Compat frame on client = 50x100.
unscaledCompatFrame.set(child.getWindowFrames().mCompatFrame);
unscaledCompatFrame.scale(overrideScale);
assertEquals(childFrame, unscaledCompatFrame);
// The position of child is relative to parent. So the local coordinates should be scaled.
final Point expectedChildPos = new Point(
(int) ((childFrame.left - parentFrame.left) / overrideScale),
(int) ((childFrame.top - parentFrame.top) / overrideScale));
final Point childPos = new Point();
child.transformFrameToSurfacePosition(childFrame.left, childFrame.top, childPos);
assertEquals(expectedChildPos, childPos);
// Surface should apply the scale.
w.prepareSurfaces();