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

Commit 72b8801b authored by tomnatan's avatar tomnatan
Browse files

[2/n] Letterbox Education: Add information about fixed orientation letterbox to TaskInfo

Bug: 207010227
Test: atest WmTests:ActivityRecordTests
Test: atest WmTests:SizeCompatTests
Test: atest WMShellUnitTests:ShellTaskOrganizerTests
Change-Id: I04e82eb494c84bd78c269dd244bdd4a3e4d5fcc8
parent d95703d1
Loading
Loading
Loading
Loading
+14 −1
Original line number Diff line number Diff line
@@ -213,6 +213,12 @@ public class TaskInfo {
     */
    public boolean topActivityInSizeCompat;

    /**
     * Whether the direct top activity is eligible for letterbox education.
     * @hide
     */
    public boolean topActivityEligibleForLetterboxEducation;

    /**
     * Whether this task is resizable. Unlike {@link #resizeMode} (which is what the top activity
     * supports), this is what the system actually uses for resizability based on other policy and
@@ -398,7 +404,8 @@ public class TaskInfo {

    /** @hide */
    public boolean hasCompatUI() {
        return hasCameraCompatControl() || topActivityInSizeCompat;
        return hasCameraCompatControl() || topActivityInSizeCompat
                || topActivityEligibleForLetterboxEducation;
    }

    /**
@@ -460,6 +467,8 @@ public class TaskInfo {
        return displayId == that.displayId
                && taskId == that.taskId
                && topActivityInSizeCompat == that.topActivityInSizeCompat
                && topActivityEligibleForLetterboxEducation
                    == that.topActivityEligibleForLetterboxEducation
                && cameraCompatControlState == that.cameraCompatControlState
                // Bounds are important if top activity has compat controls.
                && (!hasCompatUI() || configuration.windowConfiguration.getBounds()
@@ -507,6 +516,7 @@ public class TaskInfo {
        isVisible = source.readBoolean();
        isSleeping = source.readBoolean();
        topActivityInSizeCompat = source.readBoolean();
        topActivityEligibleForLetterboxEducation = source.readBoolean();
        mTopActivityLocusId = source.readTypedObject(LocusId.CREATOR);
        displayAreaFeatureId = source.readInt();
        cameraCompatControlState = source.readInt();
@@ -551,6 +561,7 @@ public class TaskInfo {
        dest.writeBoolean(isVisible);
        dest.writeBoolean(isSleeping);
        dest.writeBoolean(topActivityInSizeCompat);
        dest.writeBoolean(topActivityEligibleForLetterboxEducation);
        dest.writeTypedObject(mTopActivityLocusId, flags);
        dest.writeInt(displayAreaFeatureId);
        dest.writeInt(cameraCompatControlState);
@@ -585,6 +596,8 @@ public class TaskInfo {
                + " isVisible=" + isVisible
                + " isSleeping=" + isSleeping
                + " topActivityInSizeCompat=" + topActivityInSizeCompat
                + " topActivityEligibleForLetterboxEducation= "
                        + topActivityEligibleForLetterboxEducation
                + " locusId=" + mTopActivityLocusId
                + " displayAreaFeatureId=" + displayAreaFeatureId
                + " cameraCompatControlState="
+3 −0
Original line number Diff line number Diff line
@@ -5134,6 +5134,9 @@
        If given value is outside of this range, the option 1 (center) is assummed. -->
    <integer name="config_letterboxDefaultPositionForReachability">1</integer>

    <!-- Whether displaying letterbox education is enabled for letterboxed fullscreen apps. -->
    <bool name="config_letterboxIsEducationEnabled">false</bool>

    <!-- Whether a camera compat controller is enabled to allow the user to apply or revert
         treatment for stretched issues in camera viewfinder. -->
    <bool name="config_isCameraCompatControlForStretchedIssuesEnabled">false</bool>
+1 −0
Original line number Diff line number Diff line
@@ -4323,6 +4323,7 @@
  <java-symbol type="dimen" name="config_letterboxHorizontalPositionMultiplier" />
  <java-symbol type="bool" name="config_letterboxIsReachabilityEnabled" />
  <java-symbol type="integer" name="config_letterboxDefaultPositionForReachability" />
  <java-symbol type="bool" name="config_letterboxIsEducationEnabled" />
  <java-symbol type="bool" name="config_isCameraCompatControlForStretchedIssuesEnabled" />

  <java-symbol type="bool" name="config_hideDisplayCutoutWithDisplayArea" />
+40 −1
Original line number Diff line number Diff line
@@ -362,6 +362,45 @@ public class ShellTaskOrganizerTests {
        verify(mCompatUI).onCompatInfoChanged(taskInfo1, null /* taskListener */);
    }

    @Test
    public void testOnEligibleForLetterboxEducationActivityChanged() {
        final RunningTaskInfo taskInfo1 = createTaskInfo(12, WINDOWING_MODE_FULLSCREEN);
        taskInfo1.displayId = DEFAULT_DISPLAY;
        taskInfo1.topActivityEligibleForLetterboxEducation = false;
        final TrackingTaskListener taskListener = new TrackingTaskListener();
        mOrganizer.addListenerForType(taskListener, TASK_LISTENER_TYPE_FULLSCREEN);
        mOrganizer.onTaskAppeared(taskInfo1, null);

        // Task listener sent to compat UI is null if top activity isn't eligible for letterbox
        // education.
        verify(mCompatUI).onCompatInfoChanged(taskInfo1, null /* taskListener */);

        // Task listener is non-null if top activity is eligible for letterbox education and task
        // is visible.
        clearInvocations(mCompatUI);
        final RunningTaskInfo taskInfo2 =
                createTaskInfo(taskInfo1.taskId, WINDOWING_MODE_FULLSCREEN);
        taskInfo2.displayId = taskInfo1.displayId;
        taskInfo2.topActivityEligibleForLetterboxEducation = true;
        taskInfo2.isVisible = true;
        mOrganizer.onTaskInfoChanged(taskInfo2);
        verify(mCompatUI).onCompatInfoChanged(taskInfo2, taskListener);

        // Task listener is null if task is invisible.
        clearInvocations(mCompatUI);
        final RunningTaskInfo taskInfo3 =
                createTaskInfo(taskInfo1.taskId, WINDOWING_MODE_FULLSCREEN);
        taskInfo3.displayId = taskInfo1.displayId;
        taskInfo3.topActivityEligibleForLetterboxEducation = true;
        taskInfo3.isVisible = false;
        mOrganizer.onTaskInfoChanged(taskInfo3);
        verify(mCompatUI).onCompatInfoChanged(taskInfo3, null /* taskListener */);

        clearInvocations(mCompatUI);
        mOrganizer.onTaskVanished(taskInfo1);
        verify(mCompatUI).onCompatInfoChanged(taskInfo1, null /* taskListener */);
    }

    @Test
    public void testOnCameraCompatActivityChanged() {
        final RunningTaskInfo taskInfo1 = createTaskInfo(1, WINDOWING_MODE_FULLSCREEN);
@@ -375,7 +414,7 @@ public class ShellTaskOrganizerTests {
        // compat control.
        verify(mCompatUI).onCompatInfoChanged(taskInfo1, null /* taskListener */);

        // Task linster is non-null when request a camera compat control for a visible task.
        // Task listener is non-null when request a camera compat control for a visible task.
        clearInvocations(mCompatUI);
        final RunningTaskInfo taskInfo2 =
                createTaskInfo(taskInfo1.taskId, taskInfo1.getWindowingMode());
+29 −2
Original line number Diff line number Diff line
@@ -715,6 +715,11 @@ final class ActivityRecord extends WindowToken implements WindowManagerService.A
    @Nullable
    private Rect mLetterboxBoundsForFixedOrientationAndAspectRatio;

    // Whether the activity is eligible to be letterboxed for fixed orientation with respect to its
    // requested orientation, even when it's letterbox for another reason (e.g., size compat mode)
    // and therefore #isLetterboxedForFixedOrientationAndAspectRatio returns false.
    private boolean mIsEligibleForFixedOrientationLetterbox;

    // State of the Camera app compat control which is used to correct stretched viewfinder
    // in apps that don't handle all possible configurations and changes between them correctly.
    @CameraCompatControlState
@@ -7616,6 +7621,24 @@ final class ActivityRecord extends WindowToken implements WindowManagerService.A
        return mLetterboxBoundsForFixedOrientationAndAspectRatio != null;
    }

    /**
     * Whether this activity is eligible for letterbox eduction.
     *
     * <p>Conditions that need to be met:
     *
     * <ul>
     *     <li>{@link LetterboxConfiguration#getIsEducationEnabled} is true.
     *     <li>The activity is eligible for fixed orientation letterbox.
     *     <li>The activity is in fullscreen.
     * </ul>
     */
    // TODO(b/215316431): Add tests
    boolean isEligibleForLetterboxEducation() {
        return mWmService.mLetterboxConfiguration.getIsEducationEnabled()
                && mIsEligibleForFixedOrientationLetterbox
                && getWindowingMode() == WINDOWING_MODE_FULLSCREEN;
    }

    /**
     * In some cases, applying insets to bounds changes the orientation. For example, if a
     * close-to-square display rotates to portrait to respect a portrait orientation activity, after
@@ -7678,6 +7701,7 @@ final class ActivityRecord extends WindowToken implements WindowManagerService.A
    private void resolveFixedOrientationConfiguration(@NonNull Configuration newParentConfig,
            int windowingMode) {
        mLetterboxBoundsForFixedOrientationAndAspectRatio = null;
        mIsEligibleForFixedOrientationLetterbox = false;
        final Rect parentBounds = newParentConfig.windowConfiguration.getBounds();
        final Rect stableBounds = new Rect();
        // If orientation is respected when insets are applied, then stableBounds will be empty.
@@ -7717,8 +7741,11 @@ final class ActivityRecord extends WindowToken implements WindowManagerService.A
        // make it fit the available bounds by scaling down its bounds.
        final int forcedOrientation = getRequestedConfigurationOrientation();

        if (forcedOrientation == ORIENTATION_UNDEFINED
                || (forcedOrientation == parentOrientation && orientationRespectedWithInsets)) {
        mIsEligibleForFixedOrientationLetterbox = forcedOrientation != ORIENTATION_UNDEFINED
                && forcedOrientation != parentOrientation;

        if (!mIsEligibleForFixedOrientationLetterbox && (forcedOrientation == ORIENTATION_UNDEFINED
                || orientationRespectedWithInsets)) {
            return;
        }

Loading