summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--core/java/android/view/WindowManager.java36
-rw-r--r--services/core/java/com/android/server/wm/LetterboxUiController.java16
-rw-r--r--services/tests/wmtests/src/com/android/server/wm/LetterboxUiControllerTest.java34
3 files changed, 85 insertions, 1 deletions
diff --git a/core/java/android/view/WindowManager.java b/core/java/android/view/WindowManager.java
index a01c8328b37c..033f7263bfc6 100644
--- a/core/java/android/view/WindowManager.java
+++ b/core/java/android/view/WindowManager.java
@@ -853,6 +853,42 @@ public interface WindowManager extends ViewManager {
"android.window.PROPERTY_COMPAT_IGNORE_REQUESTED_ORIENTATION";
/**
+ * Application level {@link android.content.pm.PackageManager.Property PackageManager.Property}
+ * for an app to inform the system that the app can be opted-out from the compatibility
+ * treatment that avoids {@link android.app.Activity#setRequestedOrientation} loops. The loop
+ * can be trigerred by ignoreRequestedOrientation display setting enabled on the device or
+ * by the landscape natural orientation of the device.
+ *
+ * <p>The system could ignore {@link android.app.Activity#setRequestedOrientation}
+ * call from an app if both of the following conditions are true:
+ * <ul>
+ * <li>Activity has requested orientation more than 2 times within 1-second timer
+ * <li>Activity is not letterboxed for fixed orientation
+ * </ul>
+ *
+ * <p>Setting this property to {@code false} informs the system that the app must be
+ * opted-out from the compatibility treatment even if the device manufacturer has opted the app
+ * into the treatment.
+ *
+ * <p>Not setting this property at all, or setting this property to {@code true} has no effect.
+ *
+ * <p><b>Syntax:</b>
+ * <pre>
+ * &lt;application&gt;
+ * &lt;property
+ * android:name=
+ * "android.window.PROPERTY_COMPAT_IGNORE_ORIENTATION_REQUEST_WHEN_LOOP_DETECTED"
+ * android:value="false"/&gt;
+ * &lt;/application&gt;
+ * </pre>
+ *
+ * @hide
+ */
+ // TODO(b/274924641): Make this public API.
+ String PROPERTY_COMPAT_IGNORE_ORIENTATION_REQUEST_WHEN_LOOP_DETECTED =
+ "android.window.PROPERTY_COMPAT_IGNORE_ORIENTATION_REQUEST_WHEN_LOOP_DETECTED";
+
+ /**
* Application level {@link android.content.pm.PackageManager.Property PackageManager
* .Property} for an app to inform the system that it needs to be opted-out from the
* compatibility treatment that sandboxes {@link android.view.View} API.
diff --git a/services/core/java/com/android/server/wm/LetterboxUiController.java b/services/core/java/com/android/server/wm/LetterboxUiController.java
index 4d0c7683d621..0c1923e1d28b 100644
--- a/services/core/java/com/android/server/wm/LetterboxUiController.java
+++ b/services/core/java/com/android/server/wm/LetterboxUiController.java
@@ -50,6 +50,7 @@ import static android.view.WindowManager.PROPERTY_CAMERA_COMPAT_ENABLE_REFRESH_V
import static android.view.WindowManager.PROPERTY_COMPAT_ALLOW_DISPLAY_ORIENTATION_OVERRIDE;
import static android.view.WindowManager.PROPERTY_COMPAT_ALLOW_ORIENTATION_OVERRIDE;
import static android.view.WindowManager.PROPERTY_COMPAT_ENABLE_FAKE_FOCUS;
+import static android.view.WindowManager.PROPERTY_COMPAT_IGNORE_ORIENTATION_REQUEST_WHEN_LOOP_DETECTED;
import static android.view.WindowManager.PROPERTY_COMPAT_IGNORE_REQUESTED_ORIENTATION;
import static com.android.internal.util.FrameworkStatsLog.APP_COMPAT_STATE_CHANGED__LETTERBOX_POSITION__BOTTOM;
@@ -238,6 +239,9 @@ final class LetterboxUiController {
private final Boolean mBooleanPropertyIgnoreRequestedOrientation;
@Nullable
+ private final Boolean mBooleanPropertyIgnoreOrientationRequestWhenLoopDetected;
+
+ @Nullable
private final Boolean mBooleanPropertyFakeFocus;
private boolean mIsRelauchingAfterRequestedOrientationChanged;
@@ -254,6 +258,10 @@ final class LetterboxUiController {
readComponentProperty(packageManager, mActivityRecord.packageName,
mLetterboxConfiguration::isPolicyForIgnoringRequestedOrientationEnabled,
PROPERTY_COMPAT_IGNORE_REQUESTED_ORIENTATION);
+ mBooleanPropertyIgnoreOrientationRequestWhenLoopDetected =
+ readComponentProperty(packageManager, mActivityRecord.packageName,
+ mLetterboxConfiguration::isPolicyForIgnoringRequestedOrientationEnabled,
+ PROPERTY_COMPAT_IGNORE_ORIENTATION_REQUEST_WHEN_LOOP_DETECTED);
mBooleanPropertyFakeFocus =
readComponentProperty(packageManager, mActivityRecord.packageName,
mLetterboxConfiguration::isCompatFakeFocusEnabled,
@@ -432,6 +440,8 @@ final class LetterboxUiController {
*
* <p>This treatment is enabled when the following conditions are met:
* <ul>
+ * <li>Flag gating the treatment is enabled
+ * <li>Opt-out component property isn't enabled
* <li>Per-app override is enabled
* <li>App has requested orientation more than 2 times within 1-second
* timer and activity is not letterboxed for fixed orientation
@@ -439,7 +449,11 @@ final class LetterboxUiController {
*/
@VisibleForTesting
boolean shouldIgnoreOrientationRequestLoop() {
- if (!mIsOverrideEnableCompatIgnoreOrientationRequestWhenLoopDetectedEnabled) {
+ if (!shouldEnableWithOptInOverrideAndOptOutProperty(
+ /* gatingCondition */ mLetterboxConfiguration
+ ::isPolicyForIgnoringRequestedOrientationEnabled,
+ mIsOverrideEnableCompatIgnoreOrientationRequestWhenLoopDetectedEnabled,
+ mBooleanPropertyIgnoreOrientationRequestWhenLoopDetected)) {
return false;
}
diff --git a/services/tests/wmtests/src/com/android/server/wm/LetterboxUiControllerTest.java b/services/tests/wmtests/src/com/android/server/wm/LetterboxUiControllerTest.java
index 23a3d520ea3e..9aedbf16d09c 100644
--- a/services/tests/wmtests/src/com/android/server/wm/LetterboxUiControllerTest.java
+++ b/services/tests/wmtests/src/com/android/server/wm/LetterboxUiControllerTest.java
@@ -41,6 +41,7 @@ import static android.view.WindowManager.PROPERTY_CAMERA_COMPAT_ENABLE_REFRESH_V
import static android.view.WindowManager.PROPERTY_COMPAT_ALLOW_DISPLAY_ORIENTATION_OVERRIDE;
import static android.view.WindowManager.PROPERTY_COMPAT_ALLOW_ORIENTATION_OVERRIDE;
import static android.view.WindowManager.PROPERTY_COMPAT_ENABLE_FAKE_FOCUS;
+import static android.view.WindowManager.PROPERTY_COMPAT_IGNORE_ORIENTATION_REQUEST_WHEN_LOOP_DETECTED;
import static android.view.WindowManager.PROPERTY_COMPAT_IGNORE_REQUESTED_ORIENTATION;
import static com.android.dx.mockito.inline.extended.ExtendedMockito.doReturn;
@@ -189,7 +190,28 @@ public class LetterboxUiControllerTest extends WindowTestsBase {
@Test
public void testShouldIgnoreOrientationRequestLoop_overrideDisabled_returnsFalse() {
+ doReturn(true).when(mLetterboxConfiguration)
+ .isPolicyForIgnoringRequestedOrientationEnabled();
+ doReturn(false).when(mActivity).isLetterboxedForFixedOrientationAndAspectRatio();
+ // Request 3 times to simulate orientation request loop
+ for (int i = 0; i <= MIN_COUNT_TO_IGNORE_REQUEST_IN_LOOP; i++) {
+ assertShouldIgnoreOrientationRequestLoop(/* shouldIgnore */ false,
+ /* expectedCount */ 0);
+ }
+ }
+
+ @Test
+ @EnableCompatChanges({OVERRIDE_ENABLE_COMPAT_IGNORE_ORIENTATION_REQUEST_WHEN_LOOP_DETECTED})
+ public void testShouldIgnoreOrientationRequestLoop_propertyIsFalseAndOverride_returnsFalse()
+ throws Exception {
+ doReturn(true).when(mLetterboxConfiguration)
+ .isPolicyForIgnoringRequestedOrientationEnabled();
+ mockThatProperty(PROPERTY_COMPAT_IGNORE_ORIENTATION_REQUEST_WHEN_LOOP_DETECTED,
+ /* value */ false);
doReturn(false).when(mActivity).isLetterboxedForFixedOrientationAndAspectRatio();
+
+ mController = new LetterboxUiController(mWm, mActivity);
+
// Request 3 times to simulate orientation request loop
for (int i = 0; i <= MIN_COUNT_TO_IGNORE_REQUEST_IN_LOOP; i++) {
assertShouldIgnoreOrientationRequestLoop(/* shouldIgnore */ false,
@@ -200,7 +222,10 @@ public class LetterboxUiControllerTest extends WindowTestsBase {
@Test
@EnableCompatChanges({OVERRIDE_ENABLE_COMPAT_IGNORE_ORIENTATION_REQUEST_WHEN_LOOP_DETECTED})
public void testShouldIgnoreOrientationRequestLoop_isLetterboxed_returnsFalse() {
+ doReturn(true).when(mLetterboxConfiguration)
+ .isPolicyForIgnoringRequestedOrientationEnabled();
doReturn(true).when(mActivity).isLetterboxedForFixedOrientationAndAspectRatio();
+
// Request 3 times to simulate orientation request loop
for (int i = 0; i <= MIN_COUNT_TO_IGNORE_REQUEST_IN_LOOP; i++) {
assertShouldIgnoreOrientationRequestLoop(/* shouldIgnore */ false,
@@ -211,7 +236,10 @@ public class LetterboxUiControllerTest extends WindowTestsBase {
@Test
@EnableCompatChanges({OVERRIDE_ENABLE_COMPAT_IGNORE_ORIENTATION_REQUEST_WHEN_LOOP_DETECTED})
public void testShouldIgnoreOrientationRequestLoop_noLoop_returnsFalse() {
+ doReturn(true).when(mLetterboxConfiguration)
+ .isPolicyForIgnoringRequestedOrientationEnabled();
doReturn(false).when(mActivity).isLetterboxedForFixedOrientationAndAspectRatio();
+
// No orientation request loop
assertShouldIgnoreOrientationRequestLoop(/* shouldIgnore */ false,
/* expectedCount */ 0);
@@ -221,7 +249,10 @@ public class LetterboxUiControllerTest extends WindowTestsBase {
@EnableCompatChanges({OVERRIDE_ENABLE_COMPAT_IGNORE_ORIENTATION_REQUEST_WHEN_LOOP_DETECTED})
public void testShouldIgnoreOrientationRequestLoop_timeout_returnsFalse()
throws InterruptedException {
+ doReturn(true).when(mLetterboxConfiguration)
+ .isPolicyForIgnoringRequestedOrientationEnabled();
doReturn(false).when(mActivity).isLetterboxedForFixedOrientationAndAspectRatio();
+
for (int i = MIN_COUNT_TO_IGNORE_REQUEST_IN_LOOP; i > 0; i--) {
assertShouldIgnoreOrientationRequestLoop(/* shouldIgnore */ false,
/* expectedCount */ 0);
@@ -232,7 +263,10 @@ public class LetterboxUiControllerTest extends WindowTestsBase {
@Test
@EnableCompatChanges({OVERRIDE_ENABLE_COMPAT_IGNORE_ORIENTATION_REQUEST_WHEN_LOOP_DETECTED})
public void testShouldIgnoreOrientationRequestLoop_returnsTrue() {
+ doReturn(true).when(mLetterboxConfiguration)
+ .isPolicyForIgnoringRequestedOrientationEnabled();
doReturn(false).when(mActivity).isLetterboxedForFixedOrientationAndAspectRatio();
+
for (int i = 0; i < MIN_COUNT_TO_IGNORE_REQUEST_IN_LOOP; i++) {
assertShouldIgnoreOrientationRequestLoop(/* shouldIgnore */ false,
/* expectedCount */ i);