summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--services/core/java/com/android/server/wm/WindowState.java26
-rw-r--r--services/core/java/com/android/server/wm/utils/CoordinateTransforms.java6
-rw-r--r--services/tests/wmtests/src/com/android/server/wm/WindowStateTests.java27
3 files changed, 54 insertions, 5 deletions
diff --git a/services/core/java/com/android/server/wm/WindowState.java b/services/core/java/com/android/server/wm/WindowState.java
index d9f36bd84899..b28297ed4af8 100644
--- a/services/core/java/com/android/server/wm/WindowState.java
+++ b/services/core/java/com/android/server/wm/WindowState.java
@@ -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),
diff --git a/services/core/java/com/android/server/wm/utils/CoordinateTransforms.java b/services/core/java/com/android/server/wm/utils/CoordinateTransforms.java
index a2f37a56598d..6d8e07a919cc 100644
--- a/services/core/java/com/android/server/wm/utils/CoordinateTransforms.java
+++ b/services/core/java/com/android/server/wm/utils/CoordinateTransforms.java
@@ -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);
+ }
}
diff --git a/services/tests/wmtests/src/com/android/server/wm/WindowStateTests.java b/services/tests/wmtests/src/com/android/server/wm/WindowStateTests.java
index 178fabcc6a47..92b670ed9699 100644
--- a/services/tests/wmtests/src/com/android/server/wm/WindowStateTests.java
+++ b/services/tests/wmtests/src/com/android/server/wm/WindowStateTests.java
@@ -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(