Merge changes from topic "sandboxing-display" into sc-dev
* changes: Temporarily exclude Launcher from sandboxing; to be reverted once bug is addressed. Sandbox letterbox and size compat apps
This commit is contained in:
committed by
Android (Google) Code Review
commit
c50df25a88
@@ -24,8 +24,11 @@ import android.annotation.Nullable;
|
||||
import android.annotation.RequiresPermission;
|
||||
import android.annotation.SuppressLint;
|
||||
import android.annotation.TestApi;
|
||||
import android.app.ActivityThread;
|
||||
import android.app.KeyguardManager;
|
||||
import android.app.WindowConfiguration;
|
||||
import android.compat.annotation.UnsupportedAppUsage;
|
||||
import android.content.ComponentName;
|
||||
import android.content.res.CompatibilityInfo;
|
||||
import android.content.res.Configuration;
|
||||
import android.content.res.Resources;
|
||||
@@ -44,11 +47,14 @@ import android.os.SystemClock;
|
||||
import android.util.DisplayMetrics;
|
||||
import android.util.Log;
|
||||
|
||||
import com.android.internal.R;
|
||||
|
||||
import java.lang.annotation.Retention;
|
||||
import java.lang.annotation.RetentionPolicy;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Arrays;
|
||||
import java.util.List;
|
||||
import java.util.Optional;
|
||||
|
||||
/**
|
||||
* Provides information about the size and density of a logical display.
|
||||
@@ -111,6 +117,12 @@ public final class Display {
|
||||
*/
|
||||
private boolean mMayAdjustByFixedRotation;
|
||||
|
||||
/**
|
||||
* Cache if the application is the recents component.
|
||||
* TODO(b/179308296) Remove once Launcher addresses issue
|
||||
*/
|
||||
private Optional<Boolean> mIsRecentsComponent = Optional.empty();
|
||||
|
||||
/**
|
||||
* The default Display id, which is the id of the primary display assuming there is one.
|
||||
*/
|
||||
@@ -678,9 +690,9 @@ public final class Display {
|
||||
@UnsupportedAppUsage
|
||||
public DisplayAdjustments getDisplayAdjustments() {
|
||||
if (mResources != null) {
|
||||
final DisplayAdjustments currentAdjustements = mResources.getDisplayAdjustments();
|
||||
if (!mDisplayAdjustments.equals(currentAdjustements)) {
|
||||
mDisplayAdjustments = new DisplayAdjustments(currentAdjustements);
|
||||
final DisplayAdjustments currentAdjustments = mResources.getDisplayAdjustments();
|
||||
if (!mDisplayAdjustments.equals(currentAdjustments)) {
|
||||
mDisplayAdjustments = new DisplayAdjustments(currentAdjustments);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1278,6 +1290,18 @@ public final class Display {
|
||||
public void getRealSize(Point outSize) {
|
||||
synchronized (this) {
|
||||
updateDisplayInfoLocked();
|
||||
if (shouldReportMaxBounds()) {
|
||||
final Rect bounds = mResources.getConfiguration()
|
||||
.windowConfiguration.getMaxBounds();
|
||||
outSize.x = bounds.width();
|
||||
outSize.y = bounds.height();
|
||||
if (DEBUG) {
|
||||
Log.d(TAG, "getRealSize determined from max bounds: " + outSize);
|
||||
}
|
||||
// Skip adjusting by fixed rotation, since if it is necessary, the configuration
|
||||
// should already reflect the expected rotation.
|
||||
return;
|
||||
}
|
||||
outSize.x = mDisplayInfo.logicalWidth;
|
||||
outSize.y = mDisplayInfo.logicalHeight;
|
||||
if (mMayAdjustByFixedRotation) {
|
||||
@@ -1336,6 +1360,17 @@ public final class Display {
|
||||
public void getRealMetrics(DisplayMetrics outMetrics) {
|
||||
synchronized (this) {
|
||||
updateDisplayInfoLocked();
|
||||
if (shouldReportMaxBounds()) {
|
||||
mDisplayInfo.getMaxBoundsMetrics(outMetrics,
|
||||
CompatibilityInfo.DEFAULT_COMPATIBILITY_INFO,
|
||||
mResources.getConfiguration());
|
||||
if (DEBUG) {
|
||||
Log.d(TAG, "getRealMetrics determined from max bounds: " + outMetrics);
|
||||
}
|
||||
// Skip adjusting by fixed rotation, since if it is necessary, the configuration
|
||||
// should already reflect the expected rotation.
|
||||
return;
|
||||
}
|
||||
mDisplayInfo.getLogicalMetrics(outMetrics,
|
||||
CompatibilityInfo.DEFAULT_COMPATIBILITY_INFO, null);
|
||||
if (mMayAdjustByFixedRotation) {
|
||||
@@ -1344,6 +1379,53 @@ public final class Display {
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Determines if {@link WindowConfiguration#getMaxBounds()} should be reported as the
|
||||
* display dimensions. The max bounds field may be smaller than the logical dimensions
|
||||
* when apps need to be sandboxed.
|
||||
*
|
||||
* Depends upon {@link WindowConfiguration#getMaxBounds()} being set in
|
||||
* {@link com.android.server.wm.ConfigurationContainer#providesMaxBounds()}. In most cases, this
|
||||
* value reflects the size of the current DisplayArea.
|
||||
* @return {@code true} when max bounds should be applied.
|
||||
*/
|
||||
private boolean shouldReportMaxBounds() {
|
||||
if (mResources == null) {
|
||||
return false;
|
||||
}
|
||||
final Configuration config = mResources.getConfiguration();
|
||||
// TODO(b/179308296) Temporarily exclude Launcher from being given max bounds, by checking
|
||||
// if the caller is the recents component.
|
||||
return config != null && !config.windowConfiguration.getMaxBounds().isEmpty()
|
||||
&& !isRecentsComponent();
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns {@code true} when the calling package is the recents component.
|
||||
* TODO(b/179308296) Remove once Launcher addresses issue
|
||||
*/
|
||||
boolean isRecentsComponent() {
|
||||
if (mIsRecentsComponent.isPresent()) {
|
||||
return mIsRecentsComponent.get();
|
||||
}
|
||||
if (mResources == null) {
|
||||
return false;
|
||||
}
|
||||
try {
|
||||
String recentsComponent = mResources.getString(R.string.config_recentsComponentName);
|
||||
if (recentsComponent == null) {
|
||||
return false;
|
||||
}
|
||||
String recentsPackage = ComponentName.unflattenFromString(recentsComponent)
|
||||
.getPackageName();
|
||||
mIsRecentsComponent = Optional.of(recentsPackage != null
|
||||
&& recentsPackage.equals(ActivityThread.currentPackageName()));
|
||||
return mIsRecentsComponent.get();
|
||||
} catch (Resources.NotFoundException e) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the state of the display, such as whether it is on or off.
|
||||
*
|
||||
|
||||
@@ -24,6 +24,7 @@ import static android.view.DisplayInfoProto.LOGICAL_WIDTH;
|
||||
import static android.view.DisplayInfoProto.NAME;
|
||||
|
||||
import android.annotation.Nullable;
|
||||
import android.app.WindowConfiguration;
|
||||
import android.compat.annotation.UnsupportedAppUsage;
|
||||
import android.content.res.CompatibilityInfo;
|
||||
import android.content.res.Configuration;
|
||||
@@ -615,11 +616,29 @@ public final class DisplayInfo implements Parcelable {
|
||||
getMetricsWithSize(outMetrics, ci, configuration, appWidth, appHeight);
|
||||
}
|
||||
|
||||
/**
|
||||
* Populates {@code outMetrics} with details of the logical display. Bounds are limited
|
||||
* by the logical size of the display.
|
||||
*
|
||||
* @param outMetrics the {@link DisplayMetrics} to be populated
|
||||
* @param compatInfo the {@link CompatibilityInfo} to be applied
|
||||
* @param configuration the {@link Configuration}
|
||||
*/
|
||||
public void getLogicalMetrics(DisplayMetrics outMetrics, CompatibilityInfo compatInfo,
|
||||
Configuration configuration) {
|
||||
getMetricsWithSize(outMetrics, compatInfo, configuration, logicalWidth, logicalHeight);
|
||||
}
|
||||
|
||||
/**
|
||||
* Similar to {@link #getLogicalMetrics}, but the limiting bounds are determined from
|
||||
* {@link WindowConfiguration#getMaxBounds()}
|
||||
*/
|
||||
public void getMaxBoundsMetrics(DisplayMetrics outMetrics, CompatibilityInfo compatInfo,
|
||||
Configuration configuration) {
|
||||
Rect bounds = configuration.windowConfiguration.getMaxBounds();
|
||||
getMetricsWithSize(outMetrics, compatInfo, configuration, bounds.width(), bounds.height());
|
||||
}
|
||||
|
||||
public int getNaturalWidth() {
|
||||
return rotation == Surface.ROTATION_0 || rotation == Surface.ROTATION_180 ?
|
||||
logicalWidth : logicalHeight;
|
||||
|
||||
531
core/tests/mockingcoretests/src/android/view/DisplayTests.java
Normal file
531
core/tests/mockingcoretests/src/android/view/DisplayTests.java
Normal file
@@ -0,0 +1,531 @@
|
||||
/*
|
||||
* Copyright (C) 2021 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 android.view;
|
||||
|
||||
import static android.view.Display.DEFAULT_DISPLAY;
|
||||
import static android.view.Surface.ROTATION_0;
|
||||
import static android.view.Surface.ROTATION_90;
|
||||
|
||||
import static com.android.dx.mockito.inline.extended.ExtendedMockito.anyInt;
|
||||
import static com.android.dx.mockito.inline.extended.ExtendedMockito.doReturn;
|
||||
import static com.android.dx.mockito.inline.extended.ExtendedMockito.mock;
|
||||
import static com.android.dx.mockito.inline.extended.ExtendedMockito.mockitoSession;
|
||||
|
||||
import static com.google.common.truth.Truth.assertThat;
|
||||
|
||||
import android.content.Context;
|
||||
import android.content.res.Resources;
|
||||
import android.graphics.Point;
|
||||
import android.graphics.Rect;
|
||||
import android.hardware.display.DisplayManagerGlobal;
|
||||
import android.platform.test.annotations.Presubmit;
|
||||
import android.util.DisplayMetrics;
|
||||
import android.view.DisplayAdjustments.FixedRotationAdjustments;
|
||||
|
||||
import androidx.test.core.app.ApplicationProvider;
|
||||
import androidx.test.ext.junit.runners.AndroidJUnit4;
|
||||
import androidx.test.filters.SmallTest;
|
||||
|
||||
import com.android.dx.mockito.inline.extended.StaticMockitoSession;
|
||||
|
||||
import org.junit.After;
|
||||
import org.junit.Before;
|
||||
import org.junit.Test;
|
||||
import org.junit.runner.RunWith;
|
||||
import org.mockito.Mockito;
|
||||
import org.mockito.quality.Strictness;
|
||||
|
||||
import java.util.function.Consumer;
|
||||
|
||||
/**
|
||||
* Tests for {@link Display}.
|
||||
*
|
||||
* <p>Build/Install/Run:
|
||||
*
|
||||
* atest FrameworksMockingCoreTests:android.view.DisplayTests
|
||||
*/
|
||||
@RunWith(AndroidJUnit4.class)
|
||||
@SmallTest
|
||||
@Presubmit
|
||||
public class DisplayTests {
|
||||
|
||||
private static final int APP_WIDTH = 272;
|
||||
private static final int APP_HEIGHT = 700;
|
||||
// Tablet size device, ROTATION_0 corresponds to portrait.
|
||||
private static final int LOGICAL_WIDTH = 700;
|
||||
private static final int LOGICAL_HEIGHT = 1800;
|
||||
|
||||
// Bounds of the app when the device is in portrait mode.
|
||||
private static Rect sAppBoundsPortrait = buildAppBounds(LOGICAL_WIDTH, LOGICAL_HEIGHT);
|
||||
private static Rect sAppBoundsLandscape = buildAppBounds(LOGICAL_HEIGHT, LOGICAL_WIDTH);
|
||||
|
||||
private StaticMockitoSession mMockitoSession;
|
||||
|
||||
private DisplayManagerGlobal mDisplayManagerGlobal;
|
||||
private Context mApplicationContext;
|
||||
private DisplayInfo mDisplayInfo = new DisplayInfo();
|
||||
|
||||
@Before
|
||||
public void setupTests() {
|
||||
mMockitoSession = mockitoSession()
|
||||
.mockStatic(DisplayManagerGlobal.class)
|
||||
.strictness(Strictness.LENIENT)
|
||||
.startMocking();
|
||||
|
||||
// Ensure no adjustments are set before each test.
|
||||
mApplicationContext = ApplicationProvider.getApplicationContext();
|
||||
DisplayAdjustments displayAdjustments =
|
||||
mApplicationContext.getResources().getDisplayAdjustments();
|
||||
displayAdjustments.setFixedRotationAdjustments(null);
|
||||
mApplicationContext.getResources().overrideDisplayAdjustments(null);
|
||||
mApplicationContext.getResources().getConfiguration().windowConfiguration.setAppBounds(
|
||||
null);
|
||||
mApplicationContext.getResources().getConfiguration().windowConfiguration.setMaxBounds(
|
||||
null);
|
||||
mDisplayInfo.rotation = ROTATION_0;
|
||||
|
||||
mDisplayManagerGlobal = mock(DisplayManagerGlobal.class);
|
||||
doReturn(mDisplayInfo).when(mDisplayManagerGlobal).getDisplayInfo(anyInt());
|
||||
}
|
||||
|
||||
@After
|
||||
public void teardownTests() {
|
||||
if (mMockitoSession != null) {
|
||||
mMockitoSession.finishMocking();
|
||||
}
|
||||
Mockito.framework().clearInlineMocks();
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testConstructor_defaultDisplayAdjustments_matchesDisplayInfo() {
|
||||
setDisplayInfoPortrait(mDisplayInfo);
|
||||
final Display display = new Display(mDisplayManagerGlobal, DEFAULT_DISPLAY, mDisplayInfo,
|
||||
DisplayAdjustments.DEFAULT_DISPLAY_ADJUSTMENTS);
|
||||
assertThat(display.getDisplayAdjustments()).isEqualTo(
|
||||
DisplayAdjustments.DEFAULT_DISPLAY_ADJUSTMENTS);
|
||||
DisplayInfo actualDisplayInfo = new DisplayInfo();
|
||||
display.getDisplayInfo(actualDisplayInfo);
|
||||
verifyDisplayInfo(actualDisplayInfo, mDisplayInfo);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testConstructor_defaultResources_matchesDisplayInfo() {
|
||||
setDisplayInfoPortrait(mDisplayInfo);
|
||||
final Display display = new Display(mDisplayManagerGlobal, DEFAULT_DISPLAY, mDisplayInfo,
|
||||
mApplicationContext.getResources());
|
||||
assertThat(display.getDisplayAdjustments()).isEqualTo(
|
||||
mApplicationContext.getResources().getDisplayAdjustments());
|
||||
DisplayInfo actualDisplayInfo = new DisplayInfo();
|
||||
display.getDisplayInfo(actualDisplayInfo);
|
||||
verifyDisplayInfo(actualDisplayInfo, mDisplayInfo);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testGetRotation_defaultDisplayAdjustments_rotationNotAdjusted() {
|
||||
setDisplayInfoPortrait(mDisplayInfo);
|
||||
final Display display = new Display(mDisplayManagerGlobal, DEFAULT_DISPLAY, mDisplayInfo,
|
||||
DisplayAdjustments.DEFAULT_DISPLAY_ADJUSTMENTS);
|
||||
assertThat(display.getRotation()).isEqualTo(ROTATION_0);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testGetRotation_displayAdjustmentsWithoutOverride_rotationNotAdjusted() {
|
||||
// GIVEN display is not rotated.
|
||||
setDisplayInfoPortrait(mDisplayInfo);
|
||||
// GIVEN fixed rotation adjustments are rotated, but no override is set.
|
||||
DisplayAdjustments displayAdjustments = DisplayAdjustments.DEFAULT_DISPLAY_ADJUSTMENTS;
|
||||
final FixedRotationAdjustments fixedRotationAdjustments =
|
||||
new FixedRotationAdjustments(ROTATION_90, APP_WIDTH, APP_HEIGHT,
|
||||
DisplayCutout.NO_CUTOUT);
|
||||
displayAdjustments.setFixedRotationAdjustments(fixedRotationAdjustments);
|
||||
// GIVEN display is constructed with display adjustments.
|
||||
final Display display = new Display(mDisplayManagerGlobal, DEFAULT_DISPLAY, mDisplayInfo,
|
||||
displayAdjustments);
|
||||
// THEN rotation is not adjusted since no override was set.
|
||||
assertThat(display.getRotation()).isEqualTo(ROTATION_0);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testGetRotation_resourcesWithoutOverride_rotationNotAdjusted() {
|
||||
// GIVEN display is not rotated.
|
||||
setDisplayInfoPortrait(mDisplayInfo);
|
||||
// GIVEN fixed rotation adjustments are rotated, but no override is set.
|
||||
setFixedRotationAdjustments(mApplicationContext.getResources(), ROTATION_90);
|
||||
// GIVEN display is constructed with default resources.
|
||||
final Display display = new Display(mDisplayManagerGlobal, DEFAULT_DISPLAY, mDisplayInfo,
|
||||
mApplicationContext.getResources());
|
||||
// THEN rotation is not adjusted since no override is set.
|
||||
assertThat(display.getRotation()).isEqualTo(ROTATION_0);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testGetRotation_resourcesWithOverrideDisplayAdjustments_rotationAdjusted() {
|
||||
// GIVEN display is not rotated.
|
||||
setDisplayInfoPortrait(mDisplayInfo);
|
||||
// GIVEN fixed rotation adjustments are rotated, and an override is set.
|
||||
setOverrideFixedRotationAdjustments(mApplicationContext.getResources(), ROTATION_90);
|
||||
// GIVEN display is constructed with default resources.
|
||||
final Display display = new Display(mDisplayManagerGlobal, DEFAULT_DISPLAY, mDisplayInfo,
|
||||
mApplicationContext.getResources());
|
||||
// THEN rotation is adjusted since an override is set.
|
||||
assertThat(display.getRotation()).isEqualTo(ROTATION_90);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testGetRealSize_defaultResourcesPortrait_matchesLogicalSize() {
|
||||
// GIVEN display is not rotated.
|
||||
setDisplayInfoPortrait(mDisplayInfo);
|
||||
final Display display = new Display(mDisplayManagerGlobal, DEFAULT_DISPLAY, mDisplayInfo,
|
||||
mApplicationContext.getResources());
|
||||
// THEN real size matches display orientation.
|
||||
verifyRealSizeIsPortrait(display);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testGetRealSize_defaultResourcesLandscape_matchesRotatedLogicalSize() {
|
||||
// GIVEN display is rotated.
|
||||
setDisplayInfoLandscape(mDisplayInfo);
|
||||
final Display display = new Display(mDisplayManagerGlobal, DEFAULT_DISPLAY, mDisplayInfo,
|
||||
mApplicationContext.getResources());
|
||||
// THEN real size matches display orientation.
|
||||
verifyRealSizeIsLandscape(display);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testGetRealSize_defaultDisplayAdjustmentsPortrait_matchesLogicalSize() {
|
||||
// GIVEN display is not rotated.
|
||||
setDisplayInfoPortrait(mDisplayInfo);
|
||||
final Display display = new Display(mDisplayManagerGlobal, DEFAULT_DISPLAY, mDisplayInfo,
|
||||
DisplayAdjustments.DEFAULT_DISPLAY_ADJUSTMENTS);
|
||||
// THEN real size matches display orientation.
|
||||
verifyRealSizeIsPortrait(display);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testGetRealSize_defaultDisplayAdjustmentsLandscape_matchesLogicalSize() {
|
||||
// GIVEN display is rotated.
|
||||
setDisplayInfoLandscape(mDisplayInfo);
|
||||
final Display display = new Display(mDisplayManagerGlobal, DEFAULT_DISPLAY, mDisplayInfo,
|
||||
DisplayAdjustments.DEFAULT_DISPLAY_ADJUSTMENTS);
|
||||
// THEN real size matches display orientation.
|
||||
verifyRealSizeIsLandscape(display);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testGetRealSize_resourcesPortraitWithFixedRotation_notRotatedLogicalSize() {
|
||||
// GIVEN display is rotated.
|
||||
setDisplayInfoLandscape(mDisplayInfo);
|
||||
// GIVEN fixed rotation adjustments are rotated.
|
||||
setFixedRotationAdjustments(mApplicationContext.getResources(), ROTATION_0);
|
||||
// GIVEN display is constructed with default resources.
|
||||
final Display display = new Display(mDisplayManagerGlobal, DEFAULT_DISPLAY, mDisplayInfo,
|
||||
mApplicationContext.getResources());
|
||||
// THEN real size matches display orientation.
|
||||
verifyRealSizeIsLandscape(display);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testGetRealSize_resourcesWithLandscapeFixedRotation_notRotatedLogicalSize() {
|
||||
// GIVEN display is not rotated.
|
||||
setDisplayInfoPortrait(mDisplayInfo);
|
||||
// GIVEN fixed rotation adjustments are rotated.
|
||||
setFixedRotationAdjustments(mApplicationContext.getResources(), ROTATION_90);
|
||||
// GIVEN display is constructed with default resources.
|
||||
final Display display = new Display(mDisplayManagerGlobal, DEFAULT_DISPLAY, mDisplayInfo,
|
||||
mApplicationContext.getResources());
|
||||
// THEN real size matches display orientation.
|
||||
verifyRealSizeIsPortrait(display);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testGetRealSize_resourcesWithPortraitOverrideRotation_rotatedLogicalSize() {
|
||||
// GIVEN display is rotated.
|
||||
setDisplayInfoLandscape(mDisplayInfo);
|
||||
// GIVEN fixed rotation adjustments are rotated, and an override is set.
|
||||
setOverrideFixedRotationAdjustments(mApplicationContext.getResources(), ROTATION_0);
|
||||
// GIVEN display is constructed with default resources.
|
||||
final Display display = new Display(mDisplayManagerGlobal, DEFAULT_DISPLAY, mDisplayInfo,
|
||||
mApplicationContext.getResources());
|
||||
// THEN real size matches app orientation.
|
||||
verifyRealSizeIsPortrait(display);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testGetRealSize_resourcesWithLandscapeOverrideRotation_rotatedLogicalSize() {
|
||||
// GIVEN display is not rotated.
|
||||
setDisplayInfoPortrait(mDisplayInfo);
|
||||
// GIVEN fixed rotation adjustments are rotated, and an override is set.
|
||||
setOverrideFixedRotationAdjustments(mApplicationContext.getResources(), ROTATION_90);
|
||||
// GIVEN display is constructed with default resources.
|
||||
final Display display = new Display(mDisplayManagerGlobal, DEFAULT_DISPLAY, mDisplayInfo,
|
||||
mApplicationContext.getResources());
|
||||
// THEN real size matches app orientation.
|
||||
verifyRealSizeIsLandscape(display);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testGetRealSize_resourcesPortraitSandboxed_matchesSandboxBounds() {
|
||||
// GIVEN display is not rotated.
|
||||
setDisplayInfoPortrait(mDisplayInfo);
|
||||
// GIVEN app is letterboxed.
|
||||
setMaxBoundsSandboxedToMatchAppBounds(mApplicationContext.getResources(),
|
||||
sAppBoundsPortrait);
|
||||
final Display display = new Display(mDisplayManagerGlobal, DEFAULT_DISPLAY, mDisplayInfo,
|
||||
mApplicationContext.getResources());
|
||||
// THEN real size matches app bounds.
|
||||
verifyRealSizeMatchesApp(display, sAppBoundsPortrait);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testGetRealSize_resourcesLandscapeSandboxed_matchesSandboxBounds() {
|
||||
// GIVEN display is rotated.
|
||||
setDisplayInfoLandscape(mDisplayInfo);
|
||||
// GIVEN app is letterboxed.
|
||||
setMaxBoundsSandboxedToMatchAppBounds(mApplicationContext.getResources(),
|
||||
sAppBoundsLandscape);
|
||||
final Display display = new Display(mDisplayManagerGlobal, DEFAULT_DISPLAY, mDisplayInfo,
|
||||
mApplicationContext.getResources());
|
||||
// THEN real size matches app bounds.
|
||||
verifyRealSizeMatchesApp(display, sAppBoundsLandscape);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testGetRealMetrics_defaultResourcesPortrait_matchesLogicalSize() {
|
||||
// GIVEN display is not rotated.
|
||||
setDisplayInfoPortrait(mDisplayInfo);
|
||||
final Display display = new Display(mDisplayManagerGlobal, DEFAULT_DISPLAY, mDisplayInfo,
|
||||
mApplicationContext.getResources());
|
||||
// THEN real metrics matches display orientation.
|
||||
verifyRealMetricsIsPortrait(display);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testGetRealMetrics_defaultResourcesLandscape_matchesRotatedLogicalSize() {
|
||||
// GIVEN display is rotated.
|
||||
setDisplayInfoLandscape(mDisplayInfo);
|
||||
final Display display = new Display(mDisplayManagerGlobal, DEFAULT_DISPLAY, mDisplayInfo,
|
||||
mApplicationContext.getResources());
|
||||
// THEN real metrics matches display orientation.
|
||||
verifyRealMetricsIsLandscape(display);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testGetRealMetrics_defaultDisplayAdjustmentsPortrait_matchesLogicalSize() {
|
||||
// GIVEN display is not rotated.
|
||||
setDisplayInfoPortrait(mDisplayInfo);
|
||||
final Display display = new Display(mDisplayManagerGlobal, DEFAULT_DISPLAY, mDisplayInfo,
|
||||
DisplayAdjustments.DEFAULT_DISPLAY_ADJUSTMENTS);
|
||||
// THEN real metrics matches display orientation.
|
||||
verifyRealMetricsIsPortrait(display);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testGetRealMetrics_defaultDisplayAdjustmentsLandscape_matchesLogicalSize() {
|
||||
// GIVEN display is rotated.
|
||||
setDisplayInfoLandscape(mDisplayInfo);
|
||||
final Display display = new Display(mDisplayManagerGlobal, DEFAULT_DISPLAY, mDisplayInfo,
|
||||
DisplayAdjustments.DEFAULT_DISPLAY_ADJUSTMENTS);
|
||||
// THEN real metrics matches display orientation.
|
||||
verifyRealMetricsIsLandscape(display);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testGetRealMetrics_resourcesPortraitWithFixedRotation_notRotatedLogicalSize() {
|
||||
// GIVEN display is rotated.
|
||||
setDisplayInfoLandscape(mDisplayInfo);
|
||||
// GIVEN fixed rotation adjustments are rotated.
|
||||
setFixedRotationAdjustments(mApplicationContext.getResources(), ROTATION_0);
|
||||
// GIVEN display is constructed with default resources.
|
||||
final Display display = new Display(mDisplayManagerGlobal, DEFAULT_DISPLAY, mDisplayInfo,
|
||||
mApplicationContext.getResources());
|
||||
// THEN real metrics matches display orientation.
|
||||
verifyRealMetricsIsLandscape(display);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testGetRealMetrics_resourcesWithLandscapeFixedRotation_notRotatedLogicalSize() {
|
||||
// GIVEN display is not rotated.
|
||||
setDisplayInfoPortrait(mDisplayInfo);
|
||||
// GIVEN fixed rotation adjustments are rotated.
|
||||
setFixedRotationAdjustments(mApplicationContext.getResources(), ROTATION_90);
|
||||
// GIVEN display is constructed with default resources.
|
||||
final Display display = new Display(mDisplayManagerGlobal, DEFAULT_DISPLAY, mDisplayInfo,
|
||||
mApplicationContext.getResources());
|
||||
// THEN real metrics matches display orientation.
|
||||
verifyRealMetricsIsPortrait(display);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testGetRealMetrics_resourcesWithPortraitOverrideRotation_rotatedLogicalSize() {
|
||||
// GIVEN display is rotated.
|
||||
setDisplayInfoLandscape(mDisplayInfo);
|
||||
// GIVEN fixed rotation adjustments are rotated with an override.
|
||||
setOverrideFixedRotationAdjustments(mApplicationContext.getResources(), ROTATION_0);
|
||||
// GIVEN display is constructed with default resources.
|
||||
final Display display = new Display(mDisplayManagerGlobal, DEFAULT_DISPLAY, mDisplayInfo,
|
||||
mApplicationContext.getResources());
|
||||
// THEN real metrics matches app orientation.
|
||||
verifyRealMetricsIsPortrait(display);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testGetRealMetrics_resourcesWithLandscapeOverrideRotation_rotatedLogicalSize() {
|
||||
// GIVEN display is not rotated.
|
||||
setDisplayInfoPortrait(mDisplayInfo);
|
||||
// GIVEN fixed rotation adjustments are rotated.
|
||||
setOverrideFixedRotationAdjustments(mApplicationContext.getResources(), ROTATION_90);
|
||||
// GIVEN display is constructed with default resources.
|
||||
final Display display = new Display(mDisplayManagerGlobal, DEFAULT_DISPLAY, mDisplayInfo,
|
||||
mApplicationContext.getResources());
|
||||
// THEN real metrics matches app orientation.
|
||||
verifyRealMetricsIsLandscape(display);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testGetRealMetrics_resourcesPortraitSandboxed_matchesSandboxBounds() {
|
||||
// GIVEN display is not rotated.
|
||||
setDisplayInfoPortrait(mDisplayInfo);
|
||||
// GIVEN app is letterboxed.
|
||||
setMaxBoundsSandboxedToMatchAppBounds(mApplicationContext.getResources(),
|
||||
sAppBoundsPortrait);
|
||||
final Display display = new Display(mDisplayManagerGlobal, DEFAULT_DISPLAY, mDisplayInfo,
|
||||
mApplicationContext.getResources());
|
||||
// THEN real metrics matches app bounds.
|
||||
verifyRealMetricsMatchesApp(display, sAppBoundsPortrait);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testGetRealMetrics_resourcesLandscapeSandboxed_matchesSandboxBounds() {
|
||||
// GIVEN display is rotated.
|
||||
setDisplayInfoLandscape(mDisplayInfo);
|
||||
// GIVEN app is letterboxed.
|
||||
setMaxBoundsSandboxedToMatchAppBounds(mApplicationContext.getResources(),
|
||||
sAppBoundsLandscape);
|
||||
final Display display = new Display(mDisplayManagerGlobal, DEFAULT_DISPLAY, mDisplayInfo,
|
||||
mApplicationContext.getResources());
|
||||
// THEN real metrics matches app bounds.
|
||||
verifyRealMetricsMatchesApp(display, sAppBoundsLandscape);
|
||||
}
|
||||
|
||||
// Given rotated display dimensions, calculate the letterboxed app bounds.
|
||||
private static Rect buildAppBounds(int displayWidth, int displayHeight) {
|
||||
final int midWidth = displayWidth / 2;
|
||||
final int left = midWidth - (APP_WIDTH / 2);
|
||||
final int right = midWidth + (APP_WIDTH / 2);
|
||||
final int midHeight = displayHeight / 2;
|
||||
// Coordinate system starts at top left.
|
||||
final int top = midHeight - (APP_HEIGHT / 2);
|
||||
final int bottom = midHeight + (APP_HEIGHT / 2);
|
||||
return new Rect(left, top, right, bottom);
|
||||
}
|
||||
|
||||
private static void setDisplayInfoLandscape(DisplayInfo displayInfo) {
|
||||
displayInfo.rotation = ROTATION_90;
|
||||
// Flip width & height assignment since the device is rotated.
|
||||
displayInfo.logicalWidth = LOGICAL_HEIGHT;
|
||||
displayInfo.logicalHeight = LOGICAL_WIDTH;
|
||||
}
|
||||
|
||||
private static void setDisplayInfoPortrait(DisplayInfo displayInfo) {
|
||||
displayInfo.rotation = ROTATION_0;
|
||||
displayInfo.logicalWidth = LOGICAL_WIDTH;
|
||||
displayInfo.logicalHeight = LOGICAL_HEIGHT;
|
||||
}
|
||||
|
||||
/**
|
||||
* Set max bounds to be sandboxed to the app bounds, indicating the app is in
|
||||
* size compat mode or letterbox.
|
||||
*/
|
||||
private static void setMaxBoundsSandboxedToMatchAppBounds(Resources resources, Rect appBounds) {
|
||||
resources.getConfiguration().windowConfiguration.setMaxBounds(appBounds);
|
||||
}
|
||||
|
||||
/**
|
||||
* Do not compare entire display info, since it is updated to match display the test is run on.
|
||||
*/
|
||||
private static void verifyDisplayInfo(DisplayInfo actual, DisplayInfo expected) {
|
||||
assertThat(actual.displayId).isEqualTo(expected.displayId);
|
||||
assertThat(actual.rotation).isEqualTo(expected.rotation);
|
||||
assertThat(actual.logicalWidth).isEqualTo(LOGICAL_WIDTH);
|
||||
assertThat(actual.logicalHeight).isEqualTo(LOGICAL_HEIGHT);
|
||||
}
|
||||
|
||||
private static void verifyRealSizeIsLandscape(Display display) {
|
||||
Point size = new Point();
|
||||
display.getRealSize(size);
|
||||
// Flip the width and height check since the device is rotated.
|
||||
assertThat(size).isEqualTo(new Point(LOGICAL_HEIGHT, LOGICAL_WIDTH));
|
||||
}
|
||||
|
||||
private static void verifyRealMetricsIsLandscape(Display display) {
|
||||
DisplayMetrics metrics = new DisplayMetrics();
|
||||
display.getRealMetrics(metrics);
|
||||
// Flip the width and height check since the device is rotated.
|
||||
assertThat(metrics.widthPixels).isEqualTo(LOGICAL_HEIGHT);
|
||||
assertThat(metrics.heightPixels).isEqualTo(LOGICAL_WIDTH);
|
||||
}
|
||||
|
||||
private static void verifyRealSizeIsPortrait(Display display) {
|
||||
Point size = new Point();
|
||||
display.getRealSize(size);
|
||||
assertThat(size).isEqualTo(new Point(LOGICAL_WIDTH, LOGICAL_HEIGHT));
|
||||
}
|
||||
|
||||
private static void verifyRealMetricsIsPortrait(Display display) {
|
||||
DisplayMetrics metrics = new DisplayMetrics();
|
||||
display.getRealMetrics(metrics);
|
||||
assertThat(metrics.widthPixels).isEqualTo(LOGICAL_WIDTH);
|
||||
assertThat(metrics.heightPixels).isEqualTo(LOGICAL_HEIGHT);
|
||||
}
|
||||
|
||||
private static void verifyRealSizeMatchesApp(Display display, Rect appBounds) {
|
||||
Point size = new Point();
|
||||
display.getRealSize(size);
|
||||
assertThat(size).isEqualTo(new Point(appBounds.width(), appBounds.height()));
|
||||
}
|
||||
|
||||
private static void verifyRealMetricsMatchesApp(Display display, Rect appBounds) {
|
||||
DisplayMetrics metrics = new DisplayMetrics();
|
||||
display.getRealMetrics(metrics);
|
||||
assertThat(metrics.widthPixels).isEqualTo(appBounds.width());
|
||||
assertThat(metrics.heightPixels).isEqualTo(appBounds.height());
|
||||
}
|
||||
|
||||
private static FixedRotationAdjustments setOverrideFixedRotationAdjustments(
|
||||
Resources resources, @Surface.Rotation int rotation) {
|
||||
FixedRotationAdjustments fixedRotationAdjustments =
|
||||
setFixedRotationAdjustments(resources, rotation);
|
||||
resources.overrideDisplayAdjustments(
|
||||
buildOverrideRotationAdjustments(fixedRotationAdjustments));
|
||||
return fixedRotationAdjustments;
|
||||
}
|
||||
|
||||
private static FixedRotationAdjustments setFixedRotationAdjustments(Resources resources,
|
||||
@Surface.Rotation int rotation) {
|
||||
final FixedRotationAdjustments fixedRotationAdjustments =
|
||||
new FixedRotationAdjustments(rotation, APP_WIDTH, APP_HEIGHT,
|
||||
DisplayCutout.NO_CUTOUT);
|
||||
resources.getDisplayAdjustments().setFixedRotationAdjustments(fixedRotationAdjustments);
|
||||
return fixedRotationAdjustments;
|
||||
}
|
||||
|
||||
private static Consumer<DisplayAdjustments> buildOverrideRotationAdjustments(
|
||||
FixedRotationAdjustments fixedRotationAdjustments) {
|
||||
return consumedDisplayAdjustments
|
||||
-> consumedDisplayAdjustments.setFixedRotationAdjustments(fixedRotationAdjustments);
|
||||
}
|
||||
}
|
||||
@@ -1219,6 +1219,12 @@
|
||||
"group": "WM_DEBUG_ORIENTATION",
|
||||
"at": "com\/android\/server\/wm\/DragState.java"
|
||||
},
|
||||
"-681380736": {
|
||||
"message": "Sandbox max bounds for uid %s to bounds %s due to letterboxing from mismatch with parent bounds? %s size compat mode %s",
|
||||
"level": "DEBUG",
|
||||
"group": "WM_DEBUG_CONFIGURATION",
|
||||
"at": "com\/android\/server\/wm\/ActivityRecord.java"
|
||||
},
|
||||
"-677449371": {
|
||||
"message": "moveTaskToRootTask: moving task=%d to rootTaskId=%d toTop=%b",
|
||||
"level": "DEBUG",
|
||||
|
||||
@@ -16,6 +16,7 @@
|
||||
|
||||
package com.android.server.wm;
|
||||
|
||||
import static android.Manifest.permission.INTERNAL_SYSTEM_WINDOW;
|
||||
import static android.app.ActivityManager.LOCK_TASK_MODE_NONE;
|
||||
import static android.app.ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND;
|
||||
import static android.app.ActivityOptions.ANIM_CLIP_REVEAL;
|
||||
@@ -86,6 +87,7 @@ import static android.content.pm.ActivityInfo.SCREEN_ORIENTATION_BEHIND;
|
||||
import static android.content.pm.ActivityInfo.SCREEN_ORIENTATION_UNSET;
|
||||
import static android.content.pm.ActivityInfo.isFixedOrientationLandscape;
|
||||
import static android.content.pm.ActivityInfo.isFixedOrientationPortrait;
|
||||
import static android.content.pm.PackageManager.PERMISSION_GRANTED;
|
||||
import static android.content.res.Configuration.EMPTY;
|
||||
import static android.content.res.Configuration.ORIENTATION_LANDSCAPE;
|
||||
import static android.content.res.Configuration.ORIENTATION_PORTRAIT;
|
||||
@@ -205,6 +207,7 @@ import static com.android.server.wm.WindowContainer.AnimationFlags.PARENTS;
|
||||
import static com.android.server.wm.WindowContainer.AnimationFlags.TRANSITION;
|
||||
import static com.android.server.wm.WindowContainerChildProto.ACTIVITY;
|
||||
import static com.android.server.wm.WindowManagerDebugConfig.DEBUG_ANIM;
|
||||
import static com.android.server.wm.WindowManagerDebugConfig.DEBUG_CONFIGURATION;
|
||||
import static com.android.server.wm.WindowManagerDebugConfig.DEBUG_LAYOUT_REPEATS;
|
||||
import static com.android.server.wm.WindowManagerDebugConfig.DEBUG_STARTING_WINDOW_VERBOSE;
|
||||
import static com.android.server.wm.WindowManagerDebugConfig.TAG_WM;
|
||||
@@ -278,6 +281,7 @@ import android.os.SystemClock;
|
||||
import android.os.Trace;
|
||||
import android.os.UserHandle;
|
||||
import android.os.storage.StorageManager;
|
||||
import android.permission.PermissionManager;
|
||||
import android.service.dreams.DreamActivity;
|
||||
import android.service.dreams.DreamManagerInternal;
|
||||
import android.service.voice.IVoiceInteractionSession;
|
||||
@@ -6955,6 +6959,20 @@ final class ActivityRecord extends WindowToken implements WindowManagerService.A
|
||||
// layout traversals.
|
||||
mConfigurationSeq = Math.max(++mConfigurationSeq, 1);
|
||||
getResolvedOverrideConfiguration().seq = mConfigurationSeq;
|
||||
|
||||
// Sandbox max bounds by setting it to the app bounds, if activity is letterboxed or in
|
||||
// size compat mode.
|
||||
if (providesMaxBounds()) {
|
||||
if (DEBUG_CONFIGURATION) {
|
||||
ProtoLog.d(WM_DEBUG_CONFIGURATION, "Sandbox max bounds for uid %s to bounds %s "
|
||||
+ "due to letterboxing from mismatch with parent bounds? %s size compat "
|
||||
+ "mode %s", getUid(),
|
||||
resolvedConfig.windowConfiguration.getBounds(), !matchParentBounds(),
|
||||
inSizeCompatMode());
|
||||
}
|
||||
resolvedConfig.windowConfiguration
|
||||
.setMaxBounds(resolvedConfig.windowConfiguration.getBounds());
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -7296,6 +7314,20 @@ final class ActivityRecord extends WindowToken implements WindowManagerService.A
|
||||
return super.getBounds();
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean providesMaxBounds() {
|
||||
// System and SystemUI should always be able to access the physical display bounds,
|
||||
// so do not provide it with the overridden maximum bounds.
|
||||
// TODO(b/179179513) check WindowState#mOwnerCanAddInternalSystemWindow instead
|
||||
if (getUid() == SYSTEM_UID || PermissionManager.checkPermission(INTERNAL_SYSTEM_WINDOW,
|
||||
getPid(), info.applicationInfo.uid) == PERMISSION_GRANTED) {
|
||||
return false;
|
||||
}
|
||||
// Max bounds should be sandboxed where an activity is letterboxed (activity bounds will be
|
||||
// smaller than task bounds) or put in size compat mode.
|
||||
return !matchParentBounds() || inSizeCompatMode();
|
||||
}
|
||||
|
||||
@VisibleForTesting
|
||||
@Override
|
||||
Rect getAnimationBounds(int appRootTaskClipMode) {
|
||||
|
||||
@@ -367,8 +367,7 @@ public abstract class ConfigurationContainer<E extends ConfigurationContainer> {
|
||||
* Returns {@code true} if this {@link ConfigurationContainer} provides the maximum bounds to
|
||||
* its child {@link ConfigurationContainer}s. Returns {@code false}, otherwise.
|
||||
* <p>
|
||||
* The maximum bounds is how large a window can be expanded. Currently only
|
||||
* {@link DisplayContent} and {@link DisplayArea} effect this property.
|
||||
* The maximum bounds is how large a window can be expanded.
|
||||
* </p>
|
||||
*/
|
||||
protected boolean providesMaxBounds() {
|
||||
|
||||
@@ -40,6 +40,8 @@ import static com.android.server.wm.DisplayContent.IME_TARGET_LAYERING;
|
||||
import static com.android.server.wm.Task.ActivityState.STOPPED;
|
||||
import static com.android.server.wm.WindowContainer.POSITION_TOP;
|
||||
|
||||
import static com.google.common.truth.Truth.assertThat;
|
||||
|
||||
import static org.junit.Assert.assertEquals;
|
||||
import static org.junit.Assert.assertFalse;
|
||||
import static org.junit.Assert.assertNotEquals;
|
||||
@@ -117,18 +119,19 @@ public class SizeCompatTests extends WindowTestsBase {
|
||||
@Test
|
||||
public void testKeepBoundsWhenChangingFromFreeformToFullscreen() {
|
||||
removeGlobalMinSizeRestriction();
|
||||
// create freeform display and a freeform app
|
||||
// Create landscape freeform display and a freeform app.
|
||||
DisplayContent display = new TestDisplayContent.Builder(mAtm, 2000, 1000)
|
||||
.setCanRotate(false)
|
||||
.setWindowingMode(WindowConfiguration.WINDOWING_MODE_FREEFORM).build();
|
||||
setUpApp(display);
|
||||
|
||||
// Put app window into freeform and then make it a compat app.
|
||||
// Put app window into portrait freeform and then make it a compat app.
|
||||
final Rect bounds = new Rect(100, 100, 400, 600);
|
||||
mTask.setBounds(bounds);
|
||||
|
||||
prepareUnresizable(mActivity, -1.f /* maxAspect */, SCREEN_ORIENTATION_PORTRAIT);
|
||||
assertEquals(bounds, mActivity.getBounds());
|
||||
// Activity is not yet in size compat mode; it is filling the freeform window.
|
||||
assertMaxBoundsInheritDisplayAreaBounds();
|
||||
|
||||
// The activity should be able to accept negative x position [-150, 100 - 150, 600].
|
||||
final int dx = bounds.left + bounds.width() / 2;
|
||||
@@ -137,7 +140,7 @@ public class SizeCompatTests extends WindowTestsBase {
|
||||
|
||||
final int density = mActivity.getConfiguration().densityDpi;
|
||||
|
||||
// change display configuration to fullscreen
|
||||
// Change display configuration to fullscreen.
|
||||
Configuration c = new Configuration(display.getRequestedOverrideConfiguration());
|
||||
c.windowConfiguration.setWindowingMode(WindowConfiguration.WINDOWING_MODE_FULLSCREEN);
|
||||
display.onRequestedOverrideConfigurationChanged(c);
|
||||
@@ -147,6 +150,8 @@ public class SizeCompatTests extends WindowTestsBase {
|
||||
assertEquals(bounds.width(), mActivity.getBounds().width());
|
||||
assertEquals(bounds.height(), mActivity.getBounds().height());
|
||||
assertEquals(density, mActivity.getConfiguration().densityDpi);
|
||||
// Size compat mode is sandboxed at the activity level.
|
||||
assertActivityMaxBoundsSandboxed();
|
||||
}
|
||||
|
||||
@Test
|
||||
@@ -172,6 +177,12 @@ public class SizeCompatTests extends WindowTestsBase {
|
||||
assertEquals(appBounds.height(), appBounds.width() * aspectRatio, 0.5f /* delta */);
|
||||
// The decor height should be a part of the effective bounds.
|
||||
assertEquals(mActivity.getBounds().height(), appBounds.height() + notchHeight);
|
||||
// Activity max bounds should be sandboxed; activity is letterboxed due to aspect ratio.
|
||||
assertActivityMaxBoundsSandboxed();
|
||||
// Activity max bounds ignore notch, since an app can be shown past the notch (although app
|
||||
// is currently limited by the notch).
|
||||
assertThat(mActivity.getWindowConfiguration().getMaxBounds().height())
|
||||
.isEqualTo(displayBounds.height());
|
||||
|
||||
mActivity.setRequestedOrientation(SCREEN_ORIENTATION_LANDSCAPE);
|
||||
assertFitted();
|
||||
@@ -181,9 +192,17 @@ public class SizeCompatTests extends WindowTestsBase {
|
||||
assertEquals(appBounds.width(), appBounds.height() * aspectRatio, 0.5f /* delta */);
|
||||
// The notch is no longer on top.
|
||||
assertEquals(appBounds, mActivity.getBounds());
|
||||
// Activity max bounds are sandboxed.
|
||||
assertActivityMaxBoundsSandboxed();
|
||||
|
||||
mActivity.setRequestedOrientation(SCREEN_ORIENTATION_PORTRAIT);
|
||||
assertFitted();
|
||||
// Activity max bounds should be sandboxed; activity is letterboxed due to aspect ratio.
|
||||
assertActivityMaxBoundsSandboxed();
|
||||
// Activity max bounds ignore notch, since an app can be shown past the notch (although app
|
||||
// is currently limited by the notch).
|
||||
assertThat(mActivity.getWindowConfiguration().getMaxBounds().height())
|
||||
.isEqualTo(displayBounds.height());
|
||||
}
|
||||
|
||||
@Test
|
||||
@@ -206,6 +225,9 @@ public class SizeCompatTests extends WindowTestsBase {
|
||||
assertEquals(originalBounds.width(), mActivity.getBounds().width());
|
||||
assertEquals(originalBounds.height(), mActivity.getBounds().height());
|
||||
assertEquals(originalDpi, mActivity.getConfiguration().densityDpi);
|
||||
// Activity is sandboxed; it is in size compat mode since it is not resizable and has a
|
||||
// max aspect ratio.
|
||||
assertActivityMaxBoundsSandboxed();
|
||||
assertScaled();
|
||||
}
|
||||
|
||||
@@ -213,11 +235,13 @@ public class SizeCompatTests extends WindowTestsBase {
|
||||
public void testFixedScreenBoundsWhenDisplaySizeChanged() {
|
||||
setUpDisplaySizeWithApp(1000, 2500);
|
||||
prepareUnresizable(mActivity, -1f /* maxAspect */, SCREEN_ORIENTATION_PORTRAIT);
|
||||
final DisplayContent display = mActivity.mDisplayContent;
|
||||
assertFitted();
|
||||
// Activity inherits bounds from TaskDisplayArea, since not sandboxed.
|
||||
assertMaxBoundsInheritDisplayAreaBounds();
|
||||
|
||||
final Rect origBounds = new Rect(mActivity.getBounds());
|
||||
final Rect currentBounds = mActivity.getWindowConfiguration().getBounds();
|
||||
final DisplayContent display = mActivity.mDisplayContent;
|
||||
|
||||
// Change the size of current display.
|
||||
resizeDisplay(display, 1000, 2000);
|
||||
@@ -234,6 +258,8 @@ public class SizeCompatTests extends WindowTestsBase {
|
||||
// The position of configuration bounds should be the same as compat bounds.
|
||||
assertEquals(mActivity.getBounds().left, currentBounds.left);
|
||||
assertEquals(mActivity.getBounds().top, currentBounds.top);
|
||||
// Activity is sandboxed to the offset size compat bounds.
|
||||
assertActivityMaxBoundsSandboxed();
|
||||
|
||||
// Change display size to a different orientation
|
||||
resizeDisplay(display, 2000, 1000);
|
||||
@@ -242,6 +268,8 @@ public class SizeCompatTests extends WindowTestsBase {
|
||||
assertEquals(origBounds.height(), currentBounds.height());
|
||||
assertEquals(ORIENTATION_LANDSCAPE, display.getConfiguration().orientation);
|
||||
assertEquals(Configuration.ORIENTATION_PORTRAIT, mActivity.getConfiguration().orientation);
|
||||
// Activity is sandboxed to the offset size compat bounds.
|
||||
assertActivityMaxBoundsSandboxed();
|
||||
|
||||
// The previous resize operation doesn't consider the rotation change after size changed.
|
||||
// These setups apply the requested orientation to rotation as real case that the top fixed
|
||||
@@ -261,6 +289,8 @@ public class SizeCompatTests extends WindowTestsBase {
|
||||
assertEquals(origBounds.height(), currentBounds.height());
|
||||
assertEquals(offsetX, currentBounds.left);
|
||||
assertScaled();
|
||||
// Activity is sandboxed due to size compat mode.
|
||||
assertActivityMaxBoundsSandboxed();
|
||||
}
|
||||
|
||||
@Test
|
||||
@@ -276,6 +306,8 @@ public class SizeCompatTests extends WindowTestsBase {
|
||||
assertEquals(bounds.width(), bounds.height() * maxAspect, 0.0001f /* delta */);
|
||||
// The position should be horizontal centered.
|
||||
assertEquals((displayWidth - bounds.width()) / 2, bounds.left);
|
||||
// Activity max bounds should be sandboxed since it is letterboxed.
|
||||
assertActivityMaxBoundsSandboxed();
|
||||
|
||||
mActivity.mDisplayContent.setImeLayeringTarget(addWindowToActivity(mActivity));
|
||||
// Make sure IME cannot attach to the app, otherwise IME window will also be shifted.
|
||||
@@ -287,6 +319,8 @@ public class SizeCompatTests extends WindowTestsBase {
|
||||
// It should keep non-attachable because the resolved bounds will be computed according to
|
||||
// the aspect ratio that won't match its parent bounds.
|
||||
assertFalse(mActivity.mDisplayContent.isImeAttachedToApp());
|
||||
// Activity max bounds should be sandboxed since it is letterboxed.
|
||||
assertActivityMaxBoundsSandboxed();
|
||||
}
|
||||
|
||||
@Test
|
||||
@@ -312,14 +346,13 @@ public class SizeCompatTests extends WindowTestsBase {
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testMoveToDifferentOrientDisplay() {
|
||||
public void testMoveToDifferentOrientationDisplay() {
|
||||
setUpDisplaySizeWithApp(1000, 2500);
|
||||
prepareUnresizable(mActivity, -1.f /* maxAspect */, SCREEN_ORIENTATION_PORTRAIT);
|
||||
assertFitted();
|
||||
|
||||
final Rect configBounds = mActivity.getWindowConfiguration().getBounds();
|
||||
final int origWidth = configBounds.width();
|
||||
final int origHeight = configBounds.height();
|
||||
final Rect currentBounds = mActivity.getWindowConfiguration().getBounds();
|
||||
final Rect originalBounds = new Rect(mActivity.getWindowConfiguration().getBounds());
|
||||
|
||||
final int notchHeight = 100;
|
||||
final DisplayContent newDisplay = new TestDisplayContent.Builder(mAtm, 2000, 1000)
|
||||
@@ -328,37 +361,45 @@ public class SizeCompatTests extends WindowTestsBase {
|
||||
// Move the non-resizable activity to the new display.
|
||||
mTask.reparent(newDisplay.getDefaultTaskDisplayArea(), true /* onTop */);
|
||||
// The configuration bounds [820, 0 - 1820, 2500] should keep the same.
|
||||
assertEquals(origWidth, configBounds.width());
|
||||
assertEquals(origHeight, configBounds.height());
|
||||
assertEquals(originalBounds.width(), currentBounds.width());
|
||||
assertEquals(originalBounds.height(), currentBounds.height());
|
||||
assertScaled();
|
||||
// Activity max bounds are sandboxed due to size compat mode on the new display.
|
||||
assertActivityMaxBoundsSandboxed();
|
||||
|
||||
final Rect newDisplayBounds = newDisplay.getWindowConfiguration().getBounds();
|
||||
// The scaled bounds should exclude notch area (1000 - 100 == 360 * 2500 / 1000 = 900).
|
||||
assertEquals(newDisplayBounds.height() - notchHeight,
|
||||
(int) ((float) mActivity.getBounds().width() * origHeight / origWidth));
|
||||
(int) ((float) mActivity.getBounds().width() * originalBounds.height()
|
||||
/ originalBounds.width()));
|
||||
|
||||
// Recompute the natural configuration in the new display.
|
||||
mActivity.clearSizeCompatMode();
|
||||
mActivity.ensureActivityConfiguration(0 /* globalChanges */, false /* preserveWindow */);
|
||||
// Because the display cannot rotate, the portrait activity will fit the short side of
|
||||
// display with keeping portrait bounds [200, 0 - 700, 1000] in center.
|
||||
assertEquals(newDisplayBounds.height(), configBounds.height());
|
||||
assertEquals(configBounds.height() * newDisplayBounds.height() / newDisplayBounds.width(),
|
||||
configBounds.width());
|
||||
assertEquals(newDisplayBounds.height(), currentBounds.height());
|
||||
assertEquals(currentBounds.height() * newDisplayBounds.height() / newDisplayBounds.width(),
|
||||
currentBounds.width());
|
||||
assertFitted();
|
||||
// The appBounds should be [200, 100 - 700, 1000].
|
||||
final Rect appBounds = mActivity.getWindowConfiguration().getAppBounds();
|
||||
assertEquals(configBounds.width(), appBounds.width());
|
||||
assertEquals(configBounds.height() - notchHeight, appBounds.height());
|
||||
assertEquals(currentBounds.width(), appBounds.width());
|
||||
assertEquals(currentBounds.height() - notchHeight, appBounds.height());
|
||||
// Activity max bounds are sandboxed due to letterboxing from orientation mismatch with
|
||||
// display.
|
||||
assertActivityMaxBoundsSandboxed();
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testFixedOrientRotateCutoutDisplay() {
|
||||
public void testFixedOrientationRotateCutoutDisplay() {
|
||||
// Create a display with a notch/cutout
|
||||
final int notchHeight = 60;
|
||||
setUpApp(new TestDisplayContent.Builder(mAtm, 1000, 2500)
|
||||
final int width = 1000;
|
||||
setUpApp(new TestDisplayContent.Builder(mAtm, width, 2500)
|
||||
.setNotch(notchHeight).build());
|
||||
// Bounds=[0, 0 - 1000, 1460], AppBounds=[0, 60 - 1000, 1460].
|
||||
// Bounds=[0, 0 - 1000, 1400], AppBounds=[0, 60 - 1000, 1460].
|
||||
final float maxAspect = 1.4f;
|
||||
prepareUnresizable(mActivity, 1.4f /* maxAspect */, SCREEN_ORIENTATION_PORTRAIT);
|
||||
|
||||
final Rect currentBounds = mActivity.getWindowConfiguration().getBounds();
|
||||
@@ -366,6 +407,11 @@ public class SizeCompatTests extends WindowTestsBase {
|
||||
final Rect origBounds = new Rect(currentBounds);
|
||||
final Rect origAppBounds = new Rect(appBounds);
|
||||
|
||||
// Activity is sandboxed, and bounds include the area consumed by the notch.
|
||||
assertActivityMaxBoundsSandboxed();
|
||||
assertThat(mActivity.getConfiguration().windowConfiguration.getMaxBounds().height())
|
||||
.isEqualTo(Math.round(width * maxAspect) + notchHeight);
|
||||
|
||||
// Although the activity is fixed orientation, force rotate the display.
|
||||
rotateDisplay(mActivity.mDisplayContent, ROTATION_270);
|
||||
assertEquals(ROTATION_270, mTask.getWindowConfiguration().getRotation());
|
||||
@@ -381,10 +427,13 @@ public class SizeCompatTests extends WindowTestsBase {
|
||||
// The position in configuration should be global coordinates.
|
||||
assertEquals(mActivity.getBounds().left, currentBounds.left);
|
||||
assertEquals(mActivity.getBounds().top, currentBounds.top);
|
||||
|
||||
// Activity max bounds are sandboxed due to size compat mode.
|
||||
assertActivityMaxBoundsSandboxed();
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testFixedAspOrientChangeOrient() {
|
||||
public void testFixedAspectRatioOrientationChangeOrientation() {
|
||||
setUpDisplaySizeWithApp(1000, 2500);
|
||||
|
||||
final float maxAspect = 1.4f;
|
||||
@@ -396,6 +445,8 @@ public class SizeCompatTests extends WindowTestsBase {
|
||||
final Rect originalAppBounds = new Rect(mActivity.getWindowConfiguration().getAppBounds());
|
||||
|
||||
assertEquals((int) (originalBounds.width() * maxAspect), originalBounds.height());
|
||||
// Activity is sandboxed due to fixed aspect ratio.
|
||||
assertActivityMaxBoundsSandboxed();
|
||||
|
||||
// Change the fixed orientation.
|
||||
mActivity.setRequestedOrientation(SCREEN_ORIENTATION_LANDSCAPE);
|
||||
@@ -407,6 +458,8 @@ public class SizeCompatTests extends WindowTestsBase {
|
||||
mActivity.getWindowConfiguration().getAppBounds().height());
|
||||
assertEquals(originalAppBounds.height(),
|
||||
mActivity.getWindowConfiguration().getAppBounds().width());
|
||||
// Activity is sandboxed due to fixed aspect ratio.
|
||||
assertActivityMaxBoundsSandboxed();
|
||||
}
|
||||
|
||||
@Test
|
||||
@@ -455,6 +508,8 @@ public class SizeCompatTests extends WindowTestsBase {
|
||||
// restarted and the override configuration won't be cleared.
|
||||
verify(mActivity, never()).restartProcessIfVisible();
|
||||
assertScaled();
|
||||
// Activity max bounds are sandboxed due to size compat mode, even if is not visible.
|
||||
assertActivityMaxBoundsSandboxed();
|
||||
|
||||
// Change display density
|
||||
display.mBaseDisplayDensity = (int) (0.7f * display.mBaseDisplayDensity);
|
||||
@@ -568,12 +623,16 @@ public class SizeCompatTests extends WindowTestsBase {
|
||||
// in multi-window mode.
|
||||
mTask.setWindowingMode(WindowConfiguration.WINDOWING_MODE_FREEFORM);
|
||||
assertFalse(activity.shouldCreateCompatDisplayInsets());
|
||||
// Activity should not be sandboxed.
|
||||
assertMaxBoundsInheritDisplayAreaBounds();
|
||||
|
||||
// The non-resizable activity should not be size compat because the display support
|
||||
// changing windowing mode from fullscreen to freeform.
|
||||
mTask.mDisplayContent.setDisplayWindowingMode(WindowConfiguration.WINDOWING_MODE_FREEFORM);
|
||||
mTask.setWindowingMode(WindowConfiguration.WINDOWING_MODE_FULLSCREEN);
|
||||
assertFalse(activity.shouldCreateCompatDisplayInsets());
|
||||
// Activity should not be sandboxed.
|
||||
assertMaxBoundsInheritDisplayAreaBounds();
|
||||
}
|
||||
|
||||
@Test
|
||||
@@ -637,6 +696,9 @@ public class SizeCompatTests extends WindowTestsBase {
|
||||
// be transparent.
|
||||
assertFalse(displayPolicy.isFullyTransparentAllowed(w, TYPE_STATUS_BAR));
|
||||
|
||||
// Activity is sandboxed.
|
||||
assertActivityMaxBoundsSandboxed();
|
||||
|
||||
// Make the activity fill the display.
|
||||
prepareUnresizable(mActivity, 10 /* maxAspect */, SCREEN_ORIENTATION_LANDSCAPE);
|
||||
w.mWinAnimator.mDrawState = WindowStateAnimator.HAS_DRAWN;
|
||||
@@ -646,6 +708,7 @@ public class SizeCompatTests extends WindowTestsBase {
|
||||
// The letterbox should only cover the notch area, so status bar can be transparent.
|
||||
assertEquals(new Rect(notchHeight, 0, 0, 0), mActivity.getLetterboxInsets());
|
||||
assertTrue(displayPolicy.isFullyTransparentAllowed(w, TYPE_STATUS_BAR));
|
||||
assertActivityMaxBoundsSandboxed();
|
||||
}
|
||||
|
||||
@Test
|
||||
@@ -668,6 +731,7 @@ public class SizeCompatTests extends WindowTestsBase {
|
||||
// App should launch in fixed orientation letterbox.
|
||||
assertTrue(mActivity.isLetterboxedForFixedOrientationAndAspectRatio());
|
||||
assertFalse(mActivity.inSizeCompatMode());
|
||||
assertActivityMaxBoundsSandboxed();
|
||||
|
||||
// Activity bounds should be 700x1400 with the ratio as the display.
|
||||
assertEquals(displayBounds.height(), activityBounds.height());
|
||||
@@ -789,6 +853,7 @@ public class SizeCompatTests extends WindowTestsBase {
|
||||
assertScaled();
|
||||
assertEquals(activityBounds.width(), newActivityBounds.width());
|
||||
assertEquals(activityBounds.height(), newActivityBounds.height());
|
||||
assertActivityMaxBoundsSandboxed();
|
||||
}
|
||||
|
||||
@Test
|
||||
@@ -800,29 +865,29 @@ public class SizeCompatTests extends WindowTestsBase {
|
||||
// Portrait fixed app without max aspect.
|
||||
prepareUnresizable(mActivity, 0, SCREEN_ORIENTATION_PORTRAIT);
|
||||
|
||||
Rect displayBounds = new Rect(mActivity.mDisplayContent.getBounds());
|
||||
Rect activityBounds = new Rect(mActivity.getBounds());
|
||||
|
||||
// App should launch in fullscreen.
|
||||
assertFalse(mActivity.isLetterboxedForFixedOrientationAndAspectRatio());
|
||||
assertFalse(mActivity.inSizeCompatMode());
|
||||
assertEquals(displayBounds, activityBounds);
|
||||
// Activity inherits max bounds from TaskDisplayArea.
|
||||
assertMaxBoundsInheritDisplayAreaBounds();
|
||||
|
||||
// Rotate display to landscape.
|
||||
rotateDisplay(mActivity.mDisplayContent, ROTATION_90);
|
||||
|
||||
displayBounds = new Rect(mActivity.mDisplayContent.getBounds());
|
||||
activityBounds = new Rect(mActivity.getBounds());
|
||||
assertTrue(displayBounds.width() > displayBounds.height());
|
||||
final Rect rotatedDisplayBounds = new Rect(mActivity.mDisplayContent.getBounds());
|
||||
final Rect rotatedActivityBounds = new Rect(mActivity.getBounds());
|
||||
assertTrue(rotatedDisplayBounds.width() > rotatedDisplayBounds.height());
|
||||
|
||||
// App should be in size compat.
|
||||
assertFalse(mActivity.isLetterboxedForFixedOrientationAndAspectRatio());
|
||||
assertScaled();
|
||||
assertThat(mActivity.inSizeCompatMode()).isTrue();
|
||||
assertActivityMaxBoundsSandboxed();
|
||||
|
||||
// App bounds should be 700x1400 with the ratio as the display.
|
||||
assertEquals(displayBounds.height(), activityBounds.height());
|
||||
assertEquals(displayBounds.height() * displayBounds.height() / displayBounds.width(),
|
||||
activityBounds.width());
|
||||
assertEquals(rotatedDisplayBounds.height(), rotatedActivityBounds.height());
|
||||
assertEquals(rotatedDisplayBounds.height() * rotatedDisplayBounds.height()
|
||||
/ rotatedDisplayBounds.width(), rotatedActivityBounds.width());
|
||||
}
|
||||
|
||||
@Test
|
||||
@@ -859,6 +924,7 @@ public class SizeCompatTests extends WindowTestsBase {
|
||||
// has 700x1400 bounds with the ratio as the display.
|
||||
assertTrue(mActivity.isLetterboxedForFixedOrientationAndAspectRatio());
|
||||
assertFalse(newActivity.inSizeCompatMode());
|
||||
assertActivityMaxBoundsSandboxed();
|
||||
assertEquals(taskBounds, displayBounds);
|
||||
assertEquals(displayBounds.height(), newActivityBounds.height());
|
||||
assertEquals(displayBounds.height() * displayBounds.height() / displayBounds.width(),
|
||||
@@ -899,6 +965,11 @@ public class SizeCompatTests extends WindowTestsBase {
|
||||
// Task bounds should fill parent bounds.
|
||||
assertEquals(displayBounds, taskBounds);
|
||||
|
||||
// Prior and new activity max bounds are sandboxed due to letterbox.
|
||||
assertThat(newActivity.getConfiguration().windowConfiguration.getMaxBounds())
|
||||
.isEqualTo(newActivityBounds);
|
||||
assertActivityMaxBoundsSandboxed();
|
||||
|
||||
// Activity bounds should be (1400 / 1.3 = 1076)x1400 with the app requested ratio.
|
||||
assertTrue(mActivity.isLetterboxedForFixedOrientationAndAspectRatio());
|
||||
assertFalse(newActivity.inSizeCompatMode());
|
||||
@@ -927,6 +998,9 @@ public class SizeCompatTests extends WindowTestsBase {
|
||||
// App should be in size compat.
|
||||
assertFalse(mActivity.isLetterboxedForFixedOrientationAndAspectRatio());
|
||||
assertScaled();
|
||||
assertThat(mActivity.inSizeCompatMode()).isTrue();
|
||||
// Activity max bounds are sandboxed due to size compat mode.
|
||||
assertActivityMaxBoundsSandboxed();
|
||||
|
||||
final Rect activityBounds = new Rect(mActivity.getBounds());
|
||||
mTask.resumeTopActivityUncheckedLocked(null /* prev */, null /* options */);
|
||||
@@ -936,6 +1010,8 @@ public class SizeCompatTests extends WindowTestsBase {
|
||||
assertFalse(mActivity.isLetterboxedForFixedOrientationAndAspectRatio());
|
||||
assertScaled();
|
||||
assertEquals(activityBounds, mActivity.getBounds());
|
||||
// Activity max bounds are sandboxed due to size compat.
|
||||
assertActivityMaxBoundsSandboxed();
|
||||
}
|
||||
|
||||
@Test
|
||||
@@ -951,6 +1027,7 @@ public class SizeCompatTests extends WindowTestsBase {
|
||||
// In fixed orientation letterbox
|
||||
assertTrue(mActivity.isLetterboxedForFixedOrientationAndAspectRatio());
|
||||
assertFalse(mActivity.inSizeCompatMode());
|
||||
assertActivityMaxBoundsSandboxed();
|
||||
|
||||
// Rotate display to portrait.
|
||||
rotateDisplay(display, ROTATION_90);
|
||||
@@ -958,13 +1035,15 @@ public class SizeCompatTests extends WindowTestsBase {
|
||||
// App should be in size compat.
|
||||
assertFalse(mActivity.isLetterboxedForFixedOrientationAndAspectRatio());
|
||||
assertScaled();
|
||||
assertActivityMaxBoundsSandboxed();
|
||||
|
||||
// Rotate display to landscape.
|
||||
rotateDisplay(display, ROTATION_180);
|
||||
|
||||
// In Task letterbox
|
||||
// In activity letterbox
|
||||
assertTrue(mActivity.isLetterboxedForFixedOrientationAndAspectRatio());
|
||||
assertFalse(mActivity.inSizeCompatMode());
|
||||
assertActivityMaxBoundsSandboxed();
|
||||
}
|
||||
|
||||
@Test
|
||||
@@ -982,20 +1061,23 @@ public class SizeCompatTests extends WindowTestsBase {
|
||||
// In fixed orientation letterbox
|
||||
assertTrue(mActivity.isLetterboxedForFixedOrientationAndAspectRatio());
|
||||
assertFalse(mActivity.inSizeCompatMode());
|
||||
assertActivityMaxBoundsSandboxed();
|
||||
|
||||
// Rotate display to portrait.
|
||||
// Rotate display to landscape.
|
||||
rotateDisplay(display, ROTATION_90);
|
||||
|
||||
// App should be in size compat.
|
||||
assertFalse(mActivity.isLetterboxedForFixedOrientationAndAspectRatio());
|
||||
assertScaled();
|
||||
assertActivityMaxBoundsSandboxed();
|
||||
|
||||
// Rotate display to landscape.
|
||||
// Rotate display to portrait.
|
||||
rotateDisplay(display, ROTATION_180);
|
||||
|
||||
// In fixed orientation letterbox
|
||||
assertTrue(mActivity.isLetterboxedForFixedOrientationAndAspectRatio());
|
||||
assertFalse(mActivity.inSizeCompatMode());
|
||||
assertActivityMaxBoundsSandboxed();
|
||||
}
|
||||
|
||||
@Test
|
||||
@@ -1012,12 +1094,18 @@ public class SizeCompatTests extends WindowTestsBase {
|
||||
assertEquals(ORIENTATION_LANDSCAPE, display.getConfiguration().orientation);
|
||||
assertEquals(2800, displayBounds.width());
|
||||
assertEquals(1400, displayBounds.height());
|
||||
taskDisplayArea.setBounds(0, 0, 2400, 1000);
|
||||
Rect displayAreaBounds = new Rect(0, 0, 2400, 1000);
|
||||
taskDisplayArea.setBounds(displayAreaBounds);
|
||||
|
||||
final Rect activityBounds = new Rect(mActivity.getBounds());
|
||||
assertFalse(mActivity.inSizeCompatMode());
|
||||
assertEquals(2400, activityBounds.width());
|
||||
assertEquals(1000, activityBounds.height());
|
||||
// Task and activity maximum bounds inherit from TaskDisplayArea bounds.
|
||||
assertThat(mActivity.getConfiguration().windowConfiguration.getMaxBounds())
|
||||
.isEqualTo(displayAreaBounds);
|
||||
assertThat(mTask.getConfiguration().windowConfiguration.getMaxBounds())
|
||||
.isEqualTo(displayAreaBounds);
|
||||
}
|
||||
|
||||
@Test
|
||||
@@ -1042,6 +1130,7 @@ public class SizeCompatTests extends WindowTestsBase {
|
||||
assertScaled();
|
||||
assertEquals(originalBounds,
|
||||
mActivity.getConfiguration().windowConfiguration.getBounds());
|
||||
assertActivityMaxBoundsSandboxed();
|
||||
|
||||
// Recompute the natural configuration of the non-resizable activity and the split screen.
|
||||
mActivity.clearSizeCompatMode();
|
||||
@@ -1053,12 +1142,13 @@ public class SizeCompatTests extends WindowTestsBase {
|
||||
addWindowToActivity(mActivity);
|
||||
mActivity.mRootWindowContainer.performSurfacePlacement();
|
||||
|
||||
// Split screen is also in portrait [1000,1400], so activty should be in fixed orientation
|
||||
// Split screen is also in portrait [1000,1400], so activity should be in fixed orientation
|
||||
// letterbox.
|
||||
assertEquals(ORIENTATION_PORTRAIT, mTask.getConfiguration().orientation);
|
||||
assertEquals(ORIENTATION_LANDSCAPE, mActivity.getConfiguration().orientation);
|
||||
assertFitted();
|
||||
assertTrue(mActivity.isLetterboxedForFixedOrientationAndAspectRatio());
|
||||
assertActivityMaxBoundsSandboxed();
|
||||
|
||||
// Letterbox should fill the gap between the split screen and the letterboxed activity.
|
||||
final Rect primarySplitBounds = new Rect(organizer.mPrimary.getBounds());
|
||||
@@ -1165,6 +1255,22 @@ public class SizeCompatTests extends WindowTestsBase {
|
||||
assertFalse(mActivity.hasSizeCompatBounds());
|
||||
}
|
||||
|
||||
/** Asserts the activity max bounds inherit from the TaskDisplayArea. */
|
||||
private void assertMaxBoundsInheritDisplayAreaBounds() {
|
||||
assertThat(mActivity.getConfiguration().windowConfiguration.getMaxBounds())
|
||||
.isEqualTo(mTask.getDisplayArea().getBounds());
|
||||
}
|
||||
|
||||
/**
|
||||
* Asserts activity-level letterbox or size compat mode size compat mode, so activity max
|
||||
* bounds are sandboxed.
|
||||
*/
|
||||
private void assertActivityMaxBoundsSandboxed() {
|
||||
// Activity max bounds are sandboxed due to size compat mode.
|
||||
assertThat(mActivity.getConfiguration().windowConfiguration.getMaxBounds())
|
||||
.isEqualTo(mActivity.getWindowConfiguration().getBounds());
|
||||
}
|
||||
|
||||
static Configuration rotateDisplay(DisplayContent display, int rotation) {
|
||||
final Configuration c = new Configuration();
|
||||
display.getDisplayRotation().setRotation(rotation);
|
||||
|
||||
@@ -136,6 +136,7 @@ class TestDisplayContent extends DisplayContent {
|
||||
final Display display = new Display(DisplayManagerGlobal.getInstance(), displayId,
|
||||
mInfo, DEFAULT_DISPLAY_ADJUSTMENTS);
|
||||
final TestDisplayContent newDisplay = createInternal(display);
|
||||
|
||||
// disable the normal system decorations
|
||||
final DisplayPolicy displayPolicy = newDisplay.getDisplayPolicy();
|
||||
spyOn(displayPolicy);
|
||||
|
||||
Reference in New Issue
Block a user