Merge "Make child window inherit the scale of parent" into sc-dev
This commit is contained in:
committed by
Android (Google) Code Review
commit
4a443bc2c1
@@ -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),
|
||||
|
||||
@@ -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);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -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(
|
||||
|
||||
Reference in New Issue
Block a user