summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--data/etc/services.core.protolog.json12
-rw-r--r--services/core/java/com/android/server/wm/ActivityRecord.java7
-rw-r--r--services/core/java/com/android/server/wm/DisplayArea.java45
-rw-r--r--services/core/java/com/android/server/wm/DisplayContent.java53
-rw-r--r--services/core/java/com/android/server/wm/Task.java7
-rw-r--r--services/core/java/com/android/server/wm/TaskDisplayArea.java30
-rw-r--r--services/core/java/com/android/server/wm/WindowContainer.java7
-rw-r--r--services/tests/wmtests/src/com/android/server/wm/ActivityRecordTests.java2
-rw-r--r--services/tests/wmtests/src/com/android/server/wm/DisplayAreaTest.java68
-rw-r--r--services/tests/wmtests/src/com/android/server/wm/DualDisplayAreaGroupPolicyTest.java75
-rw-r--r--services/tests/wmtests/src/com/android/server/wm/TaskDisplayAreaTests.java105
-rw-r--r--services/tests/wmtests/src/com/android/server/wm/TaskTests.java14
-rw-r--r--services/tests/wmtests/src/com/android/server/wm/WindowContainerTests.java13
13 files changed, 304 insertions, 134 deletions
diff --git a/data/etc/services.core.protolog.json b/data/etc/services.core.protolog.json
index a4a38c713a66..86c8097ee674 100644
--- a/data/etc/services.core.protolog.json
+++ b/data/etc/services.core.protolog.json
@@ -3871,12 +3871,6 @@
"group": "WM_DEBUG_ORIENTATION",
"at": "com\/android\/server\/wm\/TaskDisplayArea.java"
},
- "1648338379": {
- "message": "Display id=%d is ignoring all orientation requests, return %d",
- "level": "VERBOSE",
- "group": "WM_DEBUG_ORIENTATION",
- "at": "com\/android\/server\/wm\/DisplayContent.java"
- },
"1653025361": {
"message": "Register task fragment organizer=%s uid=%d pid=%d",
"level": "VERBOSE",
@@ -4117,6 +4111,12 @@
"group": "WM_DEBUG_WINDOW_ORGANIZER",
"at": "com\/android\/server\/wm\/DisplayAreaPolicyBuilder.java"
},
+ "1877863087": {
+ "message": "Display id=%d is ignoring orientation request for %d, return %d",
+ "level": "VERBOSE",
+ "group": "WM_DEBUG_ORIENTATION",
+ "at": "com\/android\/server\/wm\/DisplayContent.java"
+ },
"1878927091": {
"message": "prepareSurface: No changes in animation for %s",
"level": "VERBOSE",
diff --git a/services/core/java/com/android/server/wm/ActivityRecord.java b/services/core/java/com/android/server/wm/ActivityRecord.java
index e639866a6bab..418e1edca05b 100644
--- a/services/core/java/com/android/server/wm/ActivityRecord.java
+++ b/services/core/java/com/android/server/wm/ActivityRecord.java
@@ -7756,10 +7756,6 @@ final class ActivityRecord extends WindowToken implements WindowManagerService.A
// configuration. This is important to cases where activities with incompatible
// orientations launch, or user goes back from an activity of bi-orientation to an
// activity with specified orientation.
- if (getRequestedOrientation() == SCREEN_ORIENTATION_UNSET) {
- return;
- }
-
if (onDescendantOrientationChanged(this)) {
// WM Shell can show additional UI elements, e.g. a restart button for size compat mode
// so ensure that WM Shell is called when an activity becomes visible.
@@ -8329,7 +8325,8 @@ final class ActivityRecord extends WindowToken implements WindowManagerService.A
// If orientation is respected when insets are applied, then stableBounds will be empty.
boolean orientationRespectedWithInsets =
orientationRespectedWithInsets(parentBounds, stableBounds);
- if (handlesOrientationChangeFromDescendant() && orientationRespectedWithInsets) {
+ if (orientationRespectedWithInsets
+ && handlesOrientationChangeFromDescendant(mOrientation)) {
// No need to letterbox because of fixed orientation. Display will handle
// fixed-orientation requests and a display rotation is enough to respect requested
// orientation with insets applied.
diff --git a/services/core/java/com/android/server/wm/DisplayArea.java b/services/core/java/com/android/server/wm/DisplayArea.java
index 3ac135076a97..71fef057d1d2 100644
--- a/services/core/java/com/android/server/wm/DisplayArea.java
+++ b/services/core/java/com/android/server/wm/DisplayArea.java
@@ -35,6 +35,8 @@ import static com.android.server.wm.DisplayAreaProto.WINDOW_CONTAINER;
import static com.android.server.wm.WindowContainerChildProto.DISPLAY_AREA;
import android.annotation.Nullable;
+import android.content.pm.ActivityInfo;
+import android.content.pm.ActivityInfo.ScreenOrientation;
import android.content.res.Configuration;
import android.graphics.Rect;
import android.util.proto.ProtoOutputStream;
@@ -142,26 +144,30 @@ public class DisplayArea<T extends WindowContainer> extends WindowContainer<T> {
}
@Override
+ @ScreenOrientation
int getOrientation(int candidate) {
- mLastOrientationSource = null;
- if (getIgnoreOrientationRequest()) {
+ final int orientation = super.getOrientation(candidate);
+ if (getIgnoreOrientationRequest(orientation)) {
+ // In all the other case, mLastOrientationSource will be reassigned to a new value
+ mLastOrientationSource = null;
return SCREEN_ORIENTATION_UNSET;
}
-
- return super.getOrientation(candidate);
+ return orientation;
}
@Override
- boolean handlesOrientationChangeFromDescendant() {
- return !getIgnoreOrientationRequest()
- && super.handlesOrientationChangeFromDescendant();
+ boolean handlesOrientationChangeFromDescendant(@ScreenOrientation int orientation) {
+ return !getIgnoreOrientationRequest(orientation)
+ && super.handlesOrientationChangeFromDescendant(orientation);
}
@Override
- boolean onDescendantOrientationChanged(WindowContainer requestingContainer) {
+ boolean onDescendantOrientationChanged(@Nullable WindowContainer requestingContainer) {
// If this is set to ignore the orientation request, we don't propagate descendant
// orientation request.
- return !getIgnoreOrientationRequest()
+ final int orientation = requestingContainer != null
+ ? requestingContainer.mOrientation : SCREEN_ORIENTATION_UNSET;
+ return !getIgnoreOrientationRequest(orientation)
&& super.onDescendantOrientationChanged(requestingContainer);
}
@@ -225,6 +231,23 @@ public class DisplayArea<T extends WindowContainer> extends WindowContainer<T> {
}
}
+ /**
+ * @return {@value true} if we need to ignore the orientation in input.
+ */
+ // TODO(b/262366204): Rename getIgnoreOrientationRequest to shouldIgnoreOrientationRequest
+ boolean getIgnoreOrientationRequest(@ScreenOrientation int orientation) {
+ // We always respect orientation request for ActivityInfo.SCREEN_ORIENTATION_LOCKED
+ // ActivityInfo.SCREEN_ORIENTATION_NOSENSOR.
+ // Main use case why this is important is Camera apps that rely on those
+ // properties to ensure that they will be able to determine Camera preview
+ // orientation correctly
+ if (orientation == ActivityInfo.SCREEN_ORIENTATION_LOCKED
+ || orientation == ActivityInfo.SCREEN_ORIENTATION_NOSENSOR) {
+ return false;
+ }
+ return getIgnoreOrientationRequest();
+ }
+
boolean getIgnoreOrientationRequest() {
// Adding an exception for when ignoreOrientationRequest is overridden at runtime for all
// DisplayArea-s. For example, this is needed for the Kids Mode since many Kids apps aren't
@@ -642,11 +665,9 @@ public class DisplayArea<T extends WindowContainer> extends WindowContainer<T> {
}
@Override
+ @ScreenOrientation
int getOrientation(int candidate) {
mLastOrientationSource = null;
- if (getIgnoreOrientationRequest()) {
- return SCREEN_ORIENTATION_UNSET;
- }
// Find a window requesting orientation.
final WindowState win = getWindow(mGetOrientingWindow);
diff --git a/services/core/java/com/android/server/wm/DisplayContent.java b/services/core/java/com/android/server/wm/DisplayContent.java
index 5d502f5420ca..4c499861cb9a 100644
--- a/services/core/java/com/android/server/wm/DisplayContent.java
+++ b/services/core/java/com/android/server/wm/DisplayContent.java
@@ -1558,13 +1558,15 @@ class DisplayContent extends RootDisplayArea implements WindowManagerPolicy.Disp
}
@Override
- boolean onDescendantOrientationChanged(WindowContainer requestingContainer) {
+ boolean onDescendantOrientationChanged(@Nullable WindowContainer requestingContainer) {
final Configuration config = updateOrientation(
requestingContainer, false /* forceUpdate */);
// If display rotation class tells us that it doesn't consider app requested orientation,
// this display won't rotate just because of an app changes its requested orientation. Thus
// it indicates that this display chooses not to handle this request.
- final boolean handled = handlesOrientationChangeFromDescendant();
+ final int orientation = requestingContainer != null ? requestingContainer.mOrientation
+ : SCREEN_ORIENTATION_UNSET;
+ final boolean handled = handlesOrientationChangeFromDescendant(orientation);
if (config == null) {
return handled;
}
@@ -1587,8 +1589,8 @@ class DisplayContent extends RootDisplayArea implements WindowManagerPolicy.Disp
}
@Override
- boolean handlesOrientationChangeFromDescendant() {
- return !getIgnoreOrientationRequest()
+ boolean handlesOrientationChangeFromDescendant(@ScreenOrientation int orientation) {
+ return !getIgnoreOrientationRequest(orientation)
&& !getDisplayRotation().isFixedToUserRotation();
}
@@ -1689,7 +1691,7 @@ class DisplayContent extends RootDisplayArea implements WindowManagerPolicy.Disp
return ROTATION_UNDEFINED;
}
if (!WindowManagerService.ENABLE_FIXED_ROTATION_TRANSFORM
- || getIgnoreOrientationRequest()) {
+ || getIgnoreOrientationRequest(r.mOrientation)) {
return ROTATION_UNDEFINED;
}
if (r.mOrientation == ActivityInfo.SCREEN_ORIENTATION_BEHIND) {
@@ -2688,15 +2690,6 @@ class DisplayContent extends RootDisplayArea implements WindowManagerPolicy.Disp
@ScreenOrientation
@Override
int getOrientation() {
- mLastOrientationSource = null;
- if (!handlesOrientationChangeFromDescendant()) {
- // Return SCREEN_ORIENTATION_UNSPECIFIED so that Display respect sensor rotation
- ProtoLog.v(WM_DEBUG_ORIENTATION,
- "Display id=%d is ignoring all orientation requests, return %d",
- mDisplayId, SCREEN_ORIENTATION_UNSPECIFIED);
- return SCREEN_ORIENTATION_UNSPECIFIED;
- }
-
if (mWmService.mDisplayFrozen) {
if (mWmService.mPolicy.isKeyguardLocked()) {
// Use the last orientation the while the display is frozen with the keyguard
@@ -2712,6 +2705,16 @@ class DisplayContent extends RootDisplayArea implements WindowManagerPolicy.Disp
}
final int orientation = super.getOrientation();
+
+ if (!handlesOrientationChangeFromDescendant(orientation)) {
+ mLastOrientationSource = null;
+ // Return SCREEN_ORIENTATION_UNSPECIFIED so that Display respect sensor rotation
+ ProtoLog.v(WM_DEBUG_ORIENTATION,
+ "Display id=%d is ignoring orientation request for %d, return %d",
+ mDisplayId, orientation, SCREEN_ORIENTATION_UNSPECIFIED);
+ return SCREEN_ORIENTATION_UNSPECIFIED;
+ }
+
if (orientation == SCREEN_ORIENTATION_UNSET) {
// Return SCREEN_ORIENTATION_UNSPECIFIED so that Display respect sensor rotation
ProtoLog.v(WM_DEBUG_ORIENTATION,
@@ -3832,18 +3835,7 @@ class DisplayContent extends RootDisplayArea implements WindowManagerPolicy.Disp
/** Called when the focused {@link TaskDisplayArea} on this display may have changed. */
void onLastFocusedTaskDisplayAreaChanged(@Nullable TaskDisplayArea taskDisplayArea) {
- // Only record the TaskDisplayArea that handles orientation request.
- if (taskDisplayArea != null && taskDisplayArea.handlesOrientationChangeFromDescendant()) {
- mOrientationRequestingTaskDisplayArea = taskDisplayArea;
- return;
- }
-
- // If the previous TDA no longer handles orientation request, clear it.
- if (mOrientationRequestingTaskDisplayArea != null
- && !mOrientationRequestingTaskDisplayArea
- .handlesOrientationChangeFromDescendant()) {
- mOrientationRequestingTaskDisplayArea = null;
- }
+ mOrientationRequestingTaskDisplayArea = taskDisplayArea;
}
/**
@@ -5053,13 +5045,10 @@ class DisplayContent extends RootDisplayArea implements WindowManagerPolicy.Disp
}
@Override
- int getOrientation(int candidate) {
- if (getIgnoreOrientationRequest()) {
- return SCREEN_ORIENTATION_UNSET;
- }
-
+ @ScreenOrientation
+ int getOrientation(@ScreenOrientation int candidate) {
// IME does not participate in orientation.
- return candidate;
+ return getIgnoreOrientationRequest(candidate) ? SCREEN_ORIENTATION_UNSET : candidate;
}
@Override
diff --git a/services/core/java/com/android/server/wm/Task.java b/services/core/java/com/android/server/wm/Task.java
index 69ed7a15af27..a55ea91ff196 100644
--- a/services/core/java/com/android/server/wm/Task.java
+++ b/services/core/java/com/android/server/wm/Task.java
@@ -143,6 +143,7 @@ import android.app.WindowConfiguration;
import android.content.ComponentName;
import android.content.Intent;
import android.content.pm.ActivityInfo;
+import android.content.pm.ActivityInfo.ScreenOrientation;
import android.content.pm.ApplicationInfo;
import android.content.pm.IPackageManager;
import android.content.pm.PackageManager;
@@ -2686,8 +2687,8 @@ class Task extends TaskFragment {
}
@Override
- boolean handlesOrientationChangeFromDescendant() {
- if (!super.handlesOrientationChangeFromDescendant()) {
+ boolean handlesOrientationChangeFromDescendant(@ScreenOrientation int orientation) {
+ if (!super.handlesOrientationChangeFromDescendant(orientation)) {
return false;
}
@@ -2702,7 +2703,7 @@ class Task extends TaskFragment {
// Check for leaf Task.
// Display won't rotate for the orientation request if the Task/TaskDisplayArea
// can't specify orientation.
- return canSpecifyOrientation() && getDisplayArea().canSpecifyOrientation();
+ return canSpecifyOrientation() && getDisplayArea().canSpecifyOrientation(orientation);
}
void resize(boolean relayout, boolean forced) {
diff --git a/services/core/java/com/android/server/wm/TaskDisplayArea.java b/services/core/java/com/android/server/wm/TaskDisplayArea.java
index e0ed356fbe59..8ad76a3eb327 100644
--- a/services/core/java/com/android/server/wm/TaskDisplayArea.java
+++ b/services/core/java/com/android/server/wm/TaskDisplayArea.java
@@ -41,6 +41,7 @@ import android.annotation.Nullable;
import android.app.ActivityOptions;
import android.app.WindowConfiguration;
import android.content.pm.ActivityInfo;
+import android.content.pm.ActivityInfo.ScreenOrientation;
import android.content.res.Configuration;
import android.graphics.Color;
import android.os.UserHandle;
@@ -633,22 +634,20 @@ final class TaskDisplayArea extends DisplayArea<WindowContainer> {
}
@Override
- int getOrientation(int candidate) {
- mLastOrientationSource = null;
- if (getIgnoreOrientationRequest()) {
- return SCREEN_ORIENTATION_UNSET;
- }
- if (!canSpecifyOrientation()) {
+ @ScreenOrientation
+ int getOrientation(@ScreenOrientation int candidate) {
+ final int orientation = super.getOrientation(candidate);
+ if (!canSpecifyOrientation(orientation)) {
+ mLastOrientationSource = null;
// We only respect orientation of the focused TDA, which can be a child of this TDA.
- return reduceOnAllTaskDisplayAreas((taskDisplayArea, orientation) -> {
- if (taskDisplayArea == this || orientation != SCREEN_ORIENTATION_UNSET) {
- return orientation;
+ return reduceOnAllTaskDisplayAreas((taskDisplayArea, taskOrientation) -> {
+ if (taskDisplayArea == this || taskOrientation != SCREEN_ORIENTATION_UNSET) {
+ return taskOrientation;
}
return taskDisplayArea.getOrientation(candidate);
}, SCREEN_ORIENTATION_UNSET);
}
- final int orientation = super.getOrientation(candidate);
if (orientation != SCREEN_ORIENTATION_UNSET
&& orientation != SCREEN_ORIENTATION_BEHIND) {
ProtoLog.v(WM_DEBUG_ORIENTATION,
@@ -1870,12 +1869,11 @@ final class TaskDisplayArea extends DisplayArea<WindowContainer> {
}
/** Whether this task display area can request orientation. */
- boolean canSpecifyOrientation() {
- // Only allow to specify orientation if this TDA is not set to ignore orientation request,
- // and it is the last focused one on this logical display that can request orientation
- // request.
- return !getIgnoreOrientationRequest()
- && mDisplayContent.getOrientationRequestingTaskDisplayArea() == this;
+ boolean canSpecifyOrientation(@ScreenOrientation int orientation) {
+ // Only allow to specify orientation if this TDA is the last focused one on this logical
+ // display that can request orientation request.
+ return mDisplayContent.getOrientationRequestingTaskDisplayArea() == this
+ && !getIgnoreOrientationRequest(orientation);
}
void clearPreferredTopFocusableRootTask() {
diff --git a/services/core/java/com/android/server/wm/WindowContainer.java b/services/core/java/com/android/server/wm/WindowContainer.java
index 2f81f93ba2ab..cb5a4338c567 100644
--- a/services/core/java/com/android/server/wm/WindowContainer.java
+++ b/services/core/java/com/android/server/wm/WindowContainer.java
@@ -1420,9 +1420,9 @@ class WindowContainer<E extends WindowContainer> extends ConfigurationContainer<
* @return {@code true} if it handles or will handle orientation change in the future; {@code
* false} if it won't handle the change at anytime.
*/
- boolean handlesOrientationChangeFromDescendant() {
+ boolean handlesOrientationChangeFromDescendant(int orientation) {
final WindowContainer parent = getParent();
- return parent != null && parent.handlesOrientationChangeFromDescendant();
+ return parent != null && parent.handlesOrientationChangeFromDescendant(orientation);
}
/**
@@ -1514,7 +1514,8 @@ class WindowContainer<E extends WindowContainer> extends ConfigurationContainer<
// portrait but the task is still in landscape. While updating from display,
// the task can be updated to portrait first so the configuration can be
// computed in a consistent environment.
- && (inMultiWindowMode() || !handlesOrientationChangeFromDescendant())) {
+ && (inMultiWindowMode()
+ || !handlesOrientationChangeFromDescendant(orientation))) {
// Resolve the requested orientation.
onConfigurationChanged(parent.getConfiguration());
}
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 17ec19d3e617..a017bd6a9436 100644
--- a/services/tests/wmtests/src/com/android/server/wm/ActivityRecordTests.java
+++ b/services/tests/wmtests/src/com/android/server/wm/ActivityRecordTests.java
@@ -517,7 +517,7 @@ public class ActivityRecordTests extends WindowTestsBase {
// Mimic the behavior that display doesn't handle app's requested orientation.
final DisplayContent dc = activity.getTask().getDisplayContent();
doReturn(false).when(dc).onDescendantOrientationChanged(any());
- doReturn(false).when(dc).handlesOrientationChangeFromDescendant();
+ doReturn(false).when(dc).handlesOrientationChangeFromDescendant(anyInt());
final int requestedOrientation;
switch (newConfig.orientation) {
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 b87c5a364c82..10540dc5a9ee 100644
--- a/services/tests/wmtests/src/com/android/server/wm/DisplayAreaTest.java
+++ b/services/tests/wmtests/src/com/android/server/wm/DisplayAreaTest.java
@@ -18,6 +18,8 @@ package com.android.server.wm;
import static android.app.WindowConfiguration.WINDOWING_MODE_MULTI_WINDOW;
import static android.content.pm.ActivityInfo.SCREEN_ORIENTATION_LANDSCAPE;
+import static android.content.pm.ActivityInfo.SCREEN_ORIENTATION_LOCKED;
+import static android.content.pm.ActivityInfo.SCREEN_ORIENTATION_NOSENSOR;
import static android.content.pm.ActivityInfo.SCREEN_ORIENTATION_PORTRAIT;
import static android.view.WindowManager.LayoutParams.TYPE_APPLICATION;
import static android.view.WindowManager.LayoutParams.TYPE_APPLICATION_OVERLAY;
@@ -471,29 +473,28 @@ public class DisplayAreaTest extends WindowTestsBase {
}
@Test
- public void testSetIgnoreOrientationRequest() {
- final DisplayArea.Tokens area = new DisplayArea.Tokens(mWm, 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();
+ public void testSetIgnoreOrientationRequest_notCallSuperOnDescendantOrientationChanged() {
+ final TaskDisplayArea tda = mDisplayContent.getDefaultTaskDisplayArea();
+ final Task stack =
+ new TaskBuilder(mSupervisor).setOnTop(!ON_TOP).setCreateActivity(true).build();
+ final ActivityRecord activity = stack.getTopNonFinishingActivity();
- assertEquals(ActivityInfo.SCREEN_ORIENTATION_LANDSCAPE, area.getOrientation());
+ tda.setIgnoreOrientationRequest(true /* ignoreOrientationRequest */);
- area.setIgnoreOrientationRequest(true /* ignoreOrientationRequest */);
+ activity.setRequestedOrientation(SCREEN_ORIENTATION_LANDSCAPE);
- assertEquals(ActivityInfo.SCREEN_ORIENTATION_UNSET, area.getOrientation());
+ verify(tda).onDescendantOrientationChanged(any());
+ verify(mDisplayContent, never()).onDescendantOrientationChanged(any());
+
+ tda.setIgnoreOrientationRequest(false /* ignoreOrientationRequest */);
+ activity.setRequestedOrientation(SCREEN_ORIENTATION_PORTRAIT);
+
+ verify(tda, times(2)).onDescendantOrientationChanged(any());
+ verify(mDisplayContent).onDescendantOrientationChanged(any());
}
@Test
- public void testSetIgnoreOrientationRequest_notCallSuperOnDescendantOrientationChanged() {
+ public void testSetIgnoreOrientationRequest_callSuperOnDescendantOrientationChangedNoSensor() {
final TaskDisplayArea tda = mDisplayContent.getDefaultTaskDisplayArea();
final Task stack =
new TaskBuilder(mSupervisor).setOnTop(!ON_TOP).setCreateActivity(true).build();
@@ -501,20 +502,41 @@ public class DisplayAreaTest extends WindowTestsBase {
tda.setIgnoreOrientationRequest(true /* ignoreOrientationRequest */);
- activity.setRequestedOrientation(SCREEN_ORIENTATION_LANDSCAPE);
+ activity.setRequestedOrientation(SCREEN_ORIENTATION_NOSENSOR);
verify(tda).onDescendantOrientationChanged(any());
- verify(mDisplayContent, never()).onDescendantOrientationChanged(any());
+ verify(mDisplayContent).onDescendantOrientationChanged(any());
tda.setIgnoreOrientationRequest(false /* ignoreOrientationRequest */);
- activity.setRequestedOrientation(SCREEN_ORIENTATION_PORTRAIT);
+ activity.setRequestedOrientation(SCREEN_ORIENTATION_NOSENSOR);
- verify(tda, times(2)).onDescendantOrientationChanged(any());
+ verify(tda).onDescendantOrientationChanged(any());
+ verify(mDisplayContent).onDescendantOrientationChanged(any());
+ }
+
+ @Test
+ public void testSetIgnoreOrientationRequest_callSuperOnDescendantOrientationChangedLocked() {
+ final TaskDisplayArea tda = mDisplayContent.getDefaultTaskDisplayArea();
+ final Task stack =
+ new TaskBuilder(mSupervisor).setOnTop(!ON_TOP).setCreateActivity(true).build();
+ final ActivityRecord activity = stack.getTopNonFinishingActivity();
+
+ tda.setIgnoreOrientationRequest(true /* ignoreOrientationRequest */);
+
+ activity.setRequestedOrientation(SCREEN_ORIENTATION_LOCKED);
+
+ verify(tda).onDescendantOrientationChanged(any());
+ verify(mDisplayContent).onDescendantOrientationChanged(any());
+
+ tda.setIgnoreOrientationRequest(false /* ignoreOrientationRequest */);
+ activity.setRequestedOrientation(SCREEN_ORIENTATION_LOCKED);
+
+ verify(tda).onDescendantOrientationChanged(any());
verify(mDisplayContent).onDescendantOrientationChanged(any());
}
@Test
- public void testSetIgnoreOrientationRequest_updateOrientationRequestingTaskDisplayArea() {
+ public void testGetOrientationRequestingTaskDisplayArea_updateOrientationTaskDisplayArea() {
final TaskDisplayArea tda = mDisplayContent.getDefaultTaskDisplayArea();
final Task stack =
new TaskBuilder(mSupervisor).setOnTop(!ON_TOP).setCreateActivity(true).build();
@@ -526,7 +548,7 @@ public class DisplayAreaTest extends WindowTestsBase {
// TDA is no longer handling orientation request, clear the last focused TDA.
tda.setIgnoreOrientationRequest(true /* ignoreOrientationRequest */);
- assertThat(mDisplayContent.getOrientationRequestingTaskDisplayArea()).isNull();
+ assertThat(mDisplayContent.getOrientationRequestingTaskDisplayArea()).isEqualTo(tda);
// TDA now handles orientation request, update last focused TDA based on the focused app.
tda.setIgnoreOrientationRequest(false /* ignoreOrientationRequest */);
diff --git a/services/tests/wmtests/src/com/android/server/wm/DualDisplayAreaGroupPolicyTest.java b/services/tests/wmtests/src/com/android/server/wm/DualDisplayAreaGroupPolicyTest.java
index 3ab4495bd7ca..232b9b2897cc 100644
--- a/services/tests/wmtests/src/com/android/server/wm/DualDisplayAreaGroupPolicyTest.java
+++ b/services/tests/wmtests/src/com/android/server/wm/DualDisplayAreaGroupPolicyTest.java
@@ -17,6 +17,8 @@
package com.android.server.wm;
import static android.content.pm.ActivityInfo.SCREEN_ORIENTATION_LANDSCAPE;
+import static android.content.pm.ActivityInfo.SCREEN_ORIENTATION_LOCKED;
+import static android.content.pm.ActivityInfo.SCREEN_ORIENTATION_NOSENSOR;
import static android.content.pm.ActivityInfo.SCREEN_ORIENTATION_PORTRAIT;
import static android.content.pm.ActivityInfo.SCREEN_ORIENTATION_UNSPECIFIED;
import static android.content.res.Configuration.ORIENTATION_LANDSCAPE;
@@ -163,6 +165,30 @@ public class DualDisplayAreaGroupPolicyTest extends WindowTestsBase {
}
@Test
+ public void testIgnoreOrientationRequest_displayReceiveOrientationChangeForNoSensor() {
+ mFirstRoot.setIgnoreOrientationRequest(true /* ignoreOrientationRequest */);
+ mSecondRoot.setIgnoreOrientationRequest(true /* ignoreOrientationRequest */);
+ mDisplay.onLastFocusedTaskDisplayAreaChanged(mFirstTda);
+
+ prepareUnresizable(mFirstActivity, SCREEN_ORIENTATION_NOSENSOR);
+
+ verify(mFirstRoot).onDescendantOrientationChanged(any());
+ verify(mDisplay).onDescendantOrientationChanged(any());
+ }
+
+ @Test
+ public void testIgnoreOrientationRequest_displayReceiveOrientationChangeForLocked() {
+ mFirstRoot.setIgnoreOrientationRequest(true /* ignoreOrientationRequest */);
+ mSecondRoot.setIgnoreOrientationRequest(true /* ignoreOrientationRequest */);
+ mDisplay.onLastFocusedTaskDisplayAreaChanged(mFirstTda);
+
+ prepareUnresizable(mFirstActivity, SCREEN_ORIENTATION_LOCKED);
+
+ verify(mFirstRoot).onDescendantOrientationChanged(any());
+ verify(mDisplay).onDescendantOrientationChanged(any());
+ }
+
+ @Test
public void testLaunchPortraitApp_fillsDisplayAreaGroup() {
mFirstRoot.setIgnoreOrientationRequest(true /* ignoreOrientationRequest */);
mSecondRoot.setIgnoreOrientationRequest(true /* ignoreOrientationRequest */);
@@ -215,6 +241,21 @@ public class DualDisplayAreaGroupPolicyTest extends WindowTestsBase {
}
@Test
+ public void testLaunchNoSensorApp_noSizeCompatAfterRotation() {
+ mFirstRoot.setIgnoreOrientationRequest(true /* ignoreOrientationRequest */);
+ mSecondRoot.setIgnoreOrientationRequest(true /* ignoreOrientationRequest */);
+ mDisplay.onLastFocusedTaskDisplayAreaChanged(mFirstTda);
+
+ prepareUnresizable(mFirstActivity, SCREEN_ORIENTATION_NOSENSOR);
+ assertThat(mFirstActivity.isLetterboxedForFixedOrientationAndAspectRatio()).isFalse();
+ assertThat(mFirstActivity.inSizeCompatMode()).isFalse();
+
+ rotateDisplay(mDisplay, ROTATION_90);
+ assertThat(mFirstActivity.isLetterboxedForFixedOrientationAndAspectRatio()).isFalse();
+ assertThat(mFirstActivity.inSizeCompatMode()).isFalse();
+ }
+
+ @Test
public void testLaunchLandscapeApp_activityIsLetterboxForFixedOrientationInDisplayAreaGroup() {
mFirstRoot.setIgnoreOrientationRequest(true /* ignoreOrientationRequest */);
mSecondRoot.setIgnoreOrientationRequest(true /* ignoreOrientationRequest */);
@@ -236,6 +277,26 @@ public class DualDisplayAreaGroupPolicyTest extends WindowTestsBase {
}
@Test
+ public void testLaunchNoSensorApp_activityIsNotLetterboxForFixedOrientationDisplayAreaGroup() {
+ mFirstRoot.setIgnoreOrientationRequest(true /* ignoreOrientationRequest */);
+ mSecondRoot.setIgnoreOrientationRequest(true /* ignoreOrientationRequest */);
+ mDisplay.onLastFocusedTaskDisplayAreaChanged(mFirstTda);
+
+ prepareUnresizable(mFirstActivity, SCREEN_ORIENTATION_NOSENSOR);
+ assertThat(mFirstActivity.isLetterboxedForFixedOrientationAndAspectRatio()).isFalse();
+ }
+
+ @Test
+ public void testLaunchLockedApp_activityIsNotLetterboxForFixedOrientationInDisplayAreaGroup() {
+ mFirstRoot.setIgnoreOrientationRequest(true /* ignoreOrientationRequest */);
+ mSecondRoot.setIgnoreOrientationRequest(true /* ignoreOrientationRequest */);
+ mDisplay.onLastFocusedTaskDisplayAreaChanged(mFirstTda);
+
+ prepareUnresizable(mFirstActivity, SCREEN_ORIENTATION_LOCKED);
+ assertThat(mFirstActivity.isLetterboxedForFixedOrientationAndAspectRatio()).isFalse();
+ }
+
+ @Test
public void testLaunchLandscapeApp_fixedOrientationLetterboxBecomesSizeCompatAfterRotation() {
mFirstRoot.setIgnoreOrientationRequest(true /* ignoreOrientationRequest */);
mSecondRoot.setIgnoreOrientationRequest(true /* ignoreOrientationRequest */);
@@ -265,6 +326,20 @@ public class DualDisplayAreaGroupPolicyTest extends WindowTestsBase {
}
@Test
+ public void testLaunchNoSensorApp_fixedOrientationLetterboxBecomesSizeCompatAfterRotation() {
+ mFirstRoot.setIgnoreOrientationRequest(true /* ignoreOrientationRequest */);
+ mSecondRoot.setIgnoreOrientationRequest(true /* ignoreOrientationRequest */);
+ mDisplay.onLastFocusedTaskDisplayAreaChanged(mFirstTda);
+
+ prepareUnresizable(mFirstActivity, SCREEN_ORIENTATION_NOSENSOR);
+
+ rotateDisplay(mDisplay, ROTATION_90);
+
+ assertThat(mFirstActivity.isLetterboxedForFixedOrientationAndAspectRatio()).isFalse();
+ assertThat(mFirstActivity.inSizeCompatMode()).isFalse();
+ }
+
+ @Test
public void testPlaceImeContainer_reparentToTargetDisplayAreaGroup() {
setupImeWindow();
final DisplayArea.Tokens imeContainer = mDisplay.getImeContainer();
diff --git a/services/tests/wmtests/src/com/android/server/wm/TaskDisplayAreaTests.java b/services/tests/wmtests/src/com/android/server/wm/TaskDisplayAreaTests.java
index e660db57fb69..582ddf21d7f9 100644
--- a/services/tests/wmtests/src/com/android/server/wm/TaskDisplayAreaTests.java
+++ b/services/tests/wmtests/src/com/android/server/wm/TaskDisplayAreaTests.java
@@ -29,8 +29,9 @@ import static android.app.WindowConfiguration.WINDOWING_MODE_UNDEFINED;
import static android.content.Intent.FLAG_ACTIVITY_LAUNCH_ADJACENT;
import static android.content.pm.ActivityInfo.FLAG_ALWAYS_FOCUSABLE;
import static android.content.pm.ActivityInfo.RESIZE_MODE_UNRESIZEABLE;
-import static android.content.pm.ActivityInfo.SCREEN_ORIENTATION_LANDSCAPE;
-import static android.content.pm.ActivityInfo.SCREEN_ORIENTATION_UNSET;
+import static android.content.pm.ActivityInfo.SCREEN_ORIENTATION_LOCKED;
+import static android.content.pm.ActivityInfo.SCREEN_ORIENTATION_NOSENSOR;
+import static android.content.pm.ActivityInfo.SCREEN_ORIENTATION_PORTRAIT;
import static android.window.DisplayAreaOrganizer.FEATURE_VENDOR_FIRST;
import static com.android.dx.mockito.inline.extended.ExtendedMockito.doReturn;
@@ -422,24 +423,63 @@ public class TaskDisplayAreaTests extends WindowTestsBase {
// Activity on TDA1 is focused
mDisplayContent.setFocusedApp(firstActivity);
- assertThat(firstTaskDisplayArea.canSpecifyOrientation()).isTrue();
- assertThat(secondTaskDisplayArea.canSpecifyOrientation()).isFalse();
+ final int testOrientation = SCREEN_ORIENTATION_PORTRAIT;
+
+ assertThat(firstTaskDisplayArea.canSpecifyOrientation(testOrientation)).isTrue();
+ assertThat(secondTaskDisplayArea.canSpecifyOrientation(testOrientation)).isFalse();
// No focused app, TDA1 is still recorded as last focused.
mDisplayContent.setFocusedApp(null);
- assertThat(firstTaskDisplayArea.canSpecifyOrientation()).isTrue();
- assertThat(secondTaskDisplayArea.canSpecifyOrientation()).isFalse();
+ assertThat(firstTaskDisplayArea.canSpecifyOrientation(testOrientation)).isTrue();
+ assertThat(secondTaskDisplayArea.canSpecifyOrientation(testOrientation)).isFalse();
// Activity on TDA2 is focused
mDisplayContent.setFocusedApp(secondActivity);
- assertThat(firstTaskDisplayArea.canSpecifyOrientation()).isFalse();
- assertThat(secondTaskDisplayArea.canSpecifyOrientation()).isTrue();
+ assertThat(firstTaskDisplayArea.canSpecifyOrientation(testOrientation)).isFalse();
+ assertThat(secondTaskDisplayArea.canSpecifyOrientation(testOrientation)).isTrue();
+ }
+
+ @Test
+ public void testCanSpecifyOrientation() {
+ final TaskDisplayArea firstTaskDisplayArea = mDisplayContent.getDefaultTaskDisplayArea();
+ final TaskDisplayArea secondTaskDisplayArea = createTaskDisplayArea(
+ mDisplayContent, mRootWindowContainer.mWmService, "TestTaskDisplayArea",
+ FEATURE_VENDOR_FIRST);
+ final Task firstRootTask = firstTaskDisplayArea.createRootTask(
+ WINDOWING_MODE_FULLSCREEN, ACTIVITY_TYPE_STANDARD, false /* onTop */);
+ final Task secondRootTask = secondTaskDisplayArea.createRootTask(
+ WINDOWING_MODE_FULLSCREEN, ACTIVITY_TYPE_STANDARD, false /* onTop */);
+ final ActivityRecord firstActivity = new ActivityBuilder(mAtm)
+ .setTask(firstRootTask).build();
+ final ActivityRecord secondActivity = new ActivityBuilder(mAtm)
+ .setTask(secondRootTask).build();
+ firstTaskDisplayArea.setIgnoreOrientationRequest(true /* ignoreOrientationRequest */);
+ secondTaskDisplayArea.setIgnoreOrientationRequest(false /* ignoreOrientationRequest */);
+
+ final int testOrientation = SCREEN_ORIENTATION_PORTRAIT;
+
+ // Activity on TDA1 is focused, but TDA1 cannot specify orientation because
+ // ignoreOrientationRequest is true
+ // Activity on TDA2 has ignoreOrientationRequest false but it doesn't have focus so it
+ // cannot specify orientation
+ mDisplayContent.setFocusedApp(firstActivity);
+
+ assertThat(firstTaskDisplayArea.canSpecifyOrientation(testOrientation)).isFalse();
+ assertThat(secondTaskDisplayArea.canSpecifyOrientation(testOrientation)).isFalse();
+
+ // Activity on TDA1 is not focused, and so it cannot specify orientation
+ // Activity on TDA2 is focused, and it can specify orientation because
+ // ignoreOrientationRequest is false
+ mDisplayContent.setFocusedApp(secondActivity);
+
+ assertThat(firstTaskDisplayArea.canSpecifyOrientation(testOrientation)).isFalse();
+ assertThat(secondTaskDisplayArea.canSpecifyOrientation(testOrientation)).isTrue();
}
@Test
- public void testIsLastFocused_onlyCountIfTaskDisplayAreaHandlesOrientationRequest() {
+ public void testCanSpecifyOrientationNoSensor() {
final TaskDisplayArea firstTaskDisplayArea = mDisplayContent.getDefaultTaskDisplayArea();
final TaskDisplayArea secondTaskDisplayArea = createTaskDisplayArea(
mDisplayContent, mRootWindowContainer.mWmService, "TestTaskDisplayArea",
@@ -455,34 +495,51 @@ public class TaskDisplayAreaTests extends WindowTestsBase {
firstTaskDisplayArea.setIgnoreOrientationRequest(true /* ignoreOrientationRequest */);
secondTaskDisplayArea.setIgnoreOrientationRequest(false /* ignoreOrientationRequest */);
- // Activity on TDA1 is focused, but TDA1 doesn't respect orientation request
+ final int testOrientation = SCREEN_ORIENTATION_NOSENSOR;
+
+ // ignoreOrientationRequest is always false for SCREEN_ORIENTATION_NOSENSOR so
+ // only the TDAs with focus can specify orientations
mDisplayContent.setFocusedApp(firstActivity);
- assertThat(firstTaskDisplayArea.canSpecifyOrientation()).isFalse();
- assertThat(secondTaskDisplayArea.canSpecifyOrientation()).isFalse();
+ assertThat(firstTaskDisplayArea.canSpecifyOrientation(testOrientation)).isTrue();
+ assertThat(secondTaskDisplayArea.canSpecifyOrientation(testOrientation)).isFalse();
- // Activity on TDA2 is focused, and TDA2 respects orientation request
mDisplayContent.setFocusedApp(secondActivity);
- assertThat(firstTaskDisplayArea.canSpecifyOrientation()).isFalse();
- assertThat(secondTaskDisplayArea.canSpecifyOrientation()).isTrue();
+ assertThat(firstTaskDisplayArea.canSpecifyOrientation(testOrientation)).isFalse();
+ assertThat(secondTaskDisplayArea.canSpecifyOrientation(testOrientation)).isTrue();
}
@Test
- public void testIgnoreOrientationRequest() {
- final TaskDisplayArea taskDisplayArea = mDisplayContent.getDefaultTaskDisplayArea();
- final Task task = taskDisplayArea.createRootTask(
+ public void testCanSpecifyOrientationLocked() {
+ final TaskDisplayArea firstTaskDisplayArea = mDisplayContent.getDefaultTaskDisplayArea();
+ final TaskDisplayArea secondTaskDisplayArea = createTaskDisplayArea(
+ mDisplayContent, mRootWindowContainer.mWmService, "TestTaskDisplayArea",
+ FEATURE_VENDOR_FIRST);
+ final Task firstRootTask = firstTaskDisplayArea.createRootTask(
WINDOWING_MODE_FULLSCREEN, ACTIVITY_TYPE_STANDARD, false /* onTop */);
- final ActivityRecord activity = new ActivityBuilder(mAtm).setTask(task).build();
+ final Task secondRootTask = secondTaskDisplayArea.createRootTask(
+ WINDOWING_MODE_FULLSCREEN, ACTIVITY_TYPE_STANDARD, false /* onTop */);
+ final ActivityRecord firstActivity = new ActivityBuilder(mAtm)
+ .setTask(firstRootTask).build();
+ final ActivityRecord secondActivity = new ActivityBuilder(mAtm)
+ .setTask(secondRootTask).build();
+ firstTaskDisplayArea.setIgnoreOrientationRequest(true /* ignoreOrientationRequest */);
+ secondTaskDisplayArea.setIgnoreOrientationRequest(false /* ignoreOrientationRequest */);
- mDisplayContent.setFocusedApp(activity);
- activity.setRequestedOrientation(SCREEN_ORIENTATION_LANDSCAPE);
+ final int testOrientation = SCREEN_ORIENTATION_LOCKED;
- assertThat(taskDisplayArea.getOrientation()).isEqualTo(SCREEN_ORIENTATION_LANDSCAPE);
+ // ignoreOrientationRequest is always false for SCREEN_ORIENTATION_NOSENSOR so
+ // only the TDAs with focus can specify orientations
+ mDisplayContent.setFocusedApp(firstActivity);
- taskDisplayArea.setIgnoreOrientationRequest(true /* ignoreOrientationRequest */);
+ assertThat(firstTaskDisplayArea.canSpecifyOrientation(testOrientation)).isTrue();
+ assertThat(secondTaskDisplayArea.canSpecifyOrientation(testOrientation)).isFalse();
+
+ mDisplayContent.setFocusedApp(secondActivity);
- assertThat(taskDisplayArea.getOrientation()).isEqualTo(SCREEN_ORIENTATION_UNSET);
+ assertThat(firstTaskDisplayArea.canSpecifyOrientation(testOrientation)).isFalse();
+ assertThat(secondTaskDisplayArea.canSpecifyOrientation(testOrientation)).isTrue();
}
@Test
diff --git a/services/tests/wmtests/src/com/android/server/wm/TaskTests.java b/services/tests/wmtests/src/com/android/server/wm/TaskTests.java
index 0c8e89a8d010..eac67770cf36 100644
--- a/services/tests/wmtests/src/com/android/server/wm/TaskTests.java
+++ b/services/tests/wmtests/src/com/android/server/wm/TaskTests.java
@@ -57,6 +57,7 @@ import static org.junit.Assert.assertNull;
import static org.junit.Assert.assertTrue;
import static org.mockito.ArgumentMatchers.any;
import static org.mockito.ArgumentMatchers.anyBoolean;
+import static org.mockito.ArgumentMatchers.anyInt;
import static org.mockito.ArgumentMatchers.anyString;
import static org.mockito.ArgumentMatchers.eq;
import static org.mockito.ArgumentMatchers.same;
@@ -392,12 +393,16 @@ public class TaskTests extends WindowTestsBase {
leafTask1.getWindowConfiguration().setActivityType(ACTIVITY_TYPE_HOME);
leafTask2.getWindowConfiguration().setActivityType(ACTIVITY_TYPE_STANDARD);
+ // We need to use an orientation that is not an exception for the
+ // ignoreOrientationRequest flag.
+ final int orientation = SCREEN_ORIENTATION_PORTRAIT;
+
assertEquals(leafTask2, rootTask.getTopChild());
- assertTrue(rootTask.handlesOrientationChangeFromDescendant());
+ assertTrue(rootTask.handlesOrientationChangeFromDescendant(orientation));
// Treat orientation request from home as handled.
- assertTrue(leafTask1.handlesOrientationChangeFromDescendant());
+ assertTrue(leafTask1.handlesOrientationChangeFromDescendant(orientation));
// Orientation request from standard activity in multi window will not be handled.
- assertFalse(leafTask2.handlesOrientationChangeFromDescendant());
+ assertFalse(leafTask2.handlesOrientationChangeFromDescendant(orientation));
}
@Test
@@ -636,7 +641,8 @@ public class TaskTests extends WindowTestsBase {
doReturn(parentWindowContainer).when(task).getParent();
doReturn(display.getDefaultTaskDisplayArea()).when(task).getDisplayArea();
doReturn(rootTask).when(task).getRootTask();
- doReturn(true).when(parentWindowContainer).handlesOrientationChangeFromDescendant();
+ doReturn(true).when(parentWindowContainer)
+ .handlesOrientationChangeFromDescendant(anyInt());
// Setting app to fixed portrait fits within parent, but Task shouldn't adjust the
// bounds because its parent says it will handle it at a later time.
diff --git a/services/tests/wmtests/src/com/android/server/wm/WindowContainerTests.java b/services/tests/wmtests/src/com/android/server/wm/WindowContainerTests.java
index ef3ddb7b1302..ed7d12384662 100644
--- a/services/tests/wmtests/src/com/android/server/wm/WindowContainerTests.java
+++ b/services/tests/wmtests/src/com/android/server/wm/WindowContainerTests.java
@@ -662,13 +662,13 @@ public class WindowContainerTests extends WindowTestsBase {
public void testSetOrientation() {
final TestWindowContainer root = spy(new TestWindowContainerBuilder(mWm).build());
final TestWindowContainer child = spy(root.addChildWindow());
- doReturn(true).when(root).handlesOrientationChangeFromDescendant();
+ doReturn(true).when(root).handlesOrientationChangeFromDescendant(anyInt());
child.getWindowConfiguration().setWindowingMode(WINDOWING_MODE_FULLSCREEN);
child.setOrientation(SCREEN_ORIENTATION_PORTRAIT);
// The ancestor should decide whether to dispatch the configuration change.
verify(child, never()).onConfigurationChanged(any());
- doReturn(false).when(root).handlesOrientationChangeFromDescendant();
+ doReturn(false).when(root).handlesOrientationChangeFromDescendant(anyInt());
child.setOrientation(SCREEN_ORIENTATION_LANDSCAPE);
// The ancestor doesn't handle the request so the descendant applies the change directly.
verify(child).onConfigurationChanged(any());
@@ -843,11 +843,14 @@ public class WindowContainerTests extends WindowTestsBase {
final TestWindowContainerBuilder builder = new TestWindowContainerBuilder(mWm);
final TestWindowContainer root = spy(builder.build());
+ // We use an orientation that is not an exception for the ignoreOrientationRequest flag
+ final int orientation = SCREEN_ORIENTATION_PORTRAIT;
+
final TestWindowContainer child = root.addChildWindow();
- assertFalse(child.handlesOrientationChangeFromDescendant());
+ assertFalse(child.handlesOrientationChangeFromDescendant(orientation));
- Mockito.doReturn(true).when(root).handlesOrientationChangeFromDescendant();
- assertTrue(child.handlesOrientationChangeFromDescendant());
+ Mockito.doReturn(true).when(root).handlesOrientationChangeFromDescendant(anyInt());
+ assertTrue(child.handlesOrientationChangeFromDescendant(orientation));
}
@Test