Apply user aspect ratio override settings

User aspect ratio override should be applied first before any OEM
override/property and app default in manifest file.

Change getDisplayContent to getDisplayArea.

Fix: 287448527
Test: atest WmTests:SizeCompatTests

Change-Id: Ib72a4bfe37109dbf707e1487a51a177d1ab9b9ed
This commit is contained in:
Graciela Wissen Putri
2023-07-11 14:54:03 +00:00
parent c4c4796252
commit a3f2c5ab75
3 changed files with 235 additions and 7 deletions

View File

@@ -9420,6 +9420,9 @@ final class ActivityRecord extends WindowToken implements WindowManagerService.A
if (info.applicationInfo == null) {
return info.getMinAspectRatio();
}
if (mLetterboxUiController.shouldApplyUserMinAspectRatioOverride()) {
return mLetterboxUiController.getUserMinAspectRatio();
}
if (!mLetterboxUiController.shouldOverrideMinAspectRatio()) {
return info.getMinAspectRatio();
}

View File

@@ -40,6 +40,12 @@ import static android.content.pm.ActivityInfo.SCREEN_ORIENTATION_UNSPECIFIED;
import static android.content.pm.ActivityInfo.isFixedOrientation;
import static android.content.pm.ActivityInfo.isFixedOrientationLandscape;
import static android.content.pm.ActivityInfo.screenOrientationToString;
import static android.content.pm.PackageManager.USER_MIN_ASPECT_RATIO_16_9;
import static android.content.pm.PackageManager.USER_MIN_ASPECT_RATIO_3_2;
import static android.content.pm.PackageManager.USER_MIN_ASPECT_RATIO_4_3;
import static android.content.pm.PackageManager.USER_MIN_ASPECT_RATIO_DISPLAY_SIZE;
import static android.content.pm.PackageManager.USER_MIN_ASPECT_RATIO_SPLIT_SCREEN;
import static android.content.pm.PackageManager.USER_MIN_ASPECT_RATIO_UNSET;
import static android.content.res.Configuration.ORIENTATION_LANDSCAPE;
import static android.content.res.Configuration.ORIENTATION_PORTRAIT;
import static android.content.res.Configuration.ORIENTATION_UNDEFINED;
@@ -103,6 +109,7 @@ import android.content.res.Resources;
import android.graphics.Color;
import android.graphics.Point;
import android.graphics.Rect;
import android.os.RemoteException;
import android.util.Slog;
import android.view.InsetsSource;
import android.view.InsetsState;
@@ -237,6 +244,10 @@ final class LetterboxUiController {
// Counter for ActivityRecord#setRequestedOrientation
private int mSetOrientationRequestCounter = 0;
// The min aspect ratio override set by user
@PackageManager.UserMinAspectRatio
private int mUserAspectRatio = USER_MIN_ASPECT_RATIO_UNSET;
// The CompatDisplayInsets of the opaque activity beneath the translucent one.
private ActivityRecord.CompatDisplayInsets mInheritedCompatDisplayInsets;
@@ -1059,7 +1070,7 @@ final class LetterboxUiController {
private float getDefaultMinAspectRatioForUnresizableApps() {
if (!mLetterboxConfiguration.getIsSplitScreenAspectRatioForUnresizableAppsEnabled()
|| mActivityRecord.getDisplayContent() == null) {
|| mActivityRecord.getDisplayArea() == null) {
return mLetterboxConfiguration.getDefaultMinAspectRatioForUnresizableApps()
> MIN_FIXED_ORIENTATION_LETTERBOX_ASPECT_RATIO
? mLetterboxConfiguration.getDefaultMinAspectRatioForUnresizableApps()
@@ -1071,8 +1082,8 @@ final class LetterboxUiController {
float getSplitScreenAspectRatio() {
// Getting the same aspect ratio that apps get in split screen.
final DisplayContent displayContent = mActivityRecord.getDisplayContent();
if (displayContent == null) {
final DisplayArea displayArea = mActivityRecord.getDisplayArea();
if (displayArea == null) {
return getDefaultMinAspectRatioForUnresizableApps();
}
int dividerWindowWidth =
@@ -1080,7 +1091,7 @@ final class LetterboxUiController {
int dividerInsets =
getResources().getDimensionPixelSize(R.dimen.docked_stack_divider_insets);
int dividerSize = dividerWindowWidth - dividerInsets * 2;
final Rect bounds = new Rect(displayContent.getWindowConfiguration().getAppBounds());
final Rect bounds = new Rect(displayArea.getWindowConfiguration().getAppBounds());
if (bounds.width() >= bounds.height()) {
bounds.inset(/* dx */ dividerSize / 2, /* dy */ 0);
bounds.right = bounds.centerX();
@@ -1091,14 +1102,57 @@ final class LetterboxUiController {
return computeAspectRatio(bounds);
}
boolean shouldApplyUserMinAspectRatioOverride() {
if (!mLetterboxConfiguration.isUserAppAspectRatioSettingsEnabled()) {
return false;
}
try {
final int userAspectRatio = mActivityRecord.mAtmService.getPackageManager()
.getUserMinAspectRatio(mActivityRecord.packageName, mActivityRecord.mUserId);
mUserAspectRatio = userAspectRatio;
return userAspectRatio != USER_MIN_ASPECT_RATIO_UNSET;
} catch (RemoteException e) {
// Don't apply user aspect ratio override
Slog.w(TAG, "Exception thrown retrieving aspect ratio user override " + this, e);
return false;
}
}
float getUserMinAspectRatio() {
switch (mUserAspectRatio) {
case USER_MIN_ASPECT_RATIO_DISPLAY_SIZE:
return getDisplaySizeMinAspectRatio();
case USER_MIN_ASPECT_RATIO_SPLIT_SCREEN:
return getSplitScreenAspectRatio();
case USER_MIN_ASPECT_RATIO_16_9:
return 16 / 9f;
case USER_MIN_ASPECT_RATIO_4_3:
return 4 / 3f;
case USER_MIN_ASPECT_RATIO_3_2:
return 3 / 2f;
default:
throw new AssertionError("Unexpected user min aspect ratio override: "
+ mUserAspectRatio);
}
}
private float getDisplaySizeMinAspectRatio() {
final DisplayArea displayArea = mActivityRecord.getDisplayArea();
if (displayArea == null) {
return mActivityRecord.info.getMinAspectRatio();
}
final Rect bounds = new Rect(displayArea.getWindowConfiguration().getAppBounds());
return computeAspectRatio(bounds);
}
private float getDefaultMinAspectRatio() {
final DisplayContent displayContent = mActivityRecord.getDisplayContent();
if (displayContent == null
if (mActivityRecord.getDisplayArea() == null
|| !mLetterboxConfiguration
.getIsDisplayAspectRatioEnabledForFixedOrientationLetterbox()) {
return mLetterboxConfiguration.getFixedOrientationLetterboxAspectRatio();
}
return computeAspectRatio(new Rect(displayContent.getBounds()));
return getDisplaySizeMinAspectRatio();
}
Resources getResources() {

View File

@@ -27,6 +27,11 @@ import static android.content.pm.ActivityInfo.RESIZE_MODE_UNRESIZEABLE;
import static android.content.pm.ActivityInfo.SCREEN_ORIENTATION_LANDSCAPE;
import static android.content.pm.ActivityInfo.SCREEN_ORIENTATION_PORTRAIT;
import static android.content.pm.ActivityInfo.SCREEN_ORIENTATION_UNSPECIFIED;
import static android.content.pm.PackageManager.USER_MIN_ASPECT_RATIO_16_9;
import static android.content.pm.PackageManager.USER_MIN_ASPECT_RATIO_3_2;
import static android.content.pm.PackageManager.USER_MIN_ASPECT_RATIO_4_3;
import static android.content.pm.PackageManager.USER_MIN_ASPECT_RATIO_DISPLAY_SIZE;
import static android.content.pm.PackageManager.USER_MIN_ASPECT_RATIO_SPLIT_SCREEN;
import static android.content.res.Configuration.ORIENTATION_LANDSCAPE;
import static android.content.res.Configuration.ORIENTATION_PORTRAIT;
import static android.provider.DeviceConfig.NAMESPACE_CONSTRAIN_DISPLAY_APIS;
@@ -91,9 +96,12 @@ import android.compat.testing.PlatformCompatChangeRule;
import android.content.ComponentName;
import android.content.pm.ActivityInfo;
import android.content.pm.ActivityInfo.ScreenOrientation;
import android.content.pm.IPackageManager;
import android.content.pm.PackageManager;
import android.content.res.Configuration;
import android.graphics.Rect;
import android.os.Binder;
import android.os.RemoteException;
import android.os.UserHandle;
import android.platform.test.annotations.Presubmit;
import android.provider.DeviceConfig;
@@ -2254,6 +2262,169 @@ public class SizeCompatTests extends WindowTestsBase {
assertFitted();
}
@Test
public void testUserOverrideSplitScreenAspectRatioForLandscapeDisplay() {
final int displayWidth = 1600;
final int displayHeight = 1400;
setUpDisplaySizeWithApp(displayWidth, displayHeight);
float expectedAspectRatio = 1f * displayHeight / getExpectedSplitSize(displayWidth);
testUserOverrideAspectRatio(expectedAspectRatio, USER_MIN_ASPECT_RATIO_SPLIT_SCREEN);
}
@Test
public void testUserOverrideSplitScreenAspectRatioForPortraitDisplay() {
final int displayWidth = 1400;
final int displayHeight = 1600;
setUpDisplaySizeWithApp(displayWidth, displayHeight);
float expectedAspectRatio = 1f * displayWidth / getExpectedSplitSize(displayHeight);
testUserOverrideAspectRatio(expectedAspectRatio, USER_MIN_ASPECT_RATIO_SPLIT_SCREEN);
}
@Test
public void testUserOverrideDisplaySizeAspectRatioForLandscapeDisplay() {
final int displayWidth = 1600;
final int displayHeight = 1400;
setUpDisplaySizeWithApp(displayWidth, displayHeight);
float expectedAspectRatio = 1f * displayWidth / displayHeight;
testUserOverrideAspectRatio(expectedAspectRatio, USER_MIN_ASPECT_RATIO_DISPLAY_SIZE);
}
@Test
public void testUserOverrideDisplaySizeAspectRatioForPortraitDisplay() {
final int displayWidth = 1400;
final int displayHeight = 1600;
setUpDisplaySizeWithApp(displayWidth, displayHeight);
float expectedAspectRatio = 1f * displayHeight / displayWidth;
testUserOverrideAspectRatio(expectedAspectRatio, USER_MIN_ASPECT_RATIO_DISPLAY_SIZE);
}
@Test
public void testUserOverride32AspectRatioForPortraitDisplay() {
setUpDisplaySizeWithApp(/* dw */ 1400, /* dh */ 1600);
testUserOverrideAspectRatio(3 / 2f, USER_MIN_ASPECT_RATIO_3_2);
}
@Test
public void testUserOverride32AspectRatioForLandscapeDisplay() {
setUpDisplaySizeWithApp(/* dw */ 1600, /* dh */ 1400);
testUserOverrideAspectRatio(3 / 2f, USER_MIN_ASPECT_RATIO_3_2);
}
@Test
public void testUserOverride43AspectRatioForPortraitDisplay() {
setUpDisplaySizeWithApp(/* dw */ 1400, /* dh */ 1600);
testUserOverrideAspectRatio(4 / 3f, USER_MIN_ASPECT_RATIO_4_3);
}
@Test
public void testUserOverride43AspectRatioForLandscapeDisplay() {
setUpDisplaySizeWithApp(/* dw */ 1600, /* dh */ 1400);
testUserOverrideAspectRatio(4 / 3f, USER_MIN_ASPECT_RATIO_4_3);
}
@Test
public void testUserOverride169AspectRatioForPortraitDisplay() {
setUpDisplaySizeWithApp(/* dw */ 1800, /* dh */ 1500);
testUserOverrideAspectRatio(16 / 9f, USER_MIN_ASPECT_RATIO_16_9);
}
@Test
public void testUserOverride169AspectRatioForLandscapeDisplay() {
setUpDisplaySizeWithApp(/* dw */ 1500, /* dh */ 1800);
testUserOverrideAspectRatio(16 / 9f, USER_MIN_ASPECT_RATIO_16_9);
}
@Test
@EnableCompatChanges({ActivityInfo.OVERRIDE_MIN_ASPECT_RATIO,
ActivityInfo.OVERRIDE_MIN_ASPECT_RATIO_LARGE})
public void testUserOverrideAspectRatioOverSystemOverride() {
setUpDisplaySizeWithApp(/* dw */ 1600, /* dh */ 1400);
testUserOverrideAspectRatio(false,
SCREEN_ORIENTATION_PORTRAIT,
3 / 2f,
USER_MIN_ASPECT_RATIO_3_2,
true);
}
@Test
public void testUserOverrideAspectRatioNotEnabled() {
setUpDisplaySizeWithApp(/* dw */ 1600, /* dh */ 1400);
// App aspect ratio doesn't change
testUserOverrideAspectRatio(false,
SCREEN_ORIENTATION_PORTRAIT,
1f * 1600 / 1400,
USER_MIN_ASPECT_RATIO_3_2,
false);
}
private void testUserOverrideAspectRatio(float expectedAspectRatio,
@PackageManager.UserMinAspectRatio int aspectRatio) {
testUserOverrideAspectRatio(true,
SCREEN_ORIENTATION_PORTRAIT,
expectedAspectRatio,
aspectRatio,
true);
testUserOverrideAspectRatio(false,
SCREEN_ORIENTATION_PORTRAIT,
expectedAspectRatio,
aspectRatio,
true);
testUserOverrideAspectRatio(true,
SCREEN_ORIENTATION_LANDSCAPE,
expectedAspectRatio,
aspectRatio,
true);
testUserOverrideAspectRatio(false,
SCREEN_ORIENTATION_LANDSCAPE,
expectedAspectRatio,
aspectRatio,
true);
}
private void testUserOverrideAspectRatio(boolean isUnresizable, int screenOrientation,
float expectedAspectRatio, @PackageManager.UserMinAspectRatio int aspectRatio,
boolean enabled) {
final ActivityRecord activity = new ActivityBuilder(mAtm)
.setTask(mTask)
.setComponent(ComponentName.createRelative(mContext,
SizeCompatTests.class.getName()))
.setUid(android.os.Process.myUid())
.build();
activity.mDisplayContent.setIgnoreOrientationRequest(true /* ignoreOrientationRequest */);
activity.mWmService.mLetterboxConfiguration
.setUserAppAspectRatioSettingsOverrideEnabled(enabled);
// Set user aspect ratio override
final IPackageManager pm = mAtm.getPackageManager();
try {
doReturn(aspectRatio).when(pm)
.getUserMinAspectRatio(activity.packageName, activity.mUserId);
} catch (RemoteException ignored) {
}
prepareLimitedBounds(activity, screenOrientation, isUnresizable);
final Rect afterBounds = activity.getBounds();
final int width = afterBounds.width();
final int height = afterBounds.height();
final float afterAspectRatio =
(float) Math.max(width, height) / (float) Math.min(width, height);
assertEquals(expectedAspectRatio, afterAspectRatio, 0.001f);
}
@Test
@EnableCompatChanges({ActivityInfo.OVERRIDE_MIN_ASPECT_RATIO,
ActivityInfo.OVERRIDE_MIN_ASPECT_RATIO_TO_ALIGN_WITH_SPLIT_SCREEN})