Merge "Add app bounds to configuration." into oc-dev
am: 7efe56b779
Change-Id: If871d90a72f675a93503e883135ebee77f12d971
This commit is contained in:
@@ -16,6 +16,11 @@
|
||||
|
||||
package android.content.res;
|
||||
|
||||
import android.graphics.Point;
|
||||
import android.graphics.Rect;
|
||||
import android.util.DisplayMetrics;
|
||||
import android.view.Display;
|
||||
import android.view.DisplayInfo;
|
||||
import com.android.internal.util.XmlUtils;
|
||||
|
||||
import org.xmlpull.v1.XmlPullParser;
|
||||
@@ -293,6 +298,16 @@ public final class Configuration implements Parcelable, Comparable<Configuration
|
||||
*/
|
||||
public int screenLayout;
|
||||
|
||||
/**
|
||||
* @hide
|
||||
* {@link android.graphics.Rect} defining app bounds. The dimensions override usages of
|
||||
* {@link DisplayInfo#appHeight} and {@link DisplayInfo#appWidth} and mirrors these values at
|
||||
* the display level. Lower levels can override these values to provide custom bounds to enforce
|
||||
* features such as a max aspect ratio.
|
||||
* TODO(b/36812336): Move appBounds out of {@link Configuration}.
|
||||
*/
|
||||
public Rect appBounds;
|
||||
|
||||
/** @hide */
|
||||
static public int resetScreenLayout(int curLayout) {
|
||||
return (curLayout&~(SCREENLAYOUT_LONG_MASK | SCREENLAYOUT_SIZE_MASK
|
||||
@@ -882,6 +897,7 @@ public final class Configuration implements Parcelable, Comparable<Configuration
|
||||
compatScreenWidthDp = o.compatScreenWidthDp;
|
||||
compatScreenHeightDp = o.compatScreenHeightDp;
|
||||
compatSmallestScreenWidthDp = o.compatSmallestScreenWidthDp;
|
||||
setAppBounds(o.appBounds);
|
||||
assetsSeq = o.assetsSeq;
|
||||
seq = o.seq;
|
||||
}
|
||||
@@ -1032,6 +1048,9 @@ public final class Configuration implements Parcelable, Comparable<Configuration
|
||||
case NAVIGATIONHIDDEN_YES: sb.append("/h"); break;
|
||||
default: sb.append("/"); sb.append(navigationHidden); break;
|
||||
}
|
||||
if (appBounds != null) {
|
||||
sb.append(" appBounds="); sb.append(appBounds);
|
||||
}
|
||||
if (assetsSeq != 0) {
|
||||
sb.append(" as.").append(assetsSeq);
|
||||
}
|
||||
@@ -1066,6 +1085,7 @@ public final class Configuration implements Parcelable, Comparable<Configuration
|
||||
smallestScreenWidthDp = compatSmallestScreenWidthDp = SMALLEST_SCREEN_WIDTH_DP_UNDEFINED;
|
||||
densityDpi = DENSITY_DPI_UNDEFINED;
|
||||
assetsSeq = ASSETS_SEQ_UNDEFINED;
|
||||
appBounds = null;
|
||||
seq = 0;
|
||||
}
|
||||
|
||||
@@ -1253,6 +1273,10 @@ public final class Configuration implements Parcelable, Comparable<Configuration
|
||||
if (delta.compatSmallestScreenWidthDp != SMALLEST_SCREEN_WIDTH_DP_UNDEFINED) {
|
||||
compatSmallestScreenWidthDp = delta.compatSmallestScreenWidthDp;
|
||||
}
|
||||
if (delta.appBounds != null && !delta.appBounds.equals(appBounds)) {
|
||||
changed |= ActivityInfo.CONFIG_SCREEN_SIZE;
|
||||
setAppBounds(delta.appBounds);
|
||||
}
|
||||
if (delta.assetsSeq != ASSETS_SEQ_UNDEFINED) {
|
||||
changed |= ActivityInfo.CONFIG_ASSETS_PATHS;
|
||||
assetsSeq = delta.assetsSeq;
|
||||
@@ -1399,6 +1423,13 @@ public final class Configuration implements Parcelable, Comparable<Configuration
|
||||
changed |= ActivityInfo.CONFIG_ASSETS_PATHS;
|
||||
}
|
||||
|
||||
// Make sure that one of the values is not null and that they are not equal.
|
||||
if ((compareUndefined || delta.appBounds != null)
|
||||
&& appBounds != delta.appBounds
|
||||
&& (appBounds == null || !appBounds.equals(delta.appBounds))) {
|
||||
changed |= ActivityInfo.CONFIG_SCREEN_SIZE;
|
||||
}
|
||||
|
||||
return changed;
|
||||
}
|
||||
|
||||
@@ -1494,6 +1525,7 @@ public final class Configuration implements Parcelable, Comparable<Configuration
|
||||
dest.writeInt(compatScreenWidthDp);
|
||||
dest.writeInt(compatScreenHeightDp);
|
||||
dest.writeInt(compatSmallestScreenWidthDp);
|
||||
dest.writeValue(appBounds);
|
||||
dest.writeInt(assetsSeq);
|
||||
dest.writeInt(seq);
|
||||
}
|
||||
@@ -1529,6 +1561,7 @@ public final class Configuration implements Parcelable, Comparable<Configuration
|
||||
compatScreenWidthDp = source.readInt();
|
||||
compatScreenHeightDp = source.readInt();
|
||||
compatSmallestScreenWidthDp = source.readInt();
|
||||
appBounds = (Rect) source.readValue(null);
|
||||
assetsSeq = source.readInt();
|
||||
seq = source.readInt();
|
||||
}
|
||||
@@ -1703,6 +1736,33 @@ public final class Configuration implements Parcelable, Comparable<Configuration
|
||||
setLocales(loc == null ? LocaleList.getEmptyLocaleList() : new LocaleList(loc));
|
||||
}
|
||||
|
||||
/**
|
||||
* @hide
|
||||
*
|
||||
* Helper method for setting the app bounds.
|
||||
*/
|
||||
public void setAppBounds(Rect rect) {
|
||||
if (rect == null) {
|
||||
appBounds = null;
|
||||
return;
|
||||
}
|
||||
|
||||
setAppBounds(rect.left, rect.top, rect.right, rect.bottom);
|
||||
}
|
||||
|
||||
/**
|
||||
* @hide
|
||||
*
|
||||
* Helper method for setting the app bounds.
|
||||
*/
|
||||
public void setAppBounds(int left, int top, int right, int bottom) {
|
||||
if (appBounds == null) {
|
||||
appBounds = new Rect();
|
||||
}
|
||||
|
||||
appBounds.set(left, top, right, bottom);
|
||||
}
|
||||
|
||||
/**
|
||||
* @hide
|
||||
*
|
||||
@@ -2212,6 +2272,7 @@ public final class Configuration implements Parcelable, Comparable<Configuration
|
||||
private static final String XML_ATTR_SCREEN_HEIGHT = "height";
|
||||
private static final String XML_ATTR_SMALLEST_WIDTH = "sw";
|
||||
private static final String XML_ATTR_DENSITY = "density";
|
||||
private static final String XML_ATTR_APP_BOUNDS = "app_bounds";
|
||||
|
||||
/**
|
||||
* Reads the attributes corresponding to Configuration member fields from the Xml parser.
|
||||
@@ -2261,6 +2322,8 @@ public final class Configuration implements Parcelable, Comparable<Configuration
|
||||
SMALLEST_SCREEN_WIDTH_DP_UNDEFINED);
|
||||
configOut.densityDpi = XmlUtils.readIntAttribute(parser, XML_ATTR_DENSITY,
|
||||
DENSITY_DPI_UNDEFINED);
|
||||
configOut.appBounds =
|
||||
Rect.unflattenFromString(XmlUtils.readStringAttribute(parser, XML_ATTR_APP_BOUNDS));
|
||||
|
||||
// For persistence, we don't care about assetsSeq, so do not read it out.
|
||||
}
|
||||
@@ -2332,6 +2395,11 @@ public final class Configuration implements Parcelable, Comparable<Configuration
|
||||
XmlUtils.writeIntAttribute(xml, XML_ATTR_DENSITY, config.densityDpi);
|
||||
}
|
||||
|
||||
if (config.appBounds != null) {
|
||||
XmlUtils.writeStringAttribute(xml, XML_ATTR_APP_BOUNDS,
|
||||
config.appBounds.flattenToString());
|
||||
}
|
||||
|
||||
// For persistence, we do not care about assetsSeq, so do not write it out.
|
||||
}
|
||||
}
|
||||
|
||||
@@ -562,12 +562,10 @@ public final class DisplayInfo implements Parcelable {
|
||||
outMetrics.xdpi = outMetrics.noncompatXdpi = physicalXDpi;
|
||||
outMetrics.ydpi = outMetrics.noncompatYdpi = physicalYDpi;
|
||||
|
||||
width = (configuration != null
|
||||
&& configuration.screenWidthDp != Configuration.SCREEN_WIDTH_DP_UNDEFINED)
|
||||
? (int)((configuration.screenWidthDp * outMetrics.density) + 0.5f) : width;
|
||||
height = (configuration != null
|
||||
&& configuration.screenHeightDp != Configuration.SCREEN_HEIGHT_DP_UNDEFINED)
|
||||
? (int)((configuration.screenHeightDp * outMetrics.density) + 0.5f) : height;
|
||||
width = configuration != null && configuration.appBounds != null
|
||||
? configuration.appBounds.width() : width;
|
||||
height = configuration != null && configuration.appBounds != null
|
||||
? configuration.appBounds.height() : height;
|
||||
|
||||
outMetrics.noncompatWidthPixels = outMetrics.widthPixels = width;
|
||||
outMetrics.noncompatHeightPixels = outMetrics.heightPixels = height;
|
||||
|
||||
@@ -20,6 +20,7 @@ import android.annotation.CheckResult;
|
||||
import android.os.Parcel;
|
||||
import android.os.Parcelable;
|
||||
|
||||
import android.text.TextUtils;
|
||||
import java.io.PrintWriter;
|
||||
import java.util.regex.Matcher;
|
||||
import java.util.regex.Pattern;
|
||||
@@ -170,6 +171,10 @@ public final class Rect implements Parcelable {
|
||||
* or null if the string is not of that form.
|
||||
*/
|
||||
public static Rect unflattenFromString(String str) {
|
||||
if (TextUtils.isEmpty(str)) {
|
||||
return null;
|
||||
}
|
||||
|
||||
Matcher matcher = UnflattenHelper.getMatcher(str);
|
||||
if (!matcher.matches()) {
|
||||
return null;
|
||||
@@ -179,7 +184,7 @@ public final class Rect implements Parcelable {
|
||||
Integer.parseInt(matcher.group(3)),
|
||||
Integer.parseInt(matcher.group(4)));
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Print short representation to given writer.
|
||||
* @hide
|
||||
|
||||
@@ -2122,23 +2122,31 @@ final class ActivityRecord extends ConfigurationContainer implements AppWindowCo
|
||||
return true;
|
||||
}
|
||||
|
||||
/** Computes the override configuration for this activity */
|
||||
/**
|
||||
* Computes the bounds to fit the Activity within the bounds of the {@link Configuration}.
|
||||
*/
|
||||
// TODO(b/36505427): Consider moving this method and similar ones to ConfigurationContainer.
|
||||
private void computeBounds(Rect outBounds) {
|
||||
outBounds.setEmpty();
|
||||
final float maxAspectRatio = info.maxAspectRatio;
|
||||
final ActivityStack stack = getStack();
|
||||
if ((task != null && !task.mFullscreen) || maxAspectRatio == 0 || stack == null) {
|
||||
if (task == null || stack == null || !task.mFullscreen || maxAspectRatio == 0) {
|
||||
// We don't set override configuration if that activity task isn't fullscreen. I.e. the
|
||||
// activity is in multi-window mode. Or, there isn't a max aspect ratio specified for
|
||||
// the activity.
|
||||
// the activity. This is indicated by an empty {@link outBounds}.
|
||||
return;
|
||||
}
|
||||
|
||||
stack.getDisplaySize(mTmpPoint);
|
||||
int maxActivityWidth = mTmpPoint.x;
|
||||
int maxActivityHeight = mTmpPoint.y;
|
||||
if (mTmpPoint.x < mTmpPoint.y) {
|
||||
// We must base this on the parent configuration, because we set our override
|
||||
// configuration's appBounds based on the result of this method. If we used our own
|
||||
// configuration, it would be influenced by past invocations.
|
||||
final Configuration configuration = getParent().getConfiguration();
|
||||
final int containingAppWidth = configuration.appBounds.width();
|
||||
final int containingAppHeight = configuration.appBounds.height();
|
||||
int maxActivityWidth = containingAppWidth;
|
||||
int maxActivityHeight = containingAppHeight;
|
||||
|
||||
if (containingAppWidth < containingAppHeight) {
|
||||
// Width is the shorter side, so we use that to figure-out what the max. height should
|
||||
// be given the aspect ratio.
|
||||
maxActivityHeight = (int) ((maxActivityWidth * maxAspectRatio) + 0.5f);
|
||||
@@ -2148,8 +2156,14 @@ final class ActivityRecord extends ConfigurationContainer implements AppWindowCo
|
||||
maxActivityWidth = (int) ((maxActivityHeight * maxAspectRatio) + 0.5f);
|
||||
}
|
||||
|
||||
if (mTmpPoint.x <= maxActivityWidth && mTmpPoint.y <= maxActivityHeight) {
|
||||
if (containingAppWidth <= maxActivityWidth && containingAppHeight <= maxActivityHeight) {
|
||||
// The display matches or is less than the activity aspect ratio, so nothing else to do.
|
||||
// Return the existing bounds. If this method is running for the first time,
|
||||
// {@link mBounds} will be empty (representing no override). If the method has run
|
||||
// before, then effect of {@link mBounds} will already have been applied to the
|
||||
// value returned from {@link getConfiguration}. Refer to
|
||||
// {@link TaskRecord#computeOverrideConfiguration}.
|
||||
outBounds.set(mBounds);
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
@@ -2044,6 +2044,7 @@ final class TaskRecord extends ConfigurationContainer implements TaskWindowConta
|
||||
|
||||
config.unset();
|
||||
final Configuration parentConfig = getParent().getConfiguration();
|
||||
|
||||
final float density = parentConfig.densityDpi * DisplayMetrics.DENSITY_DEFAULT_SCALE;
|
||||
|
||||
if (mStack != null) {
|
||||
@@ -2052,11 +2053,7 @@ final class TaskRecord extends ConfigurationContainer implements TaskWindowConta
|
||||
mTmpNonDecorBounds, mTmpStableBounds, overrideWidth, overrideHeight, density,
|
||||
config, parentConfig);
|
||||
} else {
|
||||
// No stack, give some default values
|
||||
config.smallestScreenWidthDp =
|
||||
mService.mStackSupervisor.mDefaultMinSizeOfResizeableTask;
|
||||
config.screenWidthDp = config.screenHeightDp = config.smallestScreenWidthDp;
|
||||
Slog.wtf(TAG, "Expected stack when calculating override config");
|
||||
throw new IllegalArgumentException("Expected stack when calculating override config");
|
||||
}
|
||||
|
||||
config.orientation = (config.screenWidthDp <= config.screenHeightDp)
|
||||
|
||||
@@ -1134,6 +1134,13 @@ class DisplayContent extends WindowContainer<DisplayContent.DisplayChildWindowCo
|
||||
config.screenHeightDp =
|
||||
(int)(mService.mPolicy.getConfigDisplayHeight(dw, dh, displayInfo.rotation,
|
||||
config.uiMode, mDisplayId) / mDisplayMetrics.density);
|
||||
|
||||
mService.mPolicy.getNonDecorInsetsLw(displayInfo.rotation, dw, dh, mTmpRect);
|
||||
final int leftInset = mTmpRect.left;
|
||||
final int topInset = mTmpRect.top;
|
||||
// appBounds at the root level should mirror the app screen size.
|
||||
config.setAppBounds(leftInset /*left*/, topInset /*top*/, leftInset + displayInfo.appWidth /*right*/,
|
||||
topInset + displayInfo.appHeight /*bottom*/);
|
||||
final boolean rotated = (displayInfo.rotation == Surface.ROTATION_90
|
||||
|| displayInfo.rotation == Surface.ROTATION_270);
|
||||
|
||||
|
||||
@@ -225,14 +225,25 @@ public class DockedStackDividerController implements DimLayerUser {
|
||||
mService.mPolicy.getStableInsetsLw(rotation, dw, dh, mTmpRect);
|
||||
config.unset();
|
||||
config.orientation = (dw <= dh) ? ORIENTATION_PORTRAIT : ORIENTATION_LANDSCAPE;
|
||||
|
||||
final int displayId = mDisplayContent.getDisplayId();
|
||||
final int appWidth = mService.mPolicy.getNonDecorDisplayWidth(dw, dh, rotation,
|
||||
baseConfig.uiMode, displayId);
|
||||
final int appHeight = mService.mPolicy.getNonDecorDisplayHeight(dw, dh, rotation,
|
||||
baseConfig.uiMode, displayId);
|
||||
mService.mPolicy.getNonDecorInsetsLw(rotation, dw, dh, mTmpRect);
|
||||
final int leftInset = mTmpRect.left;
|
||||
final int topInset = mTmpRect.top;
|
||||
|
||||
config.setAppBounds(leftInset /*left*/, topInset /*top*/, leftInset + appWidth /*right*/,
|
||||
topInset + appHeight /*bottom*/);
|
||||
|
||||
config.screenWidthDp = (int)
|
||||
(mService.mPolicy.getConfigDisplayWidth(dw, dh, rotation, baseConfig.uiMode,
|
||||
mDisplayContent.getDisplayId()) /
|
||||
mDisplayContent.getDisplayMetrics().density);
|
||||
displayId) / mDisplayContent.getDisplayMetrics().density);
|
||||
config.screenHeightDp = (int)
|
||||
(mService.mPolicy.getConfigDisplayHeight(dw, dh, rotation, baseConfig.uiMode,
|
||||
mDisplayContent.getDisplayId()) /
|
||||
mDisplayContent.getDisplayMetrics().density);
|
||||
displayId) / mDisplayContent.getDisplayMetrics().density);
|
||||
final Context rotationContext = mService.mContext.createConfigurationContext(config);
|
||||
mSnapAlgorithmForRotation[rotation] = new DividerSnapAlgorithm(
|
||||
rotationContext.getResources(), dw, dh, getContentWidth(),
|
||||
|
||||
@@ -270,6 +270,12 @@ public class StackWindowController
|
||||
|
||||
int width;
|
||||
int height;
|
||||
|
||||
final Rect parentAppBounds = parentConfig.appBounds;
|
||||
|
||||
config.setAppBounds(!bounds.isEmpty() ? bounds : null);
|
||||
boolean intersectParentBounds = false;
|
||||
|
||||
if (StackId.tasksAreFloating(mStackId)) {
|
||||
// Floating tasks should not be resized to the screen's bounds.
|
||||
|
||||
@@ -280,6 +286,7 @@ public class StackWindowController
|
||||
// the fullscreen stack, without intersecting it with the display bounds
|
||||
stableBounds.inset(mTmpStableInsets);
|
||||
nonDecorBounds.inset(mTmpNonDecorInsets);
|
||||
intersectParentBounds = true;
|
||||
}
|
||||
width = (int) (stableBounds.width() / density);
|
||||
height = (int) (stableBounds.height() / density);
|
||||
@@ -299,6 +306,11 @@ public class StackWindowController
|
||||
parentConfig.screenWidthDp);
|
||||
height = Math.min((int) (stableBounds.height() / density),
|
||||
parentConfig.screenHeightDp);
|
||||
intersectParentBounds = true;
|
||||
}
|
||||
|
||||
if (intersectParentBounds && config.appBounds != null) {
|
||||
config.appBounds.intersect(parentAppBounds);
|
||||
}
|
||||
|
||||
config.screenWidthDp = width;
|
||||
|
||||
@@ -0,0 +1,144 @@
|
||||
/*
|
||||
* Copyright (C) 2017 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 android.app.ActivityManager;
|
||||
import android.content.res.Configuration;
|
||||
import android.graphics.Rect;
|
||||
import android.os.Debug;
|
||||
import android.view.DisplayInfo;
|
||||
import org.junit.Test;
|
||||
|
||||
import android.platform.test.annotations.Presubmit;
|
||||
import android.support.test.filters.SmallTest;
|
||||
import android.support.test.runner.AndroidJUnit4;
|
||||
|
||||
import static org.junit.Assert.assertEquals;
|
||||
import static org.junit.Assert.assertTrue;
|
||||
|
||||
/**
|
||||
* Test class to exercise logic related to {@link android.content.res.Configuration#appBounds}.
|
||||
*
|
||||
* Build/Install/Run:
|
||||
* bit FrameworksServicesTests:com.android.server.wm.AppBoundsTests
|
||||
*/
|
||||
@SmallTest
|
||||
@Presubmit
|
||||
@org.junit.runner.RunWith(AndroidJUnit4.class)
|
||||
public class AppBoundsTests extends WindowTestsBase {
|
||||
private Rect mParentBounds;
|
||||
|
||||
@Override
|
||||
public void setUp() throws Exception {
|
||||
super.setUp();
|
||||
mParentBounds = new Rect(10 /*left*/, 30 /*top*/, 80 /*right*/, 60 /*bottom*/);
|
||||
}
|
||||
|
||||
/**
|
||||
* Ensures the configuration app bounds at the root level match the app dimensions.
|
||||
*/
|
||||
@Test
|
||||
public void testRootConfigurationBounds() throws Exception {
|
||||
final DisplayInfo info = sDisplayContent.getDisplayInfo();
|
||||
info.appWidth = 1024;
|
||||
info.appHeight = 768;
|
||||
|
||||
final Configuration config = sWm.computeNewConfiguration(sDisplayContent.getDisplayId());
|
||||
// The bounds should always be positioned in the top left.
|
||||
assertEquals(config.appBounds.left, 0);
|
||||
assertEquals(config.appBounds.top, 0);
|
||||
|
||||
// The bounds should equal the defined app width and height
|
||||
assertEquals(config.appBounds.width(), info.appWidth);
|
||||
assertEquals(config.appBounds.height(), info.appHeight);
|
||||
}
|
||||
|
||||
/**
|
||||
* Ensures that bounds are clipped to their parent.
|
||||
*/
|
||||
@Test
|
||||
public void testBoundsClipping() throws Exception {
|
||||
final Rect shiftedBounds = new Rect(mParentBounds);
|
||||
shiftedBounds.offset(10, 10);
|
||||
final Rect expectedBounds = new Rect(mParentBounds);
|
||||
expectedBounds.intersect(shiftedBounds);
|
||||
testStackBoundsConfiguration(null /*stackId*/, mParentBounds, shiftedBounds,
|
||||
expectedBounds);
|
||||
}
|
||||
|
||||
/**
|
||||
* Ensures that empty bounds are not propagated to the configuration.
|
||||
*/
|
||||
@Test
|
||||
public void testEmptyBounds() throws Exception {
|
||||
final Rect emptyBounds = new Rect();
|
||||
testStackBoundsConfiguration(null /*stackId*/, mParentBounds, emptyBounds,
|
||||
null /*ExpectedBounds*/);
|
||||
}
|
||||
|
||||
/**
|
||||
* Ensures that bounds on freeform stacks are not clipped.
|
||||
*/
|
||||
@Test
|
||||
public void testFreeFormBounds() throws Exception {
|
||||
final Rect freeFormBounds = new Rect(mParentBounds);
|
||||
freeFormBounds.offset(10, 10);
|
||||
testStackBoundsConfiguration(ActivityManager.StackId.FREEFORM_WORKSPACE_STACK_ID,
|
||||
mParentBounds, freeFormBounds, freeFormBounds);
|
||||
}
|
||||
|
||||
/**
|
||||
* Ensures that fully contained bounds are not clipped.
|
||||
*/
|
||||
@Test
|
||||
public void testContainedBounds() throws Exception {
|
||||
final Rect insetBounds = new Rect(mParentBounds);
|
||||
insetBounds.inset(5, 5, 5, 5);
|
||||
testStackBoundsConfiguration(null /*stackId*/, mParentBounds, insetBounds, insetBounds);
|
||||
}
|
||||
|
||||
/**
|
||||
* Ensures that full screen free form bounds are clipped
|
||||
*/
|
||||
@Test
|
||||
public void testFullScreenFreeFormBounds() throws Exception {
|
||||
final Rect fullScreenBounds = new Rect(0, 0, sDisplayInfo.logicalWidth,
|
||||
sDisplayInfo.logicalHeight);
|
||||
testStackBoundsConfiguration(null /*stackId*/, mParentBounds, fullScreenBounds,
|
||||
mParentBounds);
|
||||
}
|
||||
|
||||
|
||||
private void testStackBoundsConfiguration(Integer stackId, Rect parentBounds, Rect bounds,
|
||||
Rect expectedConfigBounds) {
|
||||
final StackWindowController stackController = stackId != null ?
|
||||
createStackControllerOnStackOnDisplay(stackId, sDisplayContent)
|
||||
: createStackControllerOnDisplay(sDisplayContent);
|
||||
|
||||
final Configuration parentConfig = sDisplayContent.getConfiguration();
|
||||
parentConfig.setAppBounds(parentBounds);
|
||||
|
||||
final Configuration config = new Configuration();
|
||||
stackController.adjustConfigurationForBounds(bounds, null /*insetBounds*/,
|
||||
new Rect() /*nonDecorBounds*/, new Rect() /*stableBounds*/, false /*overrideWidth*/,
|
||||
false /*overrideHeight*/, sDisplayInfo.logicalDensityDpi, config, parentConfig);
|
||||
// Assert that both expected and actual are null or are equal to each other
|
||||
|
||||
assertTrue((expectedConfigBounds == null && config.appBounds == null)
|
||||
|| expectedConfigBounds.equals(config.appBounds));
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user