Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit c17d5c03 authored by Graciela Wissen Putri's avatar Graciela Wissen Putri
Browse files

Add opt-out properties for user aspect ratio override

Add opt-out property for user aspect ratio override settings and opt-out
property for user aspect ratio fullscreen override. User aspect ratio
fullscreen override should not be applied if app has opted out from
either user aspect ratio override or fullscreen override specifically.

Bug: 292583399
Test: atest LetterboxUiControllerTest
Change-Id: I9a08740847577876dbdaaf673a7716fa94e2b5f7
parent 9c9649e4
Loading
Loading
Loading
Loading
+96 −8
Original line number Diff line number Diff line
@@ -913,7 +913,6 @@ public interface WindowManager extends ViewManager {
     * </application>
     * </pre>
     */
    // TODO(b/263984287): Add CTS tests.
    String PROPERTY_COMPAT_IGNORE_REQUESTED_ORIENTATION =
            "android.window.PROPERTY_COMPAT_IGNORE_REQUESTED_ORIENTATION";

@@ -983,7 +982,6 @@ public interface WindowManager extends ViewManager {
     * &lt;/application&gt;
     * </pre>
     */
    // TODO(b/263984287): Make this public API.
    String PROPERTY_COMPAT_ALLOW_SANDBOXING_VIEW_BOUNDS_APIS =
            "android.window.PROPERTY_COMPAT_ALLOW_SANDBOXING_VIEW_BOUNDS_APIS";

@@ -1018,7 +1016,6 @@ public interface WindowManager extends ViewManager {
     * &lt;/application&gt;
     * </pre>
     */
    // TODO(b/263984287): Add CTS tests.
    String PROPERTY_COMPAT_ENABLE_FAKE_FOCUS = "android.window.PROPERTY_COMPAT_ENABLE_FAKE_FOCUS";

    /**
@@ -1056,7 +1053,6 @@ public interface WindowManager extends ViewManager {
     * &lt;/application&gt;
     * </pre>
     */
    // TODO(b/263984287): Add CTS tests.
    String PROPERTY_CAMERA_COMPAT_ALLOW_FORCE_ROTATION =
            "android.window.PROPERTY_CAMERA_COMPAT_ALLOW_FORCE_ROTATION";

@@ -1102,7 +1098,6 @@ public interface WindowManager extends ViewManager {
     * &lt;/application&gt;
     * </pre>
     */
    // TODO(b/263984287): Add CTS tests.
    String PROPERTY_CAMERA_COMPAT_ALLOW_REFRESH =
            "android.window.PROPERTY_CAMERA_COMPAT_ALLOW_REFRESH";

@@ -1151,7 +1146,6 @@ public interface WindowManager extends ViewManager {
     * &lt;/application&gt;
     * </pre>
     */
    // TODO(b/263984287): Add CTS tests.
    String PROPERTY_CAMERA_COMPAT_ENABLE_REFRESH_VIA_PAUSE =
            "android.window.PROPERTY_CAMERA_COMPAT_ENABLE_REFRESH_VIA_PAUSE";

@@ -1189,7 +1183,6 @@ public interface WindowManager extends ViewManager {
     * &lt;/application&gt;
     * </pre>
     */
    // TODO(b/263984287): Add CTS tests.
    String PROPERTY_COMPAT_ALLOW_ORIENTATION_OVERRIDE =
            "android.window.PROPERTY_COMPAT_ALLOW_ORIENTATION_OVERRIDE";

@@ -1233,7 +1226,6 @@ public interface WindowManager extends ViewManager {
     * &lt;/application&gt;
     * </pre>
     */
    // TODO(b/263984287): Add CTS tests.
    String PROPERTY_COMPAT_ALLOW_DISPLAY_ORIENTATION_OVERRIDE =
            "android.window.PROPERTY_COMPAT_ALLOW_DISPLAY_ORIENTATION_OVERRIDE";

@@ -1299,6 +1291,102 @@ public interface WindowManager extends ViewManager {
    String PROPERTY_COMPAT_ALLOW_RESIZEABLE_ACTIVITY_OVERRIDES =
            "android.window.PROPERTY_COMPAT_ALLOW_RESIZEABLE_ACTIVITY_OVERRIDES";

    /**
     * Application level
     * {@link android.content.pm.PackageManager.Property PackageManager.Property}
     * tag that (when set to false) informs the system the app has opted out of the
     * user-facing aspect ratio compatibility override.
     *
     * <p>The compatibility override enables device users to set the app's aspect
     * ratio or force the app to fill the display regardless of the aspect
     * ratio or orientation specified in the app manifest.
     *
     * <p>The aspect ratio compatibility override is exposed to users in device
     * settings. A menu in device settings lists all apps that don't opt out of
     * the compatibility override. Users select apps from the menu and set the
     * app aspect ratio on a per-app basis. Typically, the menu is available
     * only on large screen devices.
     *
     * <p>When users apply the aspect ratio override, the minimum aspect ratio
     * specified in the app manifest is overridden. If users choose a
     * full-screen aspect ratio, the orientation of the activity is forced to
     * {@link android.content.pm.ActivityInfo#SCREEN_ORIENTATION_USER};
     * see {@link #PROPERTY_COMPAT_ALLOW_USER_ASPECT_RATIO_FULLSCREEN_OVERRIDE} to
     * disable the full-screen option only.
     *
     * <p>The user override is intended to improve the app experience on devices
     * that have the ignore orientation request display setting enabled by OEMs
     * (enables compatibility mode for fixed orientation on Android 12 (API
     * level 31) or higher; see
     * <a href="https://developer.android.com/guide/topics/large-screens/large-screen-app-compatibility">
     * Large screen app compatibility</a>
     * for more details).
     *
     * <p>To opt out of the user aspect ratio compatibility override, add this property
     * to your app manifest and set the value to {@code false}. Your app will be excluded
     * from the list of apps in device settings, and users will not be able to override
     * the app's aspect ratio.
     *
     * <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_ALLOW_USER_ASPECT_RATIO_OVERRIDE"
     *     android:value="false"/&gt;
     * &lt;/application&gt;
     * </pre>
     * @hide
     */
    // TODO(b/294227289): Make this public API
    String PROPERTY_COMPAT_ALLOW_USER_ASPECT_RATIO_OVERRIDE =
            "android.window.PROPERTY_COMPAT_ALLOW_USER_ASPECT_RATIO_OVERRIDE";

    /**
     * Application level
     * {@link android.content.pm.PackageManager.Property PackageManager.Property}
     * tag that (when set to false) informs the system the app has opted out of the
     * full-screen option of the aspect ratio compatibility override. (For
     * background information about the aspect ratio compatibility override, see
     * {@link #PROPERTY_COMPAT_ALLOW_USER_ASPECT_RATIO_OVERRIDE}.)
     *
     * <p>When users apply the aspect ratio compatibility override, the orientation
     * of the activity is forced to {@link android.content.pm.ActivityInfo#SCREEN_ORIENTATION_USER}.
     *
     * <p>The user override is intended to improve the app experience on devices
     * that have the ignore orientation request display setting enabled by OEMs
     * (enables compatibility mode for fixed orientation on Android 12 (API
     * level 31) or higher; see
     * <a href="https://developer.android.com/guide/topics/large-screens/large-screen-app-compatibility">
     * Large screen app compatibility</a>
     * for more details).
     *
     * <p>To opt out of the full-screen option of the user aspect ratio compatibility
     * override, add this property to your app manifest and set the value to {@code false}.
     * Your app will have full-screen option removed from the list of user aspect ratio
     * override options in device settings, and users will not be able to apply
     * full-screen override to your app.
     *
     * <p><b>Note:</b> If {@link #PROPERTY_COMPAT_ALLOW_USER_ASPECT_RATIO_OVERRIDE} is
     * {@code false}, this property has no effect.
     *
     * <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_ALLOW_USER_ASPECT_RATIO_FULLSCREEN_OVERRIDE"
     *     android:value="false"/&gt;
     * &lt;/application&gt;
     * </pre>
     * @hide
     */
    // TODO(b/294227289): Make this public API
    String PROPERTY_COMPAT_ALLOW_USER_ASPECT_RATIO_FULLSCREEN_OVERRIDE =
            "android.window.PROPERTY_COMPAT_ALLOW_USER_ASPECT_RATIO_FULLSCREEN_OVERRIDE";

    /**
     * @hide
     */
+23 −3
Original line number Diff line number Diff line
@@ -63,6 +63,8 @@ import static android.view.WindowManager.PROPERTY_COMPAT_ALLOW_IGNORING_ORIENTAT
import static android.view.WindowManager.PROPERTY_COMPAT_ALLOW_MIN_ASPECT_RATIO_OVERRIDE;
import static android.view.WindowManager.PROPERTY_COMPAT_ALLOW_ORIENTATION_OVERRIDE;
import static android.view.WindowManager.PROPERTY_COMPAT_ALLOW_RESIZEABLE_ACTIVITY_OVERRIDES;
import static android.view.WindowManager.PROPERTY_COMPAT_ALLOW_USER_ASPECT_RATIO_FULLSCREEN_OVERRIDE;
import static android.view.WindowManager.PROPERTY_COMPAT_ALLOW_USER_ASPECT_RATIO_OVERRIDE;
import static android.view.WindowManager.PROPERTY_COMPAT_ENABLE_FAKE_FOCUS;
import static android.view.WindowManager.PROPERTY_COMPAT_IGNORE_REQUESTED_ORIENTATION;

@@ -215,6 +217,11 @@ final class LetterboxUiController {
    @Nullable
    private final Boolean mBooleanPropertyAllowForceResizeOverride;

    @Nullable
    private final Boolean mBooleanPropertyAllowUserAspectRatioOverride;
    @Nullable
    private final Boolean mBooleanPropertyAllowUserAspectRatioFullscreenOverride;

    /*
     * WindowContainerListener responsible to make translucent activities inherit
     * constraints from the first opaque activity beneath them. It's null for not
@@ -335,6 +342,15 @@ final class LetterboxUiController {
                        /* gatingCondition */ null,
                        PROPERTY_COMPAT_ALLOW_RESIZEABLE_ACTIVITY_OVERRIDES);

        mBooleanPropertyAllowUserAspectRatioOverride =
                readComponentProperty(packageManager, mActivityRecord.packageName,
                        () -> mLetterboxConfiguration.isUserAppAspectRatioSettingsEnabled(),
                        PROPERTY_COMPAT_ALLOW_USER_ASPECT_RATIO_OVERRIDE);
        mBooleanPropertyAllowUserAspectRatioFullscreenOverride =
                readComponentProperty(packageManager, mActivityRecord.packageName,
                        () -> mLetterboxConfiguration.isUserAppAspectRatioFullscreenEnabled(),
                        PROPERTY_COMPAT_ALLOW_USER_ASPECT_RATIO_FULLSCREEN_OVERRIDE);

        mIsOverrideAnyOrientationEnabled = isCompatChangeEnabled(OVERRIDE_ANY_ORIENTATION);
        mIsOverrideToPortraitOrientationEnabled =
                isCompatChangeEnabled(OVERRIDE_UNDEFINED_ORIENTATION_TO_PORTRAIT);
@@ -1109,7 +1125,8 @@ final class LetterboxUiController {
    }

    boolean shouldApplyUserMinAspectRatioOverride() {
        if (!mLetterboxConfiguration.isUserAppAspectRatioSettingsEnabled()
        if (FALSE.equals(mBooleanPropertyAllowUserAspectRatioOverride)
                || !mLetterboxConfiguration.isUserAppAspectRatioSettingsEnabled()
                || mActivityRecord.mDisplayContent == null
                || !mActivityRecord.mDisplayContent.getIgnoreOrientationRequest()) {
            return false;
@@ -1122,7 +1139,9 @@ final class LetterboxUiController {
    }

    boolean shouldApplyUserFullscreenOverride() {
        if (!mLetterboxConfiguration.isUserAppAspectRatioFullscreenEnabled()
        if (FALSE.equals(mBooleanPropertyAllowUserAspectRatioOverride)
                || FALSE.equals(mBooleanPropertyAllowUserAspectRatioFullscreenOverride)
                || !mLetterboxConfiguration.isUserAppAspectRatioFullscreenEnabled()
                || mActivityRecord.mDisplayContent == null
                || !mActivityRecord.mDisplayContent.getIgnoreOrientationRequest()) {
            return false;
@@ -1151,7 +1170,8 @@ final class LetterboxUiController {
        }
    }

    private int getUserMinAspectRatioOverrideCode() {
    @VisibleForTesting
    int getUserMinAspectRatioOverrideCode() {
        try {
            return mActivityRecord.mAtmService.getPackageManager()
                    .getUserMinAspectRatio(mActivityRecord.packageName, mActivityRecord.mUserId);
+106 −0
Original line number Diff line number Diff line
@@ -37,6 +37,8 @@ import static android.content.pm.ActivityInfo.SCREEN_ORIENTATION_PORTRAIT;
import static android.content.pm.ActivityInfo.SCREEN_ORIENTATION_REVERSE_LANDSCAPE;
import static android.content.pm.ActivityInfo.SCREEN_ORIENTATION_UNSPECIFIED;
import static android.content.pm.ActivityInfo.SCREEN_ORIENTATION_USER;
import static android.content.pm.PackageManager.USER_MIN_ASPECT_RATIO_3_2;
import static android.content.pm.PackageManager.USER_MIN_ASPECT_RATIO_FULLSCREEN;
import static android.content.res.Configuration.ORIENTATION_LANDSCAPE;
import static android.content.res.Configuration.ORIENTATION_PORTRAIT;
import static android.view.InsetsSource.FLAG_INSETS_ROUNDED_CORNER;
@@ -48,6 +50,8 @@ import static android.view.WindowManager.PROPERTY_COMPAT_ALLOW_IGNORING_ORIENTAT
import static android.view.WindowManager.PROPERTY_COMPAT_ALLOW_MIN_ASPECT_RATIO_OVERRIDE;
import static android.view.WindowManager.PROPERTY_COMPAT_ALLOW_ORIENTATION_OVERRIDE;
import static android.view.WindowManager.PROPERTY_COMPAT_ALLOW_RESIZEABLE_ACTIVITY_OVERRIDES;
import static android.view.WindowManager.PROPERTY_COMPAT_ALLOW_USER_ASPECT_RATIO_FULLSCREEN_OVERRIDE;
import static android.view.WindowManager.PROPERTY_COMPAT_ALLOW_USER_ASPECT_RATIO_OVERRIDE;
import static android.view.WindowManager.PROPERTY_COMPAT_ENABLE_FAKE_FOCUS;
import static android.view.WindowManager.PROPERTY_COMPAT_IGNORE_REQUESTED_ORIENTATION;

@@ -807,6 +811,108 @@ public class LetterboxUiControllerTest extends WindowTestsBase {
                /* candidate */ SCREEN_ORIENTATION_PORTRAIT), SCREEN_ORIENTATION_PORTRAIT);
    }

    // shouldApplyUser...Override
    @Test
    public void testShouldApplyUserFullscreenOverride_trueProperty_returnsFalse() throws Exception {
        mockThatProperty(PROPERTY_COMPAT_ALLOW_USER_ASPECT_RATIO_FULLSCREEN_OVERRIDE,
                /* value */ true);

        mController = new LetterboxUiController(mWm, mActivity);
        doReturn(false).when(mLetterboxConfiguration).isUserAppAspectRatioFullscreenEnabled();

        assertFalse(mController.shouldApplyUserFullscreenOverride());
    }

    @Test
    public void testShouldApplyUserFullscreenOverride_falseFullscreenProperty_returnsFalse()
            throws Exception {
        prepareActivityThatShouldApplyUserFullscreenOverride();
        mockThatProperty(PROPERTY_COMPAT_ALLOW_USER_ASPECT_RATIO_FULLSCREEN_OVERRIDE,
                /* value */ false);

        mController = new LetterboxUiController(mWm, mActivity);

        assertFalse(mController.shouldApplyUserFullscreenOverride());
    }

    @Test
    public void testShouldApplyUserFullscreenOverride_falseSettingsProperty_returnsFalse()
            throws Exception {
        prepareActivityThatShouldApplyUserFullscreenOverride();
        mockThatProperty(PROPERTY_COMPAT_ALLOW_USER_ASPECT_RATIO_OVERRIDE, /* value */ false);

        mController = new LetterboxUiController(mWm, mActivity);

        assertFalse(mController.shouldApplyUserFullscreenOverride());
    }

    @Test
    public void testShouldApplyUserFullscreenOverride_disabledIgnoreOrientationRequest() {
        prepareActivityThatShouldApplyUserFullscreenOverride();
        mDisplayContent.setIgnoreOrientationRequest(false);

        assertFalse(mController.shouldApplyUserFullscreenOverride());
    }

    @Test
    public void testShouldApplyUserFullscreenOverride_returnsTrue() {
        prepareActivityThatShouldApplyUserFullscreenOverride();

        assertTrue(mController.shouldApplyUserFullscreenOverride());
    }

    @Test
    public void testShouldApplyUserMinAspectRatioOverride_falseProperty_returnsFalse()
            throws Exception {
        prepareActivityThatShouldApplyUserMinAspectRatioOverride();
        mockThatProperty(PROPERTY_COMPAT_ALLOW_USER_ASPECT_RATIO_OVERRIDE, /* value */ false);

        mController = new LetterboxUiController(mWm, mActivity);

        assertFalse(mController.shouldApplyUserMinAspectRatioOverride());
    }

    @Test
    public void testShouldApplyUserMinAspectRatioOverride_trueProperty_returnsFalse()
            throws Exception {
        doReturn(false).when(mLetterboxConfiguration).isUserAppAspectRatioSettingsEnabled();
        mockThatProperty(PROPERTY_COMPAT_ALLOW_USER_ASPECT_RATIO_OVERRIDE, /* value */ true);

        mController = new LetterboxUiController(mWm, mActivity);

        assertFalse(mController.shouldApplyUserMinAspectRatioOverride());
    }

    @Test
    public void testShouldApplyUserMinAspectRatioOverride_disabledIgnoreOrientationRequest() {
        prepareActivityThatShouldApplyUserMinAspectRatioOverride();
        mDisplayContent.setIgnoreOrientationRequest(false);

        assertFalse(mController.shouldApplyUserMinAspectRatioOverride());
    }

    @Test
    public void testShouldApplyUserMinAspectRatioOverride_returnsTrue() {
        prepareActivityThatShouldApplyUserMinAspectRatioOverride();

        assertTrue(mController.shouldApplyUserMinAspectRatioOverride());
    }

    private void prepareActivityThatShouldApplyUserMinAspectRatioOverride() {
        spyOn(mController);
        doReturn(true).when(mLetterboxConfiguration).isUserAppAspectRatioSettingsEnabled();
        mDisplayContent.setIgnoreOrientationRequest(true);
        doReturn(USER_MIN_ASPECT_RATIO_3_2).when(mController).getUserMinAspectRatioOverrideCode();
    }

    private void prepareActivityThatShouldApplyUserFullscreenOverride() {
        spyOn(mController);
        doReturn(true).when(mLetterboxConfiguration).isUserAppAspectRatioFullscreenEnabled();
        mDisplayContent.setIgnoreOrientationRequest(true);
        doReturn(USER_MIN_ASPECT_RATIO_FULLSCREEN).when(mController)
                .getUserMinAspectRatioOverrideCode();
    }

    // shouldUseDisplayLandscapeNaturalOrientation

    @Test