Ignore orientation from invisible non-activity window

This restores the orientation condition as in Q. Otherwise the
display orientation may still be controlled by an invisible
overlay window (e.g. its root view has set View.GONE) .

Bug: 169468732
Test: DisplayAreaTest#testGetOrientation
Change-Id: I517be9fb135eeb69722054e6191ef500f2f47da9
Merged-In: I517be9fb135eeb69722054e6191ef500f2f47da9
(cherry picked from commit 4136db264624a343d92c818efb8453a2a5f0852a)
diff --git a/services/core/java/com/android/server/wm/DisplayArea.java b/services/core/java/com/android/server/wm/DisplayArea.java
index 2be3acc..fa2a42e 100644
--- a/services/core/java/com/android/server/wm/DisplayArea.java
+++ b/services/core/java/com/android/server/wm/DisplayArea.java
@@ -200,6 +200,9 @@
                 Comparator.comparingInt(WindowToken::getWindowLayerFromType);
 
         private final Predicate<WindowState> mGetOrientingWindow = w -> {
+            if (!w.isVisible() || !w.mLegacyPolicyVisibilityAfterAnim) {
+                return false;
+            }
             final WindowManagerPolicy policy = mWmService.mPolicy;
             if (policy.isKeyguardHostWindow(w.mAttrs)) {
                 if (mWmService.mKeyguardGoingAway) {
@@ -235,6 +238,7 @@
 
         @Override
         int getOrientation(int candidate) {
+            mLastOrientationSource = null;
             // Find a window requesting orientation.
             final WindowState win = getWindow(mGetOrientingWindow);
 
diff --git a/services/core/java/com/android/server/wm/WindowContainer.java b/services/core/java/com/android/server/wm/WindowContainer.java
index 0ade586..dd5afdd 100644
--- a/services/core/java/com/android/server/wm/WindowContainer.java
+++ b/services/core/java/com/android/server/wm/WindowContainer.java
@@ -2555,8 +2555,9 @@
             pw.print(prefix); pw.println("ContainerAnimator:");
             mSurfaceAnimator.dump(pw, prefix + "  ");
         }
-        if (mLastOrientationSource != null) {
+        if (mLastOrientationSource != null && this == mDisplayContent) {
             pw.println(prefix + "mLastOrientationSource=" + mLastOrientationSource);
+            pw.println(prefix + "deepestLastOrientationSource=" + getLastOrientationSource());
         }
     }
 
diff --git a/services/tests/wmtests/src/com/android/server/wm/DisplayAreaTest.java b/services/tests/wmtests/src/com/android/server/wm/DisplayAreaTest.java
index 880c486..d42ab72 100644
--- a/services/tests/wmtests/src/com/android/server/wm/DisplayAreaTest.java
+++ b/services/tests/wmtests/src/com/android/server/wm/DisplayAreaTest.java
@@ -20,6 +20,9 @@
 import static android.view.WindowManager.LayoutParams.TYPE_PRESENTATION;
 import static android.view.WindowManager.LayoutParams.TYPE_WALLPAPER;
 
+import static com.android.dx.mockito.inline.extended.ExtendedMockito.doNothing;
+import static com.android.dx.mockito.inline.extended.ExtendedMockito.doReturn;
+import static com.android.dx.mockito.inline.extended.ExtendedMockito.spyOn;
 import static com.android.server.wm.DisplayArea.Type.ABOVE_TASKS;
 import static com.android.server.wm.DisplayArea.Type.ANY;
 import static com.android.server.wm.DisplayArea.Type.BELOW_TASKS;
@@ -29,11 +32,15 @@
 import static com.android.server.wm.testing.Assert.assertThrows;
 
 import static org.junit.Assert.assertEquals;
+import static org.mockito.ArgumentMatchers.any;
 import static org.mockito.Mockito.mock;
 
+import android.content.pm.ActivityInfo;
 import android.os.Binder;
 import android.platform.test.annotations.Presubmit;
 import android.view.SurfaceControl;
+import android.view.View;
+import android.view.WindowManager;
 
 import org.junit.Rule;
 import org.junit.Test;
@@ -97,6 +104,42 @@
         assertThrows(IllegalStateException.class, () -> checkChild(BELOW_TASKS, ANY));
     }
 
+
+    @Test
+    public void testGetOrientation() {
+        final DisplayArea.Tokens area = new DisplayArea.Tokens(mWmsRule.getWindowManagerService(),
+                ABOVE_TASKS, "test");
+        final WindowToken token = createWindowToken(TYPE_APPLICATION_OVERLAY);
+        spyOn(token);
+        doReturn(mock(DisplayContent.class)).when(token).getDisplayContent();
+        doNothing().when(token).setParent(any());
+        final WindowState win = createWindowState(token);
+        spyOn(win);
+        doNothing().when(win).setParent(any());
+        win.mAttrs.screenOrientation = ActivityInfo.SCREEN_ORIENTATION_LANDSCAPE;
+        token.addChild(win, 0);
+        area.addChild(token);
+
+        doReturn(true).when(win).isVisible();
+
+        assertEquals("Visible window can request orientation",
+                ActivityInfo.SCREEN_ORIENTATION_LANDSCAPE,
+                area.getOrientation(ActivityInfo.SCREEN_ORIENTATION_NOSENSOR));
+
+        doReturn(false).when(win).isVisible();
+
+        assertEquals("Invisible window cannot request orientation",
+                ActivityInfo.SCREEN_ORIENTATION_NOSENSOR,
+                area.getOrientation(ActivityInfo.SCREEN_ORIENTATION_NOSENSOR));
+    }
+
+    private WindowState createWindowState(WindowToken token) {
+        return new WindowState(mWmsRule.getWindowManagerService(), mock(Session.class),
+                new TestIWindow(), token, null /* parentWindow */, 0 /* appOp */, 0 /* seq*/,
+                new WindowManager.LayoutParams(), View.VISIBLE, 0 /* ownerId */, 0 /* showUserId */,
+                false /* ownerCanAddInternalSystemWindow */, null);
+    }
+
     private WindowToken createWindowToken(int type) {
         return new WindowToken(mWmsRule.getWindowManagerService(), new Binder(),
                 type, false /* persist */, null /* displayContent */,