summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
author Chris Li <lihongyu@google.com> 2020-09-14 12:45:11 -0700
committer Chris Li <lihongyu@google.com> 2020-09-22 17:01:39 -0700
commit3dbefb99c4669b4e8a0b28296ac18d8064213ea0 (patch)
tree2500a73b396d034ba79c4a43750a68de07340bff
parentf747948b6d1fc080bcd11c83555eaafd4ed7441d (diff)
Add option to always ignore orientation request
(2/n Orientation on DisplayAreaGroup) When the option is set to true, the TDA will ignore all the fixed-orientation request from apps. This can be used on duo display device, so that the logical display will not be rotated when launching a fixed-orientation app on one of the display. Bug: 155431879 Test: manual: test with dual-display-area policy Test: atest WmTests:TaskDisplayAreaTests Test: atest WmTests:WindowOrganizerTests Change-Id: I3f0ea1415523926195b51fe28744974a9b64d803
-rw-r--r--core/java/android/window/WindowContainerTransaction.java35
-rw-r--r--services/core/java/com/android/server/wm/TaskDisplayArea.java31
-rw-r--r--services/core/java/com/android/server/wm/WindowOrganizerController.java17
-rw-r--r--services/tests/wmtests/src/com/android/server/wm/TaskDisplayAreaTests.java20
-rw-r--r--services/tests/wmtests/src/com/android/server/wm/WindowOrganizerTests.java44
5 files changed, 143 insertions, 4 deletions
diff --git a/core/java/android/window/WindowContainerTransaction.java b/core/java/android/window/WindowContainerTransaction.java
index 8be37e9e492d..ba901549f2b5 100644
--- a/core/java/android/window/WindowContainerTransaction.java
+++ b/core/java/android/window/WindowContainerTransaction.java
@@ -238,6 +238,22 @@ public final class WindowContainerTransaction implements Parcelable {
}
/**
+ * Sets whether a container should ignore the orientation request from apps below it. It
+ * currently only applies to {@link com.android.server.wm.TaskDisplayArea}. When {@code false},
+ * it may rotate based on the orientation request; When {@code true}, it can never specify
+ * orientation, but shows the fixed-orientation apps in the letterbox.
+ * @hide
+ */
+ @NonNull
+ public WindowContainerTransaction setIgnoreOrientationRequest(
+ @NonNull WindowContainerToken container, boolean ignoreOrientationRequest) {
+ Change chg = getOrCreateChange(container.asBinder());
+ chg.mIgnoreOrientationRequest = ignoreOrientationRequest;
+ chg.mChangeMask |= Change.CHANGE_IGNORE_ORIENTATION_REQUEST;
+ return this;
+ }
+
+ /**
* Reparents a container into another one. The effect of a {@code null} parent can vary. For
* example, reparenting a stack to {@code null} will reparent it to its display.
*
@@ -341,10 +357,12 @@ public final class WindowContainerTransaction implements Parcelable {
public static final int CHANGE_PIP_CALLBACK = 1 << 2;
public static final int CHANGE_HIDDEN = 1 << 3;
public static final int CHANGE_BOUNDS_TRANSACTION_RECT = 1 << 4;
+ public static final int CHANGE_IGNORE_ORIENTATION_REQUEST = 1 << 5;
private final Configuration mConfiguration = new Configuration();
private boolean mFocusable = true;
private boolean mHidden = false;
+ private boolean mIgnoreOrientationRequest = false;
private int mChangeMask = 0;
private @ActivityInfo.Config int mConfigSetMask = 0;
private @WindowConfiguration.WindowConfig int mWindowSetMask = 0;
@@ -362,6 +380,7 @@ public final class WindowContainerTransaction implements Parcelable {
mConfiguration.readFromParcel(in);
mFocusable = in.readBoolean();
mHidden = in.readBoolean();
+ mIgnoreOrientationRequest = in.readBoolean();
mChangeMask = in.readInt();
mConfigSetMask = in.readInt();
mWindowSetMask = in.readInt();
@@ -404,6 +423,9 @@ public final class WindowContainerTransaction implements Parcelable {
if ((other.mChangeMask & CHANGE_HIDDEN) != 0) {
mHidden = other.mHidden;
}
+ if ((other.mChangeMask & CHANGE_IGNORE_ORIENTATION_REQUEST) != 0) {
+ mIgnoreOrientationRequest = other.mIgnoreOrientationRequest;
+ }
mChangeMask |= other.mChangeMask;
if (other.mActivityWindowingMode >= 0) {
mActivityWindowingMode = other.mActivityWindowingMode;
@@ -445,6 +467,15 @@ public final class WindowContainerTransaction implements Parcelable {
return mHidden;
}
+ /** Gets the requested state of whether to ignore orientation request. */
+ public boolean getIgnoreOrientationRequest() {
+ if ((mChangeMask & CHANGE_IGNORE_ORIENTATION_REQUEST) == 0) {
+ throw new RuntimeException("IgnoreOrientationRequest not set. "
+ + "Check CHANGE_IGNORE_ORIENTATION_REQUEST first");
+ }
+ return mIgnoreOrientationRequest;
+ }
+
public int getChangeMask() {
return mChangeMask;
}
@@ -509,6 +540,9 @@ public final class WindowContainerTransaction implements Parcelable {
if (mBoundsChangeTransaction != null) {
sb.append("hasBoundsTransaction,");
}
+ if ((mChangeMask & CHANGE_IGNORE_ORIENTATION_REQUEST) != 0) {
+ sb.append("ignoreOrientationRequest:" + mIgnoreOrientationRequest + ",");
+ }
sb.append("}");
return sb.toString();
}
@@ -518,6 +552,7 @@ public final class WindowContainerTransaction implements Parcelable {
mConfiguration.writeToParcel(dest, flags);
dest.writeBoolean(mFocusable);
dest.writeBoolean(mHidden);
+ dest.writeBoolean(mIgnoreOrientationRequest);
dest.writeInt(mChangeMask);
dest.writeInt(mConfigSetMask);
dest.writeInt(mWindowSetMask);
diff --git a/services/core/java/com/android/server/wm/TaskDisplayArea.java b/services/core/java/com/android/server/wm/TaskDisplayArea.java
index c11624c92117..5239b1f87bea 100644
--- a/services/core/java/com/android/server/wm/TaskDisplayArea.java
+++ b/services/core/java/com/android/server/wm/TaskDisplayArea.java
@@ -151,6 +151,12 @@ final class TaskDisplayArea extends DisplayArea<Task> {
*/
private boolean mRemoved;
+ /**
+ * Whether the task display area should ignore fixed-orientation request. If {@code true}, it
+ * can never specify orientation, but show the fixed-orientation apps in the letterbox;
+ * otherwise, it rotates based on the fixed-orientation request when it has the focus.
+ */
+ private boolean mIgnoreOrientationRequest;
/**
* The id of a leaf task that most recently being moved to front.
@@ -641,11 +647,30 @@ final class TaskDisplayArea extends DisplayArea<Task> {
}
}
+ /**
+ * Sets whether the task display area should ignore fixed-orientation request from apps.
+ * @return Whether the display orientation changed
+ */
+ boolean setIgnoreOrientationRequest(boolean ignoreOrientationRequest) {
+ if (mIgnoreOrientationRequest == ignoreOrientationRequest) {
+ return false;
+ }
+
+ mIgnoreOrientationRequest = ignoreOrientationRequest;
+ if (isLastFocused()) {
+ // Update orientation if this TDA is the last focused, otherwise it shouldn't affect
+ // the display.
+ return mDisplayContent.updateOrientation();
+ }
+
+ return false;
+ }
+
@Override
int getOrientation(int candidate) {
- // Only allow to specify orientation if this TDA has the focus.
- // TODO(b/155431879) Add option to never allow a TDA to specify orientation.
- if (!isLastFocused()) {
+ // Only allow to specify orientation if this TDA is not set to ignore orientation request,
+ // and it has the focus.
+ if (mIgnoreOrientationRequest || !isLastFocused()) {
return SCREEN_ORIENTATION_UNSET;
}
diff --git a/services/core/java/com/android/server/wm/WindowOrganizerController.java b/services/core/java/com/android/server/wm/WindowOrganizerController.java
index c7cad2f76486..999181dc486c 100644
--- a/services/core/java/com/android/server/wm/WindowOrganizerController.java
+++ b/services/core/java/com/android/server/wm/WindowOrganizerController.java
@@ -306,6 +306,19 @@ class WindowOrganizerController extends IWindowOrganizerController.Stub
return effects;
}
+ private int applyTaskDisplayAreaChanges(TaskDisplayArea taskDisplayArea,
+ WindowContainerTransaction.Change c) {
+ int effects = applyDisplayAreaChanges(taskDisplayArea, c);
+ if ((c.getChangeMask()
+ & WindowContainerTransaction.Change.CHANGE_IGNORE_ORIENTATION_REQUEST) != 0) {
+ if (taskDisplayArea.setIgnoreOrientationRequest(c.getIgnoreOrientationRequest())) {
+ effects |= TRANSACT_EFFECTS_LIFECYCLE;
+ }
+ }
+
+ return effects;
+ }
+
private int applyDisplayAreaChanges(WindowContainer container,
WindowContainerTransaction.Change c) {
final int[] effects = new int[1];
@@ -388,7 +401,9 @@ class WindowOrganizerController extends IWindowOrganizerController.Stub
int effects = applyChanges(wc, c);
- if (wc instanceof DisplayArea) {
+ if (wc instanceof TaskDisplayArea) {
+ effects |= applyTaskDisplayAreaChanges((TaskDisplayArea) wc, c);
+ } else if (wc instanceof DisplayArea) {
effects |= applyDisplayAreaChanges(wc, c);
} else if (wc instanceof Task) {
effects |= applyTaskChanges(wc.asTask(), c);
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 e71f7ec54b0e..8b025e34401a 100644
--- a/services/tests/wmtests/src/com/android/server/wm/TaskDisplayAreaTests.java
+++ b/services/tests/wmtests/src/com/android/server/wm/TaskDisplayAreaTests.java
@@ -29,6 +29,8 @@ import static android.app.WindowConfiguration.WINDOWING_MODE_SPLIT_SCREEN_PRIMAR
import static android.app.WindowConfiguration.WINDOWING_MODE_SPLIT_SCREEN_SECONDARY;
import static android.app.WindowConfiguration.WINDOWING_MODE_UNDEFINED;
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.window.DisplayAreaOrganizer.FEATURE_VENDOR_FIRST;
import static com.android.dx.mockito.inline.extended.ExtendedMockito.doReturn;
@@ -277,6 +279,24 @@ public class TaskDisplayAreaTests extends WindowTestsBase {
assertThat(secondTaskDisplayArea.isLastFocused()).isTrue();
}
+ @Test
+ public void testIgnoreOrientationRequest() {
+ final TaskDisplayArea taskDisplayArea = mDisplayContent.getDefaultTaskDisplayArea();
+ final Task stack = taskDisplayArea.createStack(
+ WINDOWING_MODE_FULLSCREEN, ACTIVITY_TYPE_STANDARD, false /* onTop */);
+ final ActivityRecord activity = new ActivityBuilder(mAtm).setCreateTask(true)
+ .setStack(stack).build();
+
+ mDisplayContent.setFocusedApp(activity);
+ activity.setRequestedOrientation(SCREEN_ORIENTATION_LANDSCAPE);
+
+ assertThat(taskDisplayArea.getOrientation()).isEqualTo(SCREEN_ORIENTATION_LANDSCAPE);
+
+ taskDisplayArea.setIgnoreOrientationRequest(true /* ignoreOrientationRequest */);
+
+ assertThat(taskDisplayArea.getOrientation()).isEqualTo(SCREEN_ORIENTATION_UNSET);
+ }
+
private void assertGetOrCreateStack(int windowingMode, int activityType, Task candidateTask,
boolean reuseCandidate) {
final TaskDisplayArea taskDisplayArea = candidateTask.getDisplayArea();
diff --git a/services/tests/wmtests/src/com/android/server/wm/WindowOrganizerTests.java b/services/tests/wmtests/src/com/android/server/wm/WindowOrganizerTests.java
index 11eaf8c5cea5..0152fc607f73 100644
--- a/services/tests/wmtests/src/com/android/server/wm/WindowOrganizerTests.java
+++ b/services/tests/wmtests/src/com/android/server/wm/WindowOrganizerTests.java
@@ -26,6 +26,9 @@ import static android.app.WindowConfiguration.WINDOWING_MODE_PINNED;
import static android.app.WindowConfiguration.WINDOWING_MODE_SPLIT_SCREEN_PRIMARY;
import static android.app.WindowConfiguration.WINDOWING_MODE_SPLIT_SCREEN_SECONDARY;
import static android.app.WindowConfiguration.WINDOWING_MODE_UNDEFINED;
+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_UNSPECIFIED;
import static android.content.res.Configuration.SCREEN_HEIGHT_DP_UNDEFINED;
import static android.content.res.Configuration.SCREEN_WIDTH_DP_UNDEFINED;
import static android.view.WindowManager.LayoutParams.TYPE_APPLICATION;
@@ -42,6 +45,8 @@ import static com.android.dx.mockito.inline.extended.ExtendedMockito.when;
import static com.android.server.wm.DisplayArea.Type.ABOVE_TASKS;
import static com.android.server.wm.WindowContainer.POSITION_TOP;
+import static com.google.common.truth.Truth.assertThat;
+
import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertFalse;
import static org.junit.Assert.assertNotNull;
@@ -361,6 +366,45 @@ public class WindowOrganizerTests extends WindowTestsBase {
}
@Test
+ public void testSetIgnoreOrientationRequest() {
+ removeGlobalMinSizeRestriction();
+ final TaskDisplayArea taskDisplayArea = mDisplayContent.getDefaultTaskDisplayArea();
+ final Task stack = taskDisplayArea.createStack(
+ WINDOWING_MODE_FULLSCREEN, ACTIVITY_TYPE_STANDARD, false /* onTop */);
+ final ActivityRecord activity = new ActivityBuilder(mAtm).setCreateTask(true)
+ .setStack(stack).build();
+ taskDisplayArea.setIgnoreOrientationRequest(true /* ignoreOrientationRequest */);
+ mDisplayContent.setFocusedApp(activity);
+ activity.setRequestedOrientation(SCREEN_ORIENTATION_LANDSCAPE);
+
+ // TDA returns UNSET when ignoreOrientationRequest == true
+ // DC is UNSPECIFIED because it is using the previous (default) when TDA returns UNSET.
+ assertThat(taskDisplayArea.getOrientation()).isEqualTo(SCREEN_ORIENTATION_UNSET);
+ assertThat(mDisplayContent.getLastOrientation()).isEqualTo(SCREEN_ORIENTATION_UNSPECIFIED);
+
+ WindowContainerTransaction t = new WindowContainerTransaction();
+ t.setIgnoreOrientationRequest(
+ taskDisplayArea.mRemoteToken.toWindowContainerToken(),
+ false /* ignoreOrientationRequest */);
+ mWm.mAtmService.mWindowOrganizerController.applyTransaction(t);
+
+ // TDA returns app request orientation when ignoreOrientationRequest == false
+ // DC uses the same as TDA returns when it is not UNSET.
+ assertThat(mDisplayContent.getLastOrientation()).isEqualTo(SCREEN_ORIENTATION_LANDSCAPE);
+ assertThat(taskDisplayArea.getOrientation()).isEqualTo(SCREEN_ORIENTATION_LANDSCAPE);
+
+ t.setIgnoreOrientationRequest(
+ taskDisplayArea.mRemoteToken.toWindowContainerToken(),
+ true /* ignoreOrientationRequest */);
+ mWm.mAtmService.mWindowOrganizerController.applyTransaction(t);
+
+ // TDA returns UNSET when ignoreOrientationRequest == true
+ // DC is LANDSCAPE because it is using the previous when TDA returns UNSET.
+ assertThat(taskDisplayArea.getOrientation()).isEqualTo(SCREEN_ORIENTATION_UNSET);
+ assertThat(mDisplayContent.getLastOrientation()).isEqualTo(SCREEN_ORIENTATION_LANDSCAPE);
+ }
+
+ @Test
public void testOverrideConfigSize() {
removeGlobalMinSizeRestriction();
final Task stack = new TaskBuilder(mSupervisor)