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

Commit 5e5a68dc authored by Wale Ogunwale's avatar Wale Ogunwale
Browse files

Fixed issue with SCREEN_ORIENTATION_BEHIND not working correctly

If an app specifies SCREEN_ORIENTATION_BEHIND, then use the orientation
of the app behind it regardless of the visibility state of the app
behind.

Fixes: 35281868
Test: bit FrameworksServicesTests:com.android.server.wm.WindowContainerTests
Test: bit FrameworksServicesTests:com.android.server.wm.AppWindowTokenTests
Test: bit FrameworksServicesTests:com.android.server.wm.TaskStackTests
Change-Id: Ieba4e4bb1a7f47cd6f082491d37fcabcf5bd5199
parent a56d9a18
Loading
Loading
Loading
Loading
+15 −3
Original line number Diff line number Diff line
@@ -19,6 +19,7 @@ package com.android.server.wm;
import static android.app.ActivityManager.StackId;
import static android.content.pm.ActivityInfo.CONFIG_ORIENTATION;
import static android.content.pm.ActivityInfo.CONFIG_SCREEN_SIZE;
import static android.content.pm.ActivityInfo.SCREEN_ORIENTATION_BEHIND;
import static android.content.pm.ActivityInfo.SCREEN_ORIENTATION_UNSET;
import static android.view.Display.DEFAULT_DISPLAY;
import static android.view.WindowManager.LayoutParams.FLAG_DISMISS_KEYGUARD;
@@ -1204,12 +1205,23 @@ class AppWindowToken extends WindowToken implements WindowManagerService.AppFree
     * in anyway.
     */
    @Override
    int getOrientation() {
    int getOrientation(int candidate) {
        if (!fillsParent()) {
            // Can't specify orientation if app doesn't fill parent.
            return SCREEN_ORIENTATION_UNSET;
        }

        if (candidate == SCREEN_ORIENTATION_BEHIND) {
            // Allow app to specify orientation regardless of its visibility state if the current
            // candidate want us to use orientation behind. I.e. the visible app on-top of this one
            // wants us to use the orientation of the app behind it.
            return mOrientation;
        }

        // The {@link AppWindowToken} should only specify an orientation when it is not closing or
        // going to the bottom. Allowing closing {@link AppWindowToken} to participate can lead to
        // an Activity in another task being started in the wrong orientation during the transition.
        if (fillsParent()
                && !(sendingToBottom || mService.mClosingApps.contains(this))
        if (!(sendingToBottom || mService.mClosingApps.contains(this))
                && (isVisible() || mService.mOpeningApps.contains(this))) {
            return mOrientation;
        }
+13 −3
Original line number Diff line number Diff line
@@ -516,14 +516,22 @@ class WindowContainer<E extends WindowContainer> implements Comparable<WindowCon
        mOrientation = orientation;
    }

    int getOrientation() {
        return getOrientation(mOrientation);
    }

    /**
     * Returns the specified orientation for this window container or one of its children is there
     * is one set, or {@link android.content.pm.ActivityInfo#SCREEN_ORIENTATION_UNSET} if no
     * specification is set.
     * NOTE: {@link android.content.pm.ActivityInfo#SCREEN_ORIENTATION_UNSPECIFIED} is a
     * specification...
     *
     * @param candidate The current orientation candidate that will be returned if we don't find a
     *                  better match.
     * @return The orientation as specified by this branch or the window hierarchy.
     */
    int getOrientation() {
    int getOrientation(int candidate) {
        if (!fillsParent()) {
            // Ignore containers that don't completely fill their parents.
            return SCREEN_ORIENTATION_UNSET;
@@ -537,12 +545,14 @@ class WindowContainer<E extends WindowContainer> implements Comparable<WindowCon
                && mOrientation != SCREEN_ORIENTATION_UNSPECIFIED) {
            return mOrientation;
        }
        int candidate = mOrientation;

        for (int i = mChildren.size() - 1; i >= 0; --i) {
            final WindowContainer wc = mChildren.get(i);

            final int orientation = wc.getOrientation();
            // TODO: Maybe mOrientation should default to SCREEN_ORIENTATION_UNSET vs.
            // SCREEN_ORIENTATION_UNSPECIFIED?
            final int orientation = wc.getOrientation(candidate == SCREEN_ORIENTATION_BEHIND
                    ? SCREEN_ORIENTATION_BEHIND : SCREEN_ORIENTATION_UNSET);
            if (orientation == SCREEN_ORIENTATION_BEHIND) {
                // container wants us to use the orientation of the container behind it. See if we
                // can find one. Else return SCREEN_ORIENTATION_BEHIND so the caller can choose to
+20 −0
Original line number Diff line number Diff line
@@ -26,8 +26,10 @@ import android.support.test.runner.AndroidJUnit4;
import android.view.Surface;
import android.view.WindowManager;

import static android.content.pm.ActivityInfo.SCREEN_ORIENTATION_BEHIND;
import static android.content.pm.ActivityInfo.SCREEN_ORIENTATION_LANDSCAPE;
import static android.content.pm.ActivityInfo.SCREEN_ORIENTATION_REVERSE_LANDSCAPE;
import static android.content.pm.ActivityInfo.SCREEN_ORIENTATION_UNSET;
import static android.view.WindowManager.LayoutParams.FIRST_SUB_WINDOW;
import static android.view.WindowManager.LayoutParams.TYPE_APPLICATION;
import static android.view.WindowManager.LayoutParams.TYPE_APPLICATION_STARTING;
@@ -160,4 +162,22 @@ public class AppWindowTokenTests extends WindowTestsBase {
        sWm.mRoot.mOrientationChangeComplete = true;
        sWm.mRoot.performSurfacePlacement(false /* recoveringMemory */);
    }

    @Test
    public void testGetOrientation() throws Exception {
        final TestAppWindowToken token = new TestAppWindowToken(sDisplayContent);
        token.setOrientation(SCREEN_ORIENTATION_LANDSCAPE);

        token.setFillsParent(false);
        // Can not specify orientation if app doesn't fill parent.
        assertEquals(SCREEN_ORIENTATION_UNSET, token.getOrientation());

        token.setFillsParent(true);
        token.hidden = true;
        token.sendingToBottom = true;
        // Can not specify orientation if app isn't visible even though it fills parent.
        assertEquals(SCREEN_ORIENTATION_UNSET, token.getOrientation());
        // Can specify orientation if the current orientation candidate is orientation behind.
        assertEquals(SCREEN_ORIENTATION_LANDSCAPE, token.getOrientation(SCREEN_ORIENTATION_BEHIND));
    }
}
+4 −4
Original line number Diff line number Diff line
@@ -76,9 +76,9 @@ public class TaskStackTests extends WindowTestsBase {
        task2.addChild(appWindowToken2, 0);
        appWindowToken2.setOrientation(SCREEN_ORIENTATION_PORTRAIT);

        assertEquals(stack.getOrientation(), SCREEN_ORIENTATION_PORTRAIT);
        assertEquals(SCREEN_ORIENTATION_PORTRAIT, stack.getOrientation());
        sWm.mClosingApps.add(appWindowToken2);
        assertEquals(stack.getOrientation(), SCREEN_ORIENTATION_LANDSCAPE);
        assertEquals(SCREEN_ORIENTATION_LANDSCAPE, stack.getOrientation());
    }

    @Test
@@ -94,9 +94,9 @@ public class TaskStackTests extends WindowTestsBase {
        task2.addChild(appWindowToken2, 0);
        appWindowToken2.setOrientation(SCREEN_ORIENTATION_PORTRAIT);

        assertEquals(stack.getOrientation(), SCREEN_ORIENTATION_PORTRAIT);
        assertEquals(SCREEN_ORIENTATION_PORTRAIT, stack.getOrientation());
        task2.setSendingToBottom(true);
        assertEquals(stack.getOrientation(), SCREEN_ORIENTATION_LANDSCAPE);
        assertEquals(SCREEN_ORIENTATION_LANDSCAPE, stack.getOrientation());
    }

    @Test
+7 −2
Original line number Diff line number Diff line
@@ -422,7 +422,7 @@ public class WindowContainerTests extends WindowTestsBase {
        final TestWindowContainer child1 = root.addChildWindow(builder);
        child1.setFillsParent(true);

        assertTrue(root.getOrientation() == expectedOrientation);
        assertEquals(expectedOrientation, root.getOrientation());
    }

    @Test
@@ -804,9 +804,14 @@ public class WindowContainerTests extends WindowTestsBase {
            return mIsVisible;
        }

        @Override
        int getOrientation(int candidate) {
            return mOrientation != null ? mOrientation : super.getOrientation(candidate);
        }

        @Override
        int getOrientation() {
            return mOrientation != null ? mOrientation : super.getOrientation();
            return getOrientation(super.mOrientation);
        }

        @Override