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

Commit 14d9c501 authored by Chris Li's avatar Chris Li Committed by Android (Google) Code Review
Browse files

Merge "Add option to always ignore orientation request"

parents 97cf6692 3dbefb99
Loading
Loading
Loading
Loading
+35 −0
Original line number Diff line number Diff line
@@ -237,6 +237,22 @@ public final class WindowContainerTransaction implements Parcelable {
        return this;
    }

    /**
     * Sets whether a container should ignore the orientation request from apps below it. It
     * currently only applies to {@link com.android.server.wm.TaskDisplayArea}. When {@code false},
     * it may rotate based on the orientation request; When {@code true}, it can never specify
     * orientation, but shows the fixed-orientation apps in the letterbox.
     * @hide
     */
    @NonNull
    public WindowContainerTransaction setIgnoreOrientationRequest(
            @NonNull WindowContainerToken container, boolean ignoreOrientationRequest) {
        Change chg = getOrCreateChange(container.asBinder());
        chg.mIgnoreOrientationRequest = ignoreOrientationRequest;
        chg.mChangeMask |= Change.CHANGE_IGNORE_ORIENTATION_REQUEST;
        return this;
    }

    /**
     * Reparents a container into another one. The effect of a {@code null} parent can vary. For
     * example, reparenting a stack to {@code null} will reparent it to its display.
@@ -341,10 +357,12 @@ public final class WindowContainerTransaction implements Parcelable {
        public static final int CHANGE_PIP_CALLBACK = 1 << 2;
        public static final int CHANGE_HIDDEN = 1 << 3;
        public static final int CHANGE_BOUNDS_TRANSACTION_RECT = 1 << 4;
        public static final int CHANGE_IGNORE_ORIENTATION_REQUEST = 1 << 5;

        private final Configuration mConfiguration = new Configuration();
        private boolean mFocusable = true;
        private boolean mHidden = false;
        private boolean mIgnoreOrientationRequest = false;
        private int mChangeMask = 0;
        private @ActivityInfo.Config int mConfigSetMask = 0;
        private @WindowConfiguration.WindowConfig int mWindowSetMask = 0;
@@ -362,6 +380,7 @@ public final class WindowContainerTransaction implements Parcelable {
            mConfiguration.readFromParcel(in);
            mFocusable = in.readBoolean();
            mHidden = in.readBoolean();
            mIgnoreOrientationRequest = in.readBoolean();
            mChangeMask = in.readInt();
            mConfigSetMask = in.readInt();
            mWindowSetMask = in.readInt();
@@ -404,6 +423,9 @@ public final class WindowContainerTransaction implements Parcelable {
            if ((other.mChangeMask & CHANGE_HIDDEN) != 0) {
                mHidden = other.mHidden;
            }
            if ((other.mChangeMask & CHANGE_IGNORE_ORIENTATION_REQUEST) != 0) {
                mIgnoreOrientationRequest = other.mIgnoreOrientationRequest;
            }
            mChangeMask |= other.mChangeMask;
            if (other.mActivityWindowingMode >= 0) {
                mActivityWindowingMode = other.mActivityWindowingMode;
@@ -445,6 +467,15 @@ public final class WindowContainerTransaction implements Parcelable {
            return mHidden;
        }

        /** Gets the requested state of whether to ignore orientation request. */
        public boolean getIgnoreOrientationRequest() {
            if ((mChangeMask & CHANGE_IGNORE_ORIENTATION_REQUEST) == 0) {
                throw new RuntimeException("IgnoreOrientationRequest not set. "
                        + "Check CHANGE_IGNORE_ORIENTATION_REQUEST first");
            }
            return mIgnoreOrientationRequest;
        }

        public int getChangeMask() {
            return mChangeMask;
        }
@@ -509,6 +540,9 @@ public final class WindowContainerTransaction implements Parcelable {
            if (mBoundsChangeTransaction != null) {
                sb.append("hasBoundsTransaction,");
            }
            if ((mChangeMask & CHANGE_IGNORE_ORIENTATION_REQUEST) != 0) {
                sb.append("ignoreOrientationRequest:" + mIgnoreOrientationRequest + ",");
            }
            sb.append("}");
            return sb.toString();
        }
@@ -518,6 +552,7 @@ public final class WindowContainerTransaction implements Parcelable {
            mConfiguration.writeToParcel(dest, flags);
            dest.writeBoolean(mFocusable);
            dest.writeBoolean(mHidden);
            dest.writeBoolean(mIgnoreOrientationRequest);
            dest.writeInt(mChangeMask);
            dest.writeInt(mConfigSetMask);
            dest.writeInt(mWindowSetMask);
+28 −3
Original line number Diff line number Diff line
@@ -151,6 +151,12 @@ final class TaskDisplayArea extends DisplayArea<Task> {
     */
    private boolean mRemoved;

    /**
     * Whether the task display area should ignore fixed-orientation request. If {@code true}, it
     * can never specify orientation, but show the fixed-orientation apps in the letterbox;
     * otherwise, it rotates based on the fixed-orientation request when it has the focus.
     */
    private boolean mIgnoreOrientationRequest;

    /**
     * The id of a leaf task that most recently being moved to front.
@@ -641,11 +647,30 @@ final class TaskDisplayArea extends DisplayArea<Task> {
        }
    }

    /**
     * Sets whether the task display area should ignore fixed-orientation request from apps.
     * @return Whether the display orientation changed
     */
    boolean setIgnoreOrientationRequest(boolean ignoreOrientationRequest) {
        if (mIgnoreOrientationRequest == ignoreOrientationRequest) {
            return false;
        }

        mIgnoreOrientationRequest = ignoreOrientationRequest;
        if (isLastFocused()) {
            // Update orientation if this TDA is the last focused, otherwise it shouldn't affect
            // the display.
            return mDisplayContent.updateOrientation();
        }

        return false;
    }

    @Override
    int getOrientation(int candidate) {
        // Only allow to specify orientation if this TDA has the focus.
        // TODO(b/155431879) Add option to never allow a TDA to specify orientation.
        if (!isLastFocused()) {
        // Only allow to specify orientation if this TDA is not set to ignore orientation request,
        // and it has the focus.
        if (mIgnoreOrientationRequest || !isLastFocused()) {
            return SCREEN_ORIENTATION_UNSET;
        }

+16 −1
Original line number Diff line number Diff line
@@ -306,6 +306,19 @@ class WindowOrganizerController extends IWindowOrganizerController.Stub
        return effects;
    }

    private int applyTaskDisplayAreaChanges(TaskDisplayArea taskDisplayArea,
            WindowContainerTransaction.Change c) {
        int effects = applyDisplayAreaChanges(taskDisplayArea, c);
        if ((c.getChangeMask()
                & WindowContainerTransaction.Change.CHANGE_IGNORE_ORIENTATION_REQUEST) != 0) {
            if (taskDisplayArea.setIgnoreOrientationRequest(c.getIgnoreOrientationRequest())) {
                effects |= TRANSACT_EFFECTS_LIFECYCLE;
            }
        }

        return effects;
    }

    private int applyDisplayAreaChanges(WindowContainer container,
            WindowContainerTransaction.Change c) {
        final int[] effects = new int[1];
@@ -388,7 +401,9 @@ class WindowOrganizerController extends IWindowOrganizerController.Stub

        int effects = applyChanges(wc, c);

        if (wc instanceof DisplayArea) {
        if (wc instanceof TaskDisplayArea) {
            effects |= applyTaskDisplayAreaChanges((TaskDisplayArea) wc, c);
        } else if (wc instanceof DisplayArea) {
            effects |= applyDisplayAreaChanges(wc, c);
        } else if (wc instanceof Task) {
            effects |= applyTaskChanges(wc.asTask(), c);
+20 −0
Original line number Diff line number Diff line
@@ -29,6 +29,8 @@ import static android.app.WindowConfiguration.WINDOWING_MODE_SPLIT_SCREEN_PRIMAR
import static android.app.WindowConfiguration.WINDOWING_MODE_SPLIT_SCREEN_SECONDARY;
import static android.app.WindowConfiguration.WINDOWING_MODE_UNDEFINED;
import static android.content.pm.ActivityInfo.RESIZE_MODE_UNRESIZEABLE;
import static android.content.pm.ActivityInfo.SCREEN_ORIENTATION_LANDSCAPE;
import static android.content.pm.ActivityInfo.SCREEN_ORIENTATION_UNSET;
import static android.window.DisplayAreaOrganizer.FEATURE_VENDOR_FIRST;

import static com.android.dx.mockito.inline.extended.ExtendedMockito.doReturn;
@@ -277,6 +279,24 @@ public class TaskDisplayAreaTests extends WindowTestsBase {
        assertThat(secondTaskDisplayArea.isLastFocused()).isTrue();
    }

    @Test
    public void testIgnoreOrientationRequest() {
        final TaskDisplayArea taskDisplayArea = mDisplayContent.getDefaultTaskDisplayArea();
        final Task stack = taskDisplayArea.createStack(
                WINDOWING_MODE_FULLSCREEN, ACTIVITY_TYPE_STANDARD, false /* onTop */);
        final ActivityRecord activity = new ActivityBuilder(mAtm).setCreateTask(true)
                .setStack(stack).build();

        mDisplayContent.setFocusedApp(activity);
        activity.setRequestedOrientation(SCREEN_ORIENTATION_LANDSCAPE);

        assertThat(taskDisplayArea.getOrientation()).isEqualTo(SCREEN_ORIENTATION_LANDSCAPE);

        taskDisplayArea.setIgnoreOrientationRequest(true /* ignoreOrientationRequest */);

        assertThat(taskDisplayArea.getOrientation()).isEqualTo(SCREEN_ORIENTATION_UNSET);
    }

    private void assertGetOrCreateStack(int windowingMode, int activityType, Task candidateTask,
            boolean reuseCandidate) {
        final TaskDisplayArea taskDisplayArea = candidateTask.getDisplayArea();
+44 −0
Original line number Diff line number Diff line
@@ -26,6 +26,9 @@ import static android.app.WindowConfiguration.WINDOWING_MODE_PINNED;
import static android.app.WindowConfiguration.WINDOWING_MODE_SPLIT_SCREEN_PRIMARY;
import static android.app.WindowConfiguration.WINDOWING_MODE_SPLIT_SCREEN_SECONDARY;
import static android.app.WindowConfiguration.WINDOWING_MODE_UNDEFINED;
import static android.content.pm.ActivityInfo.SCREEN_ORIENTATION_LANDSCAPE;
import static android.content.pm.ActivityInfo.SCREEN_ORIENTATION_UNSET;
import static android.content.pm.ActivityInfo.SCREEN_ORIENTATION_UNSPECIFIED;
import static android.content.res.Configuration.SCREEN_HEIGHT_DP_UNDEFINED;
import static android.content.res.Configuration.SCREEN_WIDTH_DP_UNDEFINED;
import static android.view.WindowManager.LayoutParams.TYPE_APPLICATION;
@@ -42,6 +45,8 @@ import static com.android.dx.mockito.inline.extended.ExtendedMockito.when;
import static com.android.server.wm.DisplayArea.Type.ABOVE_TASKS;
import static com.android.server.wm.WindowContainer.POSITION_TOP;

import static com.google.common.truth.Truth.assertThat;

import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertFalse;
import static org.junit.Assert.assertNotNull;
@@ -360,6 +365,45 @@ public class WindowOrganizerTests extends WindowTestsBase {
        assertTrue(stack.shouldBeVisible(null));
    }

    @Test
    public void testSetIgnoreOrientationRequest() {
        removeGlobalMinSizeRestriction();
        final TaskDisplayArea taskDisplayArea = mDisplayContent.getDefaultTaskDisplayArea();
        final Task stack = taskDisplayArea.createStack(
                WINDOWING_MODE_FULLSCREEN, ACTIVITY_TYPE_STANDARD, false /* onTop */);
        final ActivityRecord activity = new ActivityBuilder(mAtm).setCreateTask(true)
                .setStack(stack).build();
        taskDisplayArea.setIgnoreOrientationRequest(true /* ignoreOrientationRequest */);
        mDisplayContent.setFocusedApp(activity);
        activity.setRequestedOrientation(SCREEN_ORIENTATION_LANDSCAPE);

        // TDA returns UNSET when ignoreOrientationRequest == true
        // DC is UNSPECIFIED because it is using the previous (default) when TDA returns UNSET.
        assertThat(taskDisplayArea.getOrientation()).isEqualTo(SCREEN_ORIENTATION_UNSET);
        assertThat(mDisplayContent.getLastOrientation()).isEqualTo(SCREEN_ORIENTATION_UNSPECIFIED);

        WindowContainerTransaction t = new WindowContainerTransaction();
        t.setIgnoreOrientationRequest(
                taskDisplayArea.mRemoteToken.toWindowContainerToken(),
                false /* ignoreOrientationRequest */);
        mWm.mAtmService.mWindowOrganizerController.applyTransaction(t);

        // TDA returns app request orientation when ignoreOrientationRequest == false
        // DC uses the same as TDA returns when it is not UNSET.
        assertThat(mDisplayContent.getLastOrientation()).isEqualTo(SCREEN_ORIENTATION_LANDSCAPE);
        assertThat(taskDisplayArea.getOrientation()).isEqualTo(SCREEN_ORIENTATION_LANDSCAPE);

        t.setIgnoreOrientationRequest(
                taskDisplayArea.mRemoteToken.toWindowContainerToken(),
                true /* ignoreOrientationRequest */);
        mWm.mAtmService.mWindowOrganizerController.applyTransaction(t);

        // TDA returns UNSET when ignoreOrientationRequest == true
        // DC is LANDSCAPE because it is using the previous when TDA returns UNSET.
        assertThat(taskDisplayArea.getOrientation()).isEqualTo(SCREEN_ORIENTATION_UNSET);
        assertThat(mDisplayContent.getLastOrientation()).isEqualTo(SCREEN_ORIENTATION_LANDSCAPE);
    }

    @Test
    public void testOverrideConfigSize() {
        removeGlobalMinSizeRestriction();