Merge changes If8232b90,I3176837e
* changes: Deobfuscate computeFrameLw parameters. Begin series of computeFrame unit tests
This commit is contained in:
committed by
Android (Google) Code Review
commit
c3a0627f10
@@ -731,8 +731,9 @@ class WindowState extends WindowContainer<WindowState> implements WindowManagerP
|
||||
}
|
||||
|
||||
@Override
|
||||
public void computeFrameLw(Rect pf, Rect df, Rect of, Rect cf, Rect vf, Rect dcf, Rect sf,
|
||||
Rect osf) {
|
||||
public void computeFrameLw(Rect parentFrame, Rect displayFrame, Rect overscanFrame,
|
||||
Rect contentFrame, Rect visibleFrame, Rect decorFrame, Rect stableFrame,
|
||||
Rect outsetFrame) {
|
||||
if (mWillReplaceWindow && (mAnimatingExit || !mReplacingRemoveRequested)) {
|
||||
// This window is being replaced and either already got information that it's being
|
||||
// removed or we are still waiting for some information. Because of this we don't
|
||||
@@ -768,10 +769,10 @@ class WindowState extends WindowContainer<WindowState> implements WindowManagerP
|
||||
final int layoutYDiff;
|
||||
if (fullscreenTask || layoutInParentFrame()) {
|
||||
// We use the parent frame as the containing frame for fullscreen and child windows
|
||||
mContainingFrame.set(pf);
|
||||
mDisplayFrame.set(df);
|
||||
layoutDisplayFrame = df;
|
||||
layoutContainingFrame = pf;
|
||||
mContainingFrame.set(parentFrame);
|
||||
mDisplayFrame.set(displayFrame);
|
||||
layoutDisplayFrame = displayFrame;
|
||||
layoutContainingFrame = parentFrame;
|
||||
layoutXDiff = 0;
|
||||
layoutYDiff = 0;
|
||||
} else {
|
||||
@@ -787,15 +788,15 @@ class WindowState extends WindowContainer<WindowState> implements WindowManagerP
|
||||
final WindowState imeWin = mService.mInputMethodWindow;
|
||||
// IME is up and obscuring this window. Adjust the window position so it is visible.
|
||||
if (imeWin != null && imeWin.isVisibleNow() && mService.mInputMethodTarget == this) {
|
||||
if (windowsAreFloating && mContainingFrame.bottom > cf.bottom) {
|
||||
if (windowsAreFloating && mContainingFrame.bottom > contentFrame.bottom) {
|
||||
// In freeform we want to move the top up directly.
|
||||
// TODO: Investigate why this is cf not pf.
|
||||
mContainingFrame.top -= mContainingFrame.bottom - cf.bottom;
|
||||
} else if (mContainingFrame.bottom > pf.bottom) {
|
||||
// TODO: Investigate why this is contentFrame not parentFrame.
|
||||
mContainingFrame.top -= mContainingFrame.bottom - contentFrame.bottom;
|
||||
} else if (mContainingFrame.bottom > parentFrame.bottom) {
|
||||
// But in docked we want to behave like fullscreen
|
||||
// and behave as if the task were given smaller bounds
|
||||
// for the purposes of layout.
|
||||
mContainingFrame.bottom = pf.bottom;
|
||||
mContainingFrame.bottom = parentFrame.bottom;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -804,7 +805,7 @@ class WindowState extends WindowContainer<WindowState> implements WindowManagerP
|
||||
// if it wasn't set already. No need to intersect it with the (visible)
|
||||
// "content frame" since it is allowed to be outside the visible desktop.
|
||||
if (mContainingFrame.isEmpty()) {
|
||||
mContainingFrame.set(cf);
|
||||
mContainingFrame.set(contentFrame);
|
||||
}
|
||||
}
|
||||
mDisplayFrame.set(mContainingFrame);
|
||||
@@ -812,22 +813,22 @@ class WindowState extends WindowContainer<WindowState> implements WindowManagerP
|
||||
layoutYDiff = !mInsetFrame.isEmpty() ? mInsetFrame.top - mContainingFrame.top : 0;
|
||||
layoutContainingFrame = !mInsetFrame.isEmpty() ? mInsetFrame : mContainingFrame;
|
||||
mTmpRect.set(0, 0, dc.getDisplayInfo().logicalWidth, dc.getDisplayInfo().logicalHeight);
|
||||
subtractInsets(mDisplayFrame, layoutContainingFrame, df, mTmpRect);
|
||||
subtractInsets(mDisplayFrame, layoutContainingFrame, displayFrame, mTmpRect);
|
||||
if (!layoutInParentFrame()) {
|
||||
subtractInsets(mContainingFrame, layoutContainingFrame, pf, mTmpRect);
|
||||
subtractInsets(mInsetFrame, layoutContainingFrame, pf, mTmpRect);
|
||||
subtractInsets(mContainingFrame, layoutContainingFrame, parentFrame, mTmpRect);
|
||||
subtractInsets(mInsetFrame, layoutContainingFrame, parentFrame, mTmpRect);
|
||||
}
|
||||
layoutDisplayFrame = df;
|
||||
layoutDisplayFrame = displayFrame;
|
||||
layoutDisplayFrame.intersect(layoutContainingFrame);
|
||||
}
|
||||
|
||||
final int pw = mContainingFrame.width();
|
||||
final int ph = mContainingFrame.height();
|
||||
|
||||
if (!mParentFrame.equals(pf)) {
|
||||
if (!mParentFrame.equals(parentFrame)) {
|
||||
//Slog.i(TAG_WM, "Window " + this + " content frame from " + mParentFrame
|
||||
// + " to " + pf);
|
||||
mParentFrame.set(pf);
|
||||
// + " to " + parentFrame);
|
||||
mParentFrame.set(parentFrame);
|
||||
mContentChanged = true;
|
||||
}
|
||||
if (mRequestedWidth != mLastRequestedWidth || mRequestedHeight != mLastRequestedHeight) {
|
||||
@@ -836,14 +837,14 @@ class WindowState extends WindowContainer<WindowState> implements WindowManagerP
|
||||
mContentChanged = true;
|
||||
}
|
||||
|
||||
mOverscanFrame.set(of);
|
||||
mContentFrame.set(cf);
|
||||
mVisibleFrame.set(vf);
|
||||
mDecorFrame.set(dcf);
|
||||
mStableFrame.set(sf);
|
||||
final boolean hasOutsets = osf != null;
|
||||
mOverscanFrame.set(overscanFrame);
|
||||
mContentFrame.set(contentFrame);
|
||||
mVisibleFrame.set(visibleFrame);
|
||||
mDecorFrame.set(decorFrame);
|
||||
mStableFrame.set(stableFrame);
|
||||
final boolean hasOutsets = outsetFrame != null;
|
||||
if (hasOutsets) {
|
||||
mOutsetFrame.set(osf);
|
||||
mOutsetFrame.set(outsetFrame);
|
||||
}
|
||||
|
||||
final int fw = mFrame.width();
|
||||
|
||||
@@ -0,0 +1,189 @@
|
||||
/*
|
||||
* Copyright (C) 2016 The Android Open Source Project
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License
|
||||
*/
|
||||
|
||||
package com.android.server.wm;
|
||||
|
||||
import org.junit.Before;
|
||||
import org.junit.Test;
|
||||
import org.junit.runner.RunWith;
|
||||
|
||||
import android.content.Context;
|
||||
import android.graphics.Rect;
|
||||
import android.os.Binder;
|
||||
import android.platform.test.annotations.Presubmit;
|
||||
import android.support.test.InstrumentationRegistry;
|
||||
import android.support.test.filters.SmallTest;
|
||||
import android.support.test.runner.AndroidJUnit4;
|
||||
import android.view.Gravity;
|
||||
import android.view.IWindow;
|
||||
import android.view.WindowManager;
|
||||
|
||||
import static android.view.WindowManager.LayoutParams.TYPE_APPLICATION;
|
||||
import static android.view.WindowManager.LayoutParams.FLAG_SCALED;
|
||||
import static android.view.WindowManager.LayoutParams.FILL_PARENT;
|
||||
import static org.junit.Assert.assertEquals;
|
||||
|
||||
/**
|
||||
* Tests for the {@link WindowState#computeFrameLw} method and other window frame machinery.
|
||||
*
|
||||
* Build/Install/Run: bit FrameworksServicesTests:com.android.server.wm.WindowFrameTests
|
||||
*/
|
||||
@SmallTest
|
||||
@Presubmit
|
||||
@RunWith(AndroidJUnit4.class)
|
||||
public class WindowFrameTests {
|
||||
|
||||
private static WindowManagerService sWm = null;
|
||||
private WindowToken mWindowToken;
|
||||
private final IWindow mIWindow = new TestIWindow();
|
||||
|
||||
class WindowStateWithTask extends WindowState {
|
||||
final Task mTask;
|
||||
WindowStateWithTask(WindowManager.LayoutParams attrs, Task t) {
|
||||
super(sWm, null, mIWindow, mWindowToken, null, 0, 0, attrs, 0, 0);
|
||||
mTask = t;
|
||||
}
|
||||
|
||||
@Override
|
||||
Task getTask() {
|
||||
return mTask;
|
||||
}
|
||||
};
|
||||
|
||||
class TaskWithBounds extends Task {
|
||||
final Rect mBounds;
|
||||
TaskWithBounds(Rect bounds) {
|
||||
super(0, mStubStack, 0, sWm, null, null, false);
|
||||
mBounds = bounds;
|
||||
}
|
||||
@Override
|
||||
void getBounds(Rect outBounds) {
|
||||
outBounds.set(mBounds);
|
||||
}
|
||||
@Override
|
||||
void getTempInsetBounds(Rect outBounds) {
|
||||
outBounds.setEmpty();
|
||||
}
|
||||
@Override
|
||||
boolean isFullscreen() {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
TaskStack mStubStack;
|
||||
|
||||
@Before
|
||||
public void setUp() throws Exception {
|
||||
final Context context = InstrumentationRegistry.getTargetContext();
|
||||
sWm = TestWindowManagerPolicy.getWindowManagerService(context);
|
||||
mWindowToken = new WindowToken(sWm, new Binder(), 0, false,
|
||||
sWm.getDefaultDisplayContentLocked());
|
||||
mStubStack = new TaskStack(sWm, 0);
|
||||
}
|
||||
|
||||
public void assertRect(Rect rect, int left, int top, int right, int bottom) {
|
||||
assertEquals(left, rect.left);
|
||||
assertEquals(top, rect.top);
|
||||
assertEquals(right, rect.right);
|
||||
assertEquals(bottom, rect.bottom);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testLayoutInFullscreenTaskNoInsets() throws Exception {
|
||||
Task task = new TaskWithBounds(null); // fullscreen task doesn't use bounds for computeFrame
|
||||
WindowState w = createWindow(task, FILL_PARENT, FILL_PARENT);
|
||||
w.mAttrs.gravity = Gravity.LEFT | Gravity.TOP;
|
||||
|
||||
// With no insets or system decor all the frames incoming from PhoneWindowManager
|
||||
// are identical.
|
||||
final Rect pf = new Rect(0, 0, 1000, 1000);
|
||||
|
||||
// Here the window has FILL_PARENT, FILL_PARENT
|
||||
// so we expect it to fill the entire available frame.
|
||||
w.computeFrameLw(pf, pf, pf, pf, pf, pf, pf, pf);
|
||||
assertRect(w.mFrame, 0, 0, 1000, 1000);
|
||||
|
||||
// It can select various widths and heights within the bounds.
|
||||
// Strangely the window attribute width is ignored for normal windows
|
||||
// and we use mRequestedWidth/mRequestedHeight
|
||||
w.mAttrs.width = 300;
|
||||
w.mAttrs.height = 300;
|
||||
w.computeFrameLw(pf, pf, pf, pf, pf, pf, pf, pf);
|
||||
// Explicit width and height without requested width/height
|
||||
// gets us nothing.
|
||||
assertRect(w.mFrame, 0, 0, 0, 0);
|
||||
|
||||
w.mRequestedWidth = 300;
|
||||
w.mRequestedHeight = 300;
|
||||
w.computeFrameLw(pf, pf, pf, pf, pf, pf, pf, pf);
|
||||
// With requestedWidth/Height we can freely choose our size within the
|
||||
// parent bounds.
|
||||
assertRect(w.mFrame, 0, 0, 300, 300);
|
||||
|
||||
// With FLAG_SCALED though, requestedWidth/height is used to control
|
||||
// the unscaled surface size, and mAttrs.width/height becomes the
|
||||
// layout controller.
|
||||
w.mAttrs.flags = WindowManager.LayoutParams.FLAG_SCALED;
|
||||
w.mRequestedHeight = -1;
|
||||
w.mRequestedWidth = -1;
|
||||
w.mAttrs.width = 100;
|
||||
w.mAttrs.height = 100;
|
||||
w.computeFrameLw(pf, pf, pf, pf, pf, pf, pf, pf);
|
||||
assertRect(w.mFrame, 0, 0, 100, 100);
|
||||
w.mAttrs.flags = 0;
|
||||
|
||||
// But sizes too large will be clipped to the containing frame
|
||||
w.mRequestedWidth = 1200;
|
||||
w.mRequestedHeight = 1200;
|
||||
w.computeFrameLw(pf, pf, pf, pf, pf, pf, pf, pf);
|
||||
assertRect(w.mFrame, 0, 0, 1000, 1000);
|
||||
|
||||
// Before they are clipped though windows will be shifted
|
||||
w.mAttrs.x = 300;
|
||||
w.mAttrs.y = 300;
|
||||
w.mRequestedWidth = 1000;
|
||||
w.mRequestedHeight = 1000;
|
||||
w.computeFrameLw(pf, pf, pf, pf, pf, pf, pf, pf);
|
||||
assertRect(w.mFrame, 0, 0, 1000, 1000);
|
||||
|
||||
// If there is room to move around in the parent frame the window will be shifted according
|
||||
// to gravity.
|
||||
w.mAttrs.x = 0;
|
||||
w.mAttrs.y = 0;
|
||||
w.mRequestedWidth = 300;
|
||||
w.mRequestedHeight = 300;
|
||||
w.mAttrs.gravity = Gravity.RIGHT | Gravity.TOP;
|
||||
w.computeFrameLw(pf, pf, pf, pf, pf, pf, pf, pf);
|
||||
assertRect(w.mFrame, 700, 0, 1000, 300);
|
||||
w.mAttrs.gravity = Gravity.RIGHT | Gravity.BOTTOM;
|
||||
w.computeFrameLw(pf, pf, pf, pf, pf, pf, pf, pf);
|
||||
assertRect(w.mFrame, 700, 700, 1000, 1000);
|
||||
// Window specified x and y are interpreted as offsets in the opposite
|
||||
// direction of gravity
|
||||
w.mAttrs.x = 100;
|
||||
w.mAttrs.y = 100;
|
||||
w.computeFrameLw(pf, pf, pf, pf, pf, pf, pf, pf);
|
||||
assertRect(w.mFrame, 600, 600, 900, 900);
|
||||
}
|
||||
|
||||
private WindowState createWindow(Task task, int width, int height) {
|
||||
final WindowManager.LayoutParams attrs = new WindowManager.LayoutParams(TYPE_APPLICATION);
|
||||
attrs.width = width;
|
||||
attrs.height = height;
|
||||
|
||||
return new WindowStateWithTask(attrs, task);
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user