Merge "Make child window inherit the scale of parent" into sc-dev

This commit is contained in:
TreeHugger Robot
2021-06-03 08:38:19 +00:00
committed by Android (Google) Code Review
3 changed files with 54 additions and 5 deletions

View File

@@ -258,6 +258,7 @@ 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;
@@ -638,6 +639,7 @@ class WindowState extends WindowContainer<WindowState> implements WindowManagerP
private PowerManager.WakeLock mDrawLock;
private final Rect mTmpRect = new Rect();
private final Rect mTmpRect2 = new Rect();
private final Point mTmpPoint = new Point();
private final Transaction mTmpTransaction;
@@ -1160,13 +1162,14 @@ 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.
* scaling override set. This method always returns {@code false} on child window because it
* should follow parent's scale.
* @see CompatModePackages#getCompatScale
* @see android.content.res.CompatibilityInfo#supportsScreen
* @see ActivityRecord#hasSizeCompatBounds()
*/
boolean hasCompatScale() {
return mOverrideScale != 1f || hasCompatScale(mAttrs, mActivityRecord);
return (mOverrideScale != 1f || hasCompatScale(mAttrs, mActivityRecord)) && !mIsChildWindow;
}
/**
@@ -1338,7 +1341,8 @@ class WindowState extends WindowContainer<WindowState> implements WindowManagerP
}
}
layoutDisplayFrame = new Rect(windowFrames.mDisplayFrame);
layoutDisplayFrame = mTmpRect2;
layoutDisplayFrame.set(windowFrames.mDisplayFrame);
windowFrames.mDisplayFrame.set(windowFrames.mContainingFrame);
layoutXDiff = mInsetFrame.left - windowFrames.mContainingFrame.left;
layoutYDiff = mInsetFrame.top - windowFrames.mContainingFrame.top;
@@ -4442,6 +4446,22 @@ 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(mAttrs.gravity, w, h, containingFrame,
(int) (x + mAttrs.horizontalMargin * pw),

View File

@@ -152,4 +152,10 @@ 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

@@ -35,6 +35,7 @@ import static android.view.WindowManager.LayoutParams.TYPE_APPLICATION_ATTACHED_
import static android.view.WindowManager.LayoutParams.TYPE_APPLICATION_MEDIA;
import static android.view.WindowManager.LayoutParams.TYPE_APPLICATION_MEDIA_OVERLAY;
import static android.view.WindowManager.LayoutParams.TYPE_APPLICATION_OVERLAY;
import static android.view.WindowManager.LayoutParams.TYPE_APPLICATION_PANEL;
import static android.view.WindowManager.LayoutParams.TYPE_APPLICATION_STARTING;
import static android.view.WindowManager.LayoutParams.TYPE_APPLICATION_SUB_PANEL;
import static android.view.WindowManager.LayoutParams.TYPE_BASE_APPLICATION;
@@ -577,21 +578,43 @@ public class WindowStateTests extends WindowTestsBase {
spyOn(cmp);
doReturn(overrideScale).when(cmp).getCompatScale(anyString(), anyInt());
final WindowState w = createWindow(null, TYPE_APPLICATION_OVERLAY, "win");
makeWindowVisible(w);
final WindowState child = createWindow(w, TYPE_APPLICATION_PANEL, "child");
assertTrue(w.hasCompatScale());
assertFalse(child.hasCompatScale());
makeWindowVisible(w, child);
w.setRequestedSize(100, 200);
child.setRequestedSize(50, 100);
child.mAttrs.width = child.mAttrs.height = 0;
w.mAttrs.x = w.mAttrs.y = 100;
w.mAttrs.width = w.mAttrs.height = WindowManager.LayoutParams.WRAP_CONTENT;
w.mAttrs.gravity = Gravity.TOP | Gravity.LEFT;
child.mAttrs.gravity = Gravity.CENTER;
DisplayContentTests.performLayout(mDisplayContent);
// Frame on screen = 100x200. Compat frame on client = 50x100.
// 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);
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);
// Surface should apply the scale.
w.prepareSurfaces();
verify(w.getPendingTransaction()).setMatrix(w.getSurfaceControl(),
overrideScale, 0, 0, overrideScale);
// Child surface inherits parent's scale, so it doesn't need to scale.
verify(child.getPendingTransaction(), never()).setMatrix(any(), anyInt(), anyInt(),
anyInt(), anyInt());
// According to "dp * density / 160 = px", density is scaled and the size in dp is the same.
final CompatibilityInfo compatInfo = cmp.compatibilityInfoForPackageLocked(