From dd0f6850606c85b6914e1f946efd32a132bae599 Mon Sep 17 00:00:00 2001 From: Massimo Carli Date: Fri, 26 Aug 2022 14:01:38 +0000 Subject: [PATCH] Fix letterbox for SCREEN_ORIENTATION_BEHIND MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit At the moment, an activity with "behind" doesn’t go in letterbox as expected when it’s at the top of a portrait-only one which was letterboxed in landscape device orientation. An activity with "behind" orientation will be letterboxed if it is the activity that's immediately beneath it Test: Launch an activity using SCREEN_ORIENTATION_BEHIND on top of a fixed orientation activity and check it's letterboxed. Also run `atest ActivityRecordTests` Fix: 244309481 Change-Id: I221e4c2a778a4e2ea11795e82366bf5bb08a5507 --- .../com/android/server/wm/ActivityRecord.java | 25 +++++++++++++++++++ .../server/wm/ActivityRecordTests.java | 16 ++++++++++++ 2 files changed, 41 insertions(+) diff --git a/services/core/java/com/android/server/wm/ActivityRecord.java b/services/core/java/com/android/server/wm/ActivityRecord.java index 9c080e856500a..bef739ebacfd8 100644 --- a/services/core/java/com/android/server/wm/ActivityRecord.java +++ b/services/core/java/com/android/server/wm/ActivityRecord.java @@ -7634,6 +7634,31 @@ final class ActivityRecord extends WindowToken implements WindowManagerService.A ensureActivityConfiguration(0 /* globalChanges */, false /* preserveWindow */); } + /** + * Returns the requested {@link Configuration.Orientation} for the current activity. + * + *

When The current orientation is set to {@link SCREEN_ORIENTATION_BEHIND} it returns the + * requested orientation for the activity below which is the first activity with an explicit + * (different from {@link SCREEN_ORIENTATION_UNSET}) orientation which is not {@link + * SCREEN_ORIENTATION_BEHIND}. + */ + @Configuration.Orientation + @Override + int getRequestedConfigurationOrientation(boolean forDisplay) { + if (mOrientation == SCREEN_ORIENTATION_BEHIND && task != null) { + // 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.mOrientation != SCREEN_ORIENTATION_UNSET && !a.finishing + && a.mOrientation != ActivityInfo.SCREEN_ORIENTATION_BEHIND, this, + false /* includeBoundary */, true /* traverseTopToBottom */); + if (belowCandidate != null) { + return belowCandidate.getRequestedConfigurationOrientation(forDisplay); + } + } + return super.getRequestedConfigurationOrientation(forDisplay); + } + @Override void onCancelFixedRotationTransform(int originalDisplayRotation) { if (this != mDisplayContent.getLastOrientationSource()) { diff --git a/services/tests/wmtests/src/com/android/server/wm/ActivityRecordTests.java b/services/tests/wmtests/src/com/android/server/wm/ActivityRecordTests.java index d5447447a7b2a..462957a88a6ca 100644 --- a/services/tests/wmtests/src/com/android/server/wm/ActivityRecordTests.java +++ b/services/tests/wmtests/src/com/android/server/wm/ActivityRecordTests.java @@ -2319,6 +2319,22 @@ public class ActivityRecordTests extends WindowTestsBase { assertTrue(activity1.getTask().getTaskInfo().launchCookies.contains(launchCookie)); } + @Test + public void testOrientationForScreenOrientationBehind() { + final Task task = createTask(mDisplayContent); + // Activity below + new ActivityBuilder(mAtm) + .setTask(task) + .setScreenOrientation(SCREEN_ORIENTATION_PORTRAIT) + .build(); + final ActivityRecord activityTop = new ActivityBuilder(mAtm) + .setTask(task) + .setScreenOrientation(SCREEN_ORIENTATION_BEHIND) + .build(); + final int topOrientation = activityTop.getRequestedConfigurationOrientation(); + assertEquals(SCREEN_ORIENTATION_PORTRAIT, topOrientation); + } + private void verifyProcessInfoUpdate(ActivityRecord activity, State state, boolean shouldUpdate, boolean activityChange) { reset(activity.app);