Merge "Skip Size Compat mode when orientation change comes from app" into tm-qpr-dev

This commit is contained in:
Vali Calinescu
2023-03-09 12:07:33 +00:00
committed by Android (Google) Code Review
7 changed files with 140 additions and 22 deletions

View File

@@ -1051,6 +1051,12 @@
"group": "WM_DEBUG_ORIENTATION",
"at": "com\/android\/server\/wm\/WindowContainer.java"
},
"-1104347731": {
"message": "Setting requested orientation %s for %s",
"level": "VERBOSE",
"group": "WM_DEBUG_ORIENTATION",
"at": "com\/android\/server\/wm\/ActivityRecord.java"
},
"-1103716954": {
"message": "Not removing %s due to exit animation",
"level": "VERBOSE",

View File

@@ -7733,27 +7733,38 @@ final class ActivityRecord extends WindowToken implements WindowManagerService.A
/**
* Returns the requested {@link Configuration.Orientation} for the current activity.
*
* <p>When The current orientation is set to {@link SCREEN_ORIENTATION_BEHIND} it returns the
* requested orientation for the activity below which is the first activity with an explicit
* (different from {@link SCREEN_ORIENTATION_UNSET}) orientation which is not {@link
* SCREEN_ORIENTATION_BEHIND}.
*/
@Configuration.Orientation
@Override
int getRequestedConfigurationOrientation(boolean forDisplay) {
return getRequestedConfigurationOrientation(forDisplay, getOverrideOrientation());
}
/**
* Returns the requested {@link Configuration.Orientation} for the requested
* {@link ActivityInfo.ScreenOrientation}.
*
* <p>When the current screen orientation is set to {@link SCREEN_ORIENTATION_BEHIND} it returns
* the requested orientation for the activity below which is the first activity with an explicit
* (different from {@link SCREEN_ORIENTATION_UNSET}) orientation which is not {@link
* SCREEN_ORIENTATION_BEHIND}.
*/
@Configuration.Orientation
int getRequestedConfigurationOrientation(boolean forDisplay,
@ActivityInfo.ScreenOrientation int requestedOrientation) {
if (mLetterboxUiController.hasInheritedOrientation()) {
final RootDisplayArea root = getRootDisplayArea();
if (forDisplay && root != null && root.isOrientationDifferentFromDisplay()) {
return ActivityInfo.reverseOrientation(
return reverseConfigurationOrientation(
mLetterboxUiController.getInheritedOrientation());
} else {
return mLetterboxUiController.getInheritedOrientation();
}
}
if (task != null && getOverrideOrientation() == SCREEN_ORIENTATION_BEHIND) {
if (task != null && requestedOrientation == SCREEN_ORIENTATION_BEHIND) {
// We use Task here because we want to be consistent with what happens in
// multi-window mode where other tasks orientations are ignored.
android.util.Log.d("orientation", "We are here");
final ActivityRecord belowCandidate = task.getActivity(
a -> a.canDefineOrientationForActivitiesAbove() /* callback */,
this /* boundary */, false /* includeBoundary */,
@@ -7762,7 +7773,23 @@ final class ActivityRecord extends WindowToken implements WindowManagerService.A
return belowCandidate.getRequestedConfigurationOrientation(forDisplay);
}
}
return super.getRequestedConfigurationOrientation(forDisplay);
return super.getRequestedConfigurationOrientation(forDisplay, requestedOrientation);
}
/**
* Returns the reversed configuration orientation.
* @hide
*/
@Configuration.Orientation
public static int reverseConfigurationOrientation(@Configuration.Orientation int orientation) {
switch (orientation) {
case ORIENTATION_LANDSCAPE:
return ORIENTATION_PORTRAIT;
case ORIENTATION_PORTRAIT:
return ORIENTATION_LANDSCAPE;
default:
return orientation;
}
}
/**
@@ -7808,6 +7835,19 @@ final class ActivityRecord extends WindowToken implements WindowManagerService.A
if (mLetterboxUiController.shouldIgnoreRequestedOrientation(requestedOrientation)) {
return;
}
// This is necessary in order to avoid going into size compat mode when the orientation
// change request comes from the app
if (mWmService.mLetterboxConfiguration
.isSizeCompatModeDisabledAfterOrientationChangeFromApp()
&& getRequestedConfigurationOrientation(false, requestedOrientation)
!= getRequestedConfigurationOrientation(false /*forDisplay */)) {
// Do not change the requested configuration now, because this will be done when setting
// the orientation below with the new mCompatDisplayInsets
clearSizeCompatModeAttributes();
}
ProtoLog.v(WM_DEBUG_ORIENTATION,
"Setting requested orientation %s for %s",
ActivityInfo.screenOrientationToString(requestedOrientation), this);
setOrientation(requestedOrientation, this);
// Push the new configuration to the requested app in case where it's not pushed, e.g. when
@@ -8027,17 +8067,20 @@ final class ActivityRecord extends WindowToken implements WindowManagerService.A
mDisplayContent, this, mLetterboxBoundsForFixedOrientationAndAspectRatio);
}
@VisibleForTesting
void clearSizeCompatMode() {
final float lastSizeCompatScale = mSizeCompatScale;
private void clearSizeCompatModeAttributes() {
mInSizeCompatModeForBounds = false;
mSizeCompatScale = 1f;
mSizeCompatBounds = null;
mCompatDisplayInsets = null;
}
@VisibleForTesting
void clearSizeCompatMode() {
final float lastSizeCompatScale = mSizeCompatScale;
clearSizeCompatModeAttributes();
if (mSizeCompatScale != lastSizeCompatScale) {
forAllWindows(WindowState::updateGlobalScale, false /* traverseTopToBottom */);
}
// Clear config override in #updateCompatDisplayInsets().
final int activityType = getActivityType();
final Configuration overrideConfig = getRequestedOverrideConfiguration();

View File

@@ -19,6 +19,7 @@ package com.android.server.wm;
import static com.android.server.wm.ActivityTaskManagerDebugConfig.TAG_ATM;
import static com.android.server.wm.ActivityTaskManagerDebugConfig.TAG_WITH_CLASS_NAME;
import static com.android.server.wm.LetterboxConfigurationDeviceConfig.KEY_ALLOW_IGNORE_ORIENTATION_REQUEST;
import static com.android.server.wm.LetterboxConfigurationDeviceConfig.KEY_DISABLE_SIZE_COMPAT_MODE_AFTER_ORIENTATION_CHANGE_FROM_APP;
import static com.android.server.wm.LetterboxConfigurationDeviceConfig.KEY_ENABLE_CAMERA_COMPAT_TREATMENT;
import static com.android.server.wm.LetterboxConfigurationDeviceConfig.KEY_ENABLE_COMPAT_FAKE_FOCUS;
import static com.android.server.wm.LetterboxConfigurationDeviceConfig.KEY_ENABLE_DISPLAY_ROTATION_IMMERSIVE_APP_COMPAT_POLICY;
@@ -314,6 +315,10 @@ final class LetterboxConfiguration {
mDeviceConfig.updateFlagActiveStatus(
/* isActive */ mTranslucentLetterboxingEnabled,
/* key */ KEY_ENABLE_LETTERBOX_TRANSLUCENT_ACTIVITY);
mDeviceConfig.updateFlagActiveStatus(
/* isActive */ true,
/* key */ KEY_DISABLE_SIZE_COMPAT_MODE_AFTER_ORIENTATION_CHANGE_FROM_APP);
mLetterboxConfigurationPersister = letterboxConfigurationPersister;
mLetterboxConfigurationPersister.start();
}
@@ -326,6 +331,16 @@ final class LetterboxConfiguration {
return mDeviceConfig.getFlag(KEY_ALLOW_IGNORE_ORIENTATION_REQUEST);
}
/**
* Whether size compat mode is disabled after an orientation change request comes from the app.
* This value is controlled via {@link android.provider.DeviceConfig}.
*/
// TODO(b/270356567) Clean up this flag
boolean isSizeCompatModeDisabledAfterOrientationChangeFromApp() {
return mDeviceConfig.getFlag(
KEY_DISABLE_SIZE_COMPAT_MODE_AFTER_ORIENTATION_CHANGE_FROM_APP);
}
/**
* Overrides the aspect ratio of letterbox for fixed orientation. If given value is <= {@link
* #MIN_FIXED_ORIENTATION_LETTERBOX_ASPECT_RATIO}, both it and a value of {@link

View File

@@ -20,7 +20,6 @@ import android.annotation.NonNull;
import android.provider.DeviceConfig;
import android.util.ArraySet;
import com.android.internal.annotations.VisibleForTesting;
import java.util.Map;
@@ -53,6 +52,11 @@ final class LetterboxConfigurationDeviceConfig
private static final boolean DEFAULT_VALUE_ENABLE_LETTERBOX_TRANSLUCENT_ACTIVITY = true;
static final String KEY_DISABLE_SIZE_COMPAT_MODE_AFTER_ORIENTATION_CHANGE_FROM_APP =
"disable_size_compat_mode_after_orientation_change_from_app";
private static final boolean
DEFAULT_VALUE_DISABLE_SIZE_COMPAT_MODE_AFTER_ORIENTATION_CHANGE_FROM_APP = true;
@VisibleForTesting
static final Map<String, Boolean> sKeyToDefaultValueMap = Map.of(
KEY_ENABLE_CAMERA_COMPAT_TREATMENT,
@@ -64,7 +68,9 @@ final class LetterboxConfigurationDeviceConfig
KEY_ENABLE_COMPAT_FAKE_FOCUS,
DEFAULT_VALUE_ENABLE_COMPAT_FAKE_FOCUS,
KEY_ENABLE_LETTERBOX_TRANSLUCENT_ACTIVITY,
DEFAULT_VALUE_ENABLE_LETTERBOX_TRANSLUCENT_ACTIVITY
DEFAULT_VALUE_ENABLE_LETTERBOX_TRANSLUCENT_ACTIVITY,
KEY_DISABLE_SIZE_COMPAT_MODE_AFTER_ORIENTATION_CHANGE_FROM_APP,
DEFAULT_VALUE_DISABLE_SIZE_COMPAT_MODE_AFTER_ORIENTATION_CHANGE_FROM_APP
);
// Whether camera compatibility treatment is enabled.
@@ -93,6 +99,10 @@ final class LetterboxConfigurationDeviceConfig
private boolean mIsTranslucentLetterboxingAllowed =
DEFAULT_VALUE_ENABLE_LETTERBOX_TRANSLUCENT_ACTIVITY;
// Whether size compat mode is disabled after an orientation change request comes from the app
private boolean mIsSizeCompatModeDisabledAfterOrientationChangeFromApp =
DEFAULT_VALUE_DISABLE_SIZE_COMPAT_MODE_AFTER_ORIENTATION_CHANGE_FROM_APP;
// Set of active device configs that need to be updated in
// DeviceConfig.OnPropertiesChangedListener#onPropertiesChanged.
private final ArraySet<String> mActiveDeviceConfigsSet = new ArraySet<>();
@@ -142,6 +152,8 @@ final class LetterboxConfigurationDeviceConfig
return mIsCompatFakeFocusAllowed;
case KEY_ENABLE_LETTERBOX_TRANSLUCENT_ACTIVITY:
return mIsTranslucentLetterboxingAllowed;
case KEY_DISABLE_SIZE_COMPAT_MODE_AFTER_ORIENTATION_CHANGE_FROM_APP:
return mIsSizeCompatModeDisabledAfterOrientationChangeFromApp;
default:
throw new AssertionError("Unexpected flag name: " + key);
}
@@ -169,6 +181,10 @@ final class LetterboxConfigurationDeviceConfig
case KEY_ENABLE_LETTERBOX_TRANSLUCENT_ACTIVITY:
mIsTranslucentLetterboxingAllowed = getDeviceConfig(key, defaultValue);
break;
case KEY_DISABLE_SIZE_COMPAT_MODE_AFTER_ORIENTATION_CHANGE_FROM_APP:
mIsSizeCompatModeDisabledAfterOrientationChangeFromApp =
getDeviceConfig(key, defaultValue);
break;
default:
throw new AssertionError("Unexpected flag name: " + key);
}

View File

@@ -1456,7 +1456,26 @@ class WindowContainer<E extends WindowContainer> extends ConfigurationContainer<
*/
@Configuration.Orientation
int getRequestedConfigurationOrientation(boolean forDisplay) {
int requestedOrientation = getOverrideOrientation();
return getRequestedConfigurationOrientation(forDisplay, getOverrideOrientation());
}
/**
* Gets the configuration orientation by the requested screen orientation
*
* @param forDisplay whether it is the requested config orientation for display.
* If {@code true}, we may reverse the requested orientation if the root is
* different from the display, so that when the display rotates to the
* reversed orientation, the requested app will be in the requested
* orientation.
* @param requestedOrientation the screen orientation({@link ScreenOrientation}) that is
* requested
* @return orientation in ({@link Configuration#ORIENTATION_LANDSCAPE},
* {@link Configuration#ORIENTATION_PORTRAIT},
* {@link Configuration#ORIENTATION_UNDEFINED}).
*/
@Configuration.Orientation
int getRequestedConfigurationOrientation(boolean forDisplay,
@ScreenOrientation int requestedOrientation) {
final RootDisplayArea root = getRootDisplayArea();
if (forDisplay && root != null && root.isOrientationDifferentFromDisplay()) {
// Reverse the requested orientation if the orientation of its root is different from
@@ -1466,7 +1485,7 @@ class WindowContainer<E extends WindowContainer> extends ConfigurationContainer<
// (portrait).
// When an app below the DAG is requesting landscape, it should actually request the
// display to be portrait, so that the DAG and the app will be in landscape.
requestedOrientation = reverseOrientation(getOverrideOrientation());
requestedOrientation = reverseOrientation(requestedOrientation);
}
if (requestedOrientation == ActivityInfo.SCREEN_ORIENTATION_NOSENSOR) {

View File

@@ -2377,7 +2377,7 @@ public class ActivityRecordTests extends WindowTestsBase {
.setScreenOrientation(SCREEN_ORIENTATION_BEHIND)
.build();
final int topOrientation = activityTop.getRequestedConfigurationOrientation();
assertEquals(SCREEN_ORIENTATION_PORTRAIT, topOrientation);
assertEquals(ORIENTATION_PORTRAIT, topOrientation);
}
private void verifyProcessInfoUpdate(ActivityRecord activity, State state,

View File

@@ -381,7 +381,7 @@ public class SizeCompatTests extends WindowTestsBase {
}
@Test
public void testTranslucentActivitiesDontGoInSizeCompactMode() {
public void testTranslucentActivitiesDontGoInSizeCompatMode() {
mWm.mLetterboxConfiguration.setTranslucentLetterboxingOverrideEnabled(true);
setUpDisplaySizeWithApp(2800, 1400);
mActivity.mDisplayContent.setIgnoreOrientationRequest(true /* ignoreOrientationRequest */);
@@ -2454,11 +2454,11 @@ public class SizeCompatTests extends WindowTestsBase {
assertFalse(mActivity.inSizeCompatMode());
mActivity.setRequestedOrientation(SCREEN_ORIENTATION_UNSPECIFIED);
assertTrue(mActivity.inSizeCompatMode());
// We should remember the original orientation.
// Activity is not in size compat mode because the orientation change request came from the
// app itself
assertFalse(mActivity.inSizeCompatMode());
assertEquals(mActivity.getResolvedOverrideConfiguration().orientation,
Configuration.ORIENTATION_PORTRAIT);
Configuration.ORIENTATION_UNDEFINED);
}
@Test
@@ -3032,6 +3032,25 @@ public class SizeCompatTests extends WindowTestsBase {
assertTrue(mActivity.mLetterboxUiController.isVerticalReachabilityEnabled());
}
@Test
public void testAppRequestsOrientationChange_notInSizeCompat() {
setUpDisplaySizeWithApp(2200, 1800);
mActivity.mDisplayContent.setIgnoreOrientationRequest(true /* ignoreOrientationRequest */);
prepareUnresizable(mActivity, SCREEN_ORIENTATION_LANDSCAPE);
mActivity.setRequestedOrientation(SCREEN_ORIENTATION_PORTRAIT);
// Activity is not in size compat mode because the orientation change request came from the
// app itself
assertFalse(mActivity.inSizeCompatMode());
rotateDisplay(mActivity.mDisplayContent, ROTATION_270);
// Activity should go into size compat mode now because the orientation change came from the
// system (device rotation)
assertTrue(mActivity.inSizeCompatMode());
}
@Test
public void testLetterboxDetailsForStatusBar_noLetterbox() {
setUpDisplaySizeWithApp(2800, 1000);