summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--data/etc/services.core.protolog.json6
-rw-r--r--services/core/java/com/android/server/wm/ActivityRecord.java65
-rw-r--r--services/core/java/com/android/server/wm/LetterboxConfiguration.java15
-rw-r--r--services/core/java/com/android/server/wm/LetterboxConfigurationDeviceConfig.java20
-rw-r--r--services/core/java/com/android/server/wm/WindowContainer.java23
-rw-r--r--services/tests/wmtests/src/com/android/server/wm/ActivityRecordTests.java2
-rw-r--r--services/tests/wmtests/src/com/android/server/wm/SizeCompatTests.java29
7 files changed, 139 insertions, 21 deletions
diff --git a/data/etc/services.core.protolog.json b/data/etc/services.core.protolog.json
index 913eaf2391f6..ffc5ff226607 100644
--- a/data/etc/services.core.protolog.json
+++ b/data/etc/services.core.protolog.json
@@ -1099,6 +1099,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",
diff --git a/services/core/java/com/android/server/wm/ActivityRecord.java b/services/core/java/com/android/server/wm/ActivityRecord.java
index 424c3271cde6..c7754194d3b1 100644
--- a/services/core/java/com/android/server/wm/ActivityRecord.java
+++ b/services/core/java/com/android/server/wm/ActivityRecord.java
@@ -7824,27 +7824,38 @@ final class ActivityRecord extends WindowToken implements WindowManagerService.A
/**
* Returns the requested {@link Configuration.Orientation} for the current activity.
+ */
+ @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 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
+ * <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
- @Override
- int getRequestedConfigurationOrientation(boolean forDisplay) {
+ 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 */,
@@ -7853,7 +7864,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;
+ }
}
/**
@@ -7899,6 +7926,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
@@ -8139,17 +8179,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();
diff --git a/services/core/java/com/android/server/wm/LetterboxConfiguration.java b/services/core/java/com/android/server/wm/LetterboxConfiguration.java
index fa49a6ba6c2b..37cf5bc95a23 100644
--- a/services/core/java/com/android/server/wm/LetterboxConfiguration.java
+++ b/services/core/java/com/android/server/wm/LetterboxConfiguration.java
@@ -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();
}
@@ -327,6 +332,16 @@ final class LetterboxConfiguration {
}
/**
+ * 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
* com.android.internal.R.dimen.config_fixedOrientationLetterboxAspectRatio} will be ignored and
diff --git a/services/core/java/com/android/server/wm/LetterboxConfigurationDeviceConfig.java b/services/core/java/com/android/server/wm/LetterboxConfigurationDeviceConfig.java
index df3c8f0fdccc..1651af328b1f 100644
--- a/services/core/java/com/android/server/wm/LetterboxConfigurationDeviceConfig.java
+++ b/services/core/java/com/android/server/wm/LetterboxConfigurationDeviceConfig.java
@@ -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);
}
diff --git a/services/core/java/com/android/server/wm/WindowContainer.java b/services/core/java/com/android/server/wm/WindowContainer.java
index 132f5a72aadb..d42a62971395 100644
--- a/services/core/java/com/android/server/wm/WindowContainer.java
+++ b/services/core/java/com/android/server/wm/WindowContainer.java
@@ -1493,7 +1493,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
@@ -1503,7 +1522,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) {
diff --git a/services/tests/wmtests/src/com/android/server/wm/ActivityRecordTests.java b/services/tests/wmtests/src/com/android/server/wm/ActivityRecordTests.java
index 49f215a83c2b..6147633f624a 100644
--- a/services/tests/wmtests/src/com/android/server/wm/ActivityRecordTests.java
+++ b/services/tests/wmtests/src/com/android/server/wm/ActivityRecordTests.java
@@ -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,
diff --git a/services/tests/wmtests/src/com/android/server/wm/SizeCompatTests.java b/services/tests/wmtests/src/com/android/server/wm/SizeCompatTests.java
index 00d7a52752dd..753cc623cf25 100644
--- a/services/tests/wmtests/src/com/android/server/wm/SizeCompatTests.java
+++ b/services/tests/wmtests/src/com/android/server/wm/SizeCompatTests.java
@@ -402,7 +402,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 */);
@@ -2490,11 +2490,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
@@ -3069,6 +3069,25 @@ public class SizeCompatTests extends WindowTestsBase {
}
@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);
addStatusBar(mActivity.mDisplayContent);