From 4136db264624a343d92c818efb8453a2a5f0852a Mon Sep 17 00:00:00 2001 From: Riddle Hsu Date: Mon, 12 Oct 2020 19:03:35 +0800 Subject: [PATCH] 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 --- .../com/android/server/wm/DisplayArea.java | 4 ++ .../android/server/wm/WindowContainer.java | 3 +- .../android/server/wm/DisplayAreaTest.java | 40 +++++++++++++++++++ 3 files changed, 46 insertions(+), 1 deletion(-) diff --git a/services/core/java/com/android/server/wm/DisplayArea.java b/services/core/java/com/android/server/wm/DisplayArea.java index 8bd42f03ff861..1718b2aef0c99 100644 --- a/services/core/java/com/android/server/wm/DisplayArea.java +++ b/services/core/java/com/android/server/wm/DisplayArea.java @@ -370,6 +370,9 @@ public class DisplayArea extends WindowContainer { Comparator.comparingInt(WindowToken::getWindowLayerFromType); private final Predicate mGetOrientingWindow = w -> { + if (!w.isVisible() || !w.mLegacyPolicyVisibilityAfterAnim) { + return false; + } final WindowManagerPolicy policy = mWmService.mPolicy; if (policy.isKeyguardHostWindow(w.mAttrs)) { if (mWmService.mKeyguardGoingAway) { @@ -405,6 +408,7 @@ public class DisplayArea extends WindowContainer { @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 38ec924ec6701..95d86621c5416 100644 --- a/services/core/java/com/android/server/wm/WindowContainer.java +++ b/services/core/java/com/android/server/wm/WindowContainer.java @@ -2744,8 +2744,9 @@ class WindowContainer extends ConfigurationContainer< 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 e17601e99010c..f88530c1f23e7 100644 --- a/services/tests/wmtests/src/com/android/server/wm/DisplayAreaTest.java +++ b/services/tests/wmtests/src/com/android/server/wm/DisplayAreaTest.java @@ -23,6 +23,8 @@ import static android.view.WindowManager.LayoutParams.TYPE_WALLPAPER; import static android.window.DisplayAreaOrganizer.FEATURE_DEFAULT_TASK_CONTAINER; import static android.window.DisplayAreaOrganizer.FEATURE_VENDOR_FIRST; +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; @@ -37,14 +39,18 @@ import static com.android.server.wm.testing.Assert.assertThrows; import static com.google.common.truth.Truth.assertThat; import static org.junit.Assert.assertEquals; +import static org.mockito.ArgumentMatchers.any; import static org.mockito.Mockito.mock; import static org.mockito.Mockito.verify; import static org.mockito.Mockito.verifyZeroInteractions; +import android.content.pm.ActivityInfo; import android.graphics.Rect; import android.os.Binder; import android.platform.test.annotations.Presubmit; import android.view.SurfaceControl; +import android.view.View; +import android.view.WindowManager; import com.google.android.collect.Lists; @@ -405,6 +411,33 @@ public class DisplayAreaTest { childBounds1, windowToken.getMaxBounds()); } + @Test + public void testGetOrientation() { + final DisplayArea.Tokens area = new DisplayArea.Tokens(mWms, 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 static class TestDisplayArea extends DisplayArea { private TestDisplayArea(WindowManagerService wms, Rect bounds) { super(wms, ANY, "half display area"); @@ -417,6 +450,13 @@ public class DisplayAreaTest { } } + private WindowState createWindowState(WindowToken token) { + return new WindowState(mWms, mock(Session.class), new TestIWindow(), token, + null /* parentWindow */, 0 /* appOp */, new WindowManager.LayoutParams(), + View.VISIBLE, 0 /* ownerId */, 0 /* showUserId */, + false /* ownerCanAddInternalSystemWindow */); + } + private WindowToken createWindowToken(int type) { return new WindowToken(mWmsRule.getWindowManagerService(), new Binder(), type, false /* persist */, null /* displayContent */,