Loading services/core/java/com/android/server/wm/ActivityRecord.java +1 −4 Original line number Diff line number Diff line Loading @@ -8125,10 +8125,7 @@ final class ActivityRecord extends WindowToken implements WindowManagerService.A if (task != null && requestedOrientation == SCREEN_ORIENTATION_BEHIND) { // We use Task here because we want to be consistent with what happens in // multi-window mode where other tasks orientations are ignored. final ActivityRecord belowCandidate = task.getActivity( a -> a.canDefineOrientationForActivitiesAbove() /* callback */, this /* boundary */, false /* includeBoundary */, true /* traverseTopToBottom */); final ActivityRecord belowCandidate = task.getActivityBelowForDefiningOrientation(this); if (belowCandidate != null) { return belowCandidate.getRequestedConfigurationOrientation(forDisplay); } Loading services/core/java/com/android/server/wm/DisplayContent.java +8 −4 Original line number Diff line number Diff line Loading @@ -1822,7 +1822,13 @@ class DisplayContent extends RootDisplayArea implements WindowManagerPolicy.Disp */ private void applyFixedRotationForNonTopVisibleActivityIfNeeded(@NonNull ActivityRecord ar, @ActivityInfo.ScreenOrientation int topOrientation) { final int orientation = ar.getRequestedOrientation(); int orientation = ar.getRequestedOrientation(); if (orientation == ActivityInfo.SCREEN_ORIENTATION_BEHIND) { final ActivityRecord nextCandidate = getActivityBelowForDefiningOrientation(ar); if (nextCandidate != null) { orientation = nextCandidate.getRequestedOrientation(); } } if (orientation == topOrientation || ar.inMultiWindowMode() || ar.getRequestedConfigurationOrientation() == ORIENTATION_UNDEFINED) { return; Loading Loading @@ -1864,9 +1870,7 @@ class DisplayContent extends RootDisplayArea implements WindowManagerPolicy.Disp return ROTATION_UNDEFINED; } if (activityOrientation == ActivityInfo.SCREEN_ORIENTATION_BEHIND) { final ActivityRecord nextCandidate = getActivity( a -> a.canDefineOrientationForActivitiesAbove() /* callback */, r /* boundary */, false /* includeBoundary */, true /* traverseTopToBottom */); final ActivityRecord nextCandidate = getActivityBelowForDefiningOrientation(r); if (nextCandidate != null) { r = nextCandidate; activityOrientation = r.getOverrideOrientation(); Loading services/core/java/com/android/server/wm/WindowContainer.java +6 −0 Original line number Diff line number Diff line Loading @@ -1659,6 +1659,12 @@ class WindowContainer<E extends WindowContainer> extends ConfigurationContainer< return ORIENTATION_UNDEFINED; } @Nullable ActivityRecord getActivityBelowForDefiningOrientation(ActivityRecord from) { return getActivity(ActivityRecord::canDefineOrientationForActivitiesAbove, from /* boundary */, false /* includeBoundary */, true /* traverseTopToBottom */); } /** * Calls {@link #setOrientation(int, WindowContainer)} with {@code null} to the last 2 * parameters. Loading services/tests/wmtests/src/com/android/server/wm/DisplayContentTests.java +12 −0 Original line number Diff line number Diff line Loading @@ -1183,6 +1183,18 @@ public class DisplayContentTests extends WindowTestsBase { assertEquals(prev, mDisplayContent.getLastOrientationSource()); // The top will use the rotation from "prev" with fixed rotation. assertTrue(top.hasFixedRotationTransform()); mDisplayContent.continueUpdateOrientationForDiffOrienLaunchingApp(); assertFalse(top.hasFixedRotationTransform()); // Assume that the requested orientation of "prev" is landscape. And the display is also // rotated to landscape. The activities from bottom to top are TaskB{"prev, "behindTop"}, // TaskB{"top"}. Then "behindTop" should also get landscape according to ORIENTATION_BEHIND // instead of resolving as undefined which causes to unexpected fixed portrait rotation. final ActivityRecord behindTop = new ActivityBuilder(mAtm).setTask(prev.getTask()) .setOnTop(false).setScreenOrientation(SCREEN_ORIENTATION_BEHIND).build(); mDisplayContent.applyFixedRotationForNonTopVisibleActivityIfNeeded(behindTop); assertFalse(behindTop.hasFixedRotationTransform()); } @Test Loading Loading
services/core/java/com/android/server/wm/ActivityRecord.java +1 −4 Original line number Diff line number Diff line Loading @@ -8125,10 +8125,7 @@ final class ActivityRecord extends WindowToken implements WindowManagerService.A if (task != null && requestedOrientation == SCREEN_ORIENTATION_BEHIND) { // We use Task here because we want to be consistent with what happens in // multi-window mode where other tasks orientations are ignored. final ActivityRecord belowCandidate = task.getActivity( a -> a.canDefineOrientationForActivitiesAbove() /* callback */, this /* boundary */, false /* includeBoundary */, true /* traverseTopToBottom */); final ActivityRecord belowCandidate = task.getActivityBelowForDefiningOrientation(this); if (belowCandidate != null) { return belowCandidate.getRequestedConfigurationOrientation(forDisplay); } Loading
services/core/java/com/android/server/wm/DisplayContent.java +8 −4 Original line number Diff line number Diff line Loading @@ -1822,7 +1822,13 @@ class DisplayContent extends RootDisplayArea implements WindowManagerPolicy.Disp */ private void applyFixedRotationForNonTopVisibleActivityIfNeeded(@NonNull ActivityRecord ar, @ActivityInfo.ScreenOrientation int topOrientation) { final int orientation = ar.getRequestedOrientation(); int orientation = ar.getRequestedOrientation(); if (orientation == ActivityInfo.SCREEN_ORIENTATION_BEHIND) { final ActivityRecord nextCandidate = getActivityBelowForDefiningOrientation(ar); if (nextCandidate != null) { orientation = nextCandidate.getRequestedOrientation(); } } if (orientation == topOrientation || ar.inMultiWindowMode() || ar.getRequestedConfigurationOrientation() == ORIENTATION_UNDEFINED) { return; Loading Loading @@ -1864,9 +1870,7 @@ class DisplayContent extends RootDisplayArea implements WindowManagerPolicy.Disp return ROTATION_UNDEFINED; } if (activityOrientation == ActivityInfo.SCREEN_ORIENTATION_BEHIND) { final ActivityRecord nextCandidate = getActivity( a -> a.canDefineOrientationForActivitiesAbove() /* callback */, r /* boundary */, false /* includeBoundary */, true /* traverseTopToBottom */); final ActivityRecord nextCandidate = getActivityBelowForDefiningOrientation(r); if (nextCandidate != null) { r = nextCandidate; activityOrientation = r.getOverrideOrientation(); Loading
services/core/java/com/android/server/wm/WindowContainer.java +6 −0 Original line number Diff line number Diff line Loading @@ -1659,6 +1659,12 @@ class WindowContainer<E extends WindowContainer> extends ConfigurationContainer< return ORIENTATION_UNDEFINED; } @Nullable ActivityRecord getActivityBelowForDefiningOrientation(ActivityRecord from) { return getActivity(ActivityRecord::canDefineOrientationForActivitiesAbove, from /* boundary */, false /* includeBoundary */, true /* traverseTopToBottom */); } /** * Calls {@link #setOrientation(int, WindowContainer)} with {@code null} to the last 2 * parameters. Loading
services/tests/wmtests/src/com/android/server/wm/DisplayContentTests.java +12 −0 Original line number Diff line number Diff line Loading @@ -1183,6 +1183,18 @@ public class DisplayContentTests extends WindowTestsBase { assertEquals(prev, mDisplayContent.getLastOrientationSource()); // The top will use the rotation from "prev" with fixed rotation. assertTrue(top.hasFixedRotationTransform()); mDisplayContent.continueUpdateOrientationForDiffOrienLaunchingApp(); assertFalse(top.hasFixedRotationTransform()); // Assume that the requested orientation of "prev" is landscape. And the display is also // rotated to landscape. The activities from bottom to top are TaskB{"prev, "behindTop"}, // TaskB{"top"}. Then "behindTop" should also get landscape according to ORIENTATION_BEHIND // instead of resolving as undefined which causes to unexpected fixed portrait rotation. final ActivityRecord behindTop = new ActivityBuilder(mAtm).setTask(prev.getTask()) .setOnTop(false).setScreenOrientation(SCREEN_ORIENTATION_BEHIND).build(); mDisplayContent.applyFixedRotationForNonTopVisibleActivityIfNeeded(behindTop); assertFalse(behindTop.hasFixedRotationTransform()); } @Test Loading