summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--data/etc/services.core.protolog.json24
-rw-r--r--services/core/java/com/android/server/wm/DisplayContent.java38
-rw-r--r--services/core/java/com/android/server/wm/TaskDisplayArea.java30
-rw-r--r--services/tests/wmtests/src/com/android/server/wm/SystemServicesTestRule.java3
-rw-r--r--services/tests/wmtests/src/com/android/server/wm/TaskDisplayAreaTests.java35
-rw-r--r--services/tests/wmtests/src/com/android/server/wm/TaskRecordTests.java39
-rw-r--r--services/tests/wmtests/src/com/android/server/wm/TestDisplayContent.java4
7 files changed, 142 insertions, 31 deletions
diff --git a/data/etc/services.core.protolog.json b/data/etc/services.core.protolog.json
index 217de84cfc3e..6b80bb60ec67 100644
--- a/data/etc/services.core.protolog.json
+++ b/data/etc/services.core.protolog.json
@@ -259,6 +259,12 @@
"group": "WM_DEBUG_ORIENTATION",
"at": "com\/android\/server\/wm\/WindowState.java"
},
+ "-1741065110": {
+ "message": "No app is requesting an orientation, return %d for display id=%d",
+ "level": "VERBOSE",
+ "group": "WM_DEBUG_ORIENTATION",
+ "at": "com\/android\/server\/wm\/DisplayContent.java"
+ },
"-1730156332": {
"message": "Display id=%d rotation changed to %d from %d, lastOrientation=%d",
"level": "VERBOSE",
@@ -1909,6 +1915,12 @@
"group": "WM_ERROR",
"at": "com\/android\/server\/wm\/WindowToken.java"
},
+ "845234215": {
+ "message": "App is requesting an orientation, return %d for display id=%d",
+ "level": "VERBOSE",
+ "group": "WM_DEBUG_ORIENTATION",
+ "at": "com\/android\/server\/wm\/DisplayContent.java"
+ },
"853091290": {
"message": "Moved stack=%s behind stack=%s",
"level": "DEBUG",
@@ -2179,12 +2191,6 @@
"group": "WM_DEBUG_IME",
"at": "com\/android\/server\/wm\/ImeInsetsSourceProvider.java"
},
- "1381227466": {
- "message": "App is requesting an orientation, return %d for display id=%d",
- "level": "VERBOSE",
- "group": "WM_DEBUG_ORIENTATION",
- "at": "com\/android\/server\/wm\/TaskDisplayArea.java"
- },
"1401295262": {
"message": "Mode default, asking user",
"level": "WARN",
@@ -2371,12 +2377,6 @@
"group": "WM_DEBUG_RESIZE",
"at": "com\/android\/server\/wm\/WindowState.java"
},
- "1640436199": {
- "message": "No app is requesting an orientation, return %d for display id=%d",
- "level": "VERBOSE",
- "group": "WM_DEBUG_ORIENTATION",
- "at": "com\/android\/server\/wm\/TaskDisplayArea.java"
- },
"1653210583": {
"message": "Removing app %s delayed=%b animation=%s animating=%b",
"level": "VERBOSE",
diff --git a/services/core/java/com/android/server/wm/DisplayContent.java b/services/core/java/com/android/server/wm/DisplayContent.java
index 0044d7498614..0be5cbe5199c 100644
--- a/services/core/java/com/android/server/wm/DisplayContent.java
+++ b/services/core/java/com/android/server/wm/DisplayContent.java
@@ -28,6 +28,8 @@ import static android.app.WindowConfiguration.WINDOWING_MODE_MULTI_WINDOW;
import static android.app.WindowConfiguration.WINDOWING_MODE_PINNED;
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_BEHIND;
+import static android.content.pm.ActivityInfo.SCREEN_ORIENTATION_UNSET;
import static android.content.res.Configuration.ORIENTATION_LANDSCAPE;
import static android.content.res.Configuration.ORIENTATION_PORTRAIT;
import static android.content.res.Configuration.ORIENTATION_UNDEFINED;
@@ -464,6 +466,9 @@ class DisplayContent extends RootDisplayArea implements WindowManagerPolicy.Disp
*/
ActivityRecord mFocusedApp = null;
+ /** The last focused {@link TaskDisplayArea} on this display. */
+ private TaskDisplayArea mLastFocusedTaskDisplayArea = null;
+
/**
* The launching activity which is using fixed rotation transformation.
*
@@ -2327,7 +2332,21 @@ class DisplayContent extends RootDisplayArea implements WindowManagerPolicy.Disp
return getLastOrientation();
}
}
- return super.getOrientation();
+
+ final int orientation = super.getOrientation();
+ if (orientation != SCREEN_ORIENTATION_UNSET && orientation != SCREEN_ORIENTATION_BEHIND) {
+ ProtoLog.v(WM_DEBUG_ORIENTATION,
+ "App is requesting an orientation, return %d for display id=%d",
+ orientation, mDisplayId);
+ return orientation;
+ }
+
+ ProtoLog.v(WM_DEBUG_ORIENTATION,
+ "No app is requesting an orientation, return %d for display id=%d",
+ getLastOrientation(), mDisplayId);
+ // The next app has not been requested to be visible, so we keep the current orientation
+ // to prevent freezing/unfreezing the display too early.
+ return getLastOrientation();
}
void updateDisplayInfo() {
@@ -3202,6 +3221,10 @@ class DisplayContent extends RootDisplayArea implements WindowManagerPolicy.Disp
throw new IllegalStateException(newFocus + " is not on " + getName()
+ " but " + ((appDisplay != null) ? appDisplay.getName() : "none"));
}
+
+ // Called even if the focused app is not changed in case the app is moved to a different
+ // TaskDisplayArea.
+ setLastFocusedTaskDisplayArea(newFocus.getDisplayArea());
}
if (mFocusedApp == newFocus) {
return false;
@@ -3214,6 +3237,19 @@ class DisplayContent extends RootDisplayArea implements WindowManagerPolicy.Disp
return true;
}
+ /** Called when the focused {@link TaskDisplayArea} on this display may have changed. */
+ @VisibleForTesting
+ void setLastFocusedTaskDisplayArea(@Nullable TaskDisplayArea taskDisplayArea) {
+ if (taskDisplayArea != null) {
+ mLastFocusedTaskDisplayArea = taskDisplayArea;
+ }
+ }
+
+ /** Gets the last focused {@link TaskDisplayArea} on this display. */
+ TaskDisplayArea getLastFocusedTaskDisplayArea() {
+ return mLastFocusedTaskDisplayArea;
+ }
+
/** Updates the layer assignment of windows on this display. */
void assignWindowLayers(boolean setLayoutNeeded) {
Trace.traceBegin(TRACE_TAG_WINDOW_MANAGER, "assignWindowLayers");
diff --git a/services/core/java/com/android/server/wm/TaskDisplayArea.java b/services/core/java/com/android/server/wm/TaskDisplayArea.java
index 0d77d1c2cd89..c11624c92117 100644
--- a/services/core/java/com/android/server/wm/TaskDisplayArea.java
+++ b/services/core/java/com/android/server/wm/TaskDisplayArea.java
@@ -29,12 +29,10 @@ 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.app.WindowConfiguration.isSplitScreenWindowingMode;
-import static android.content.pm.ActivityInfo.SCREEN_ORIENTATION_BEHIND;
import static android.content.pm.ActivityInfo.SCREEN_ORIENTATION_UNSET;
import static android.content.pm.ActivityInfo.SCREEN_ORIENTATION_UNSPECIFIED;
import static com.android.internal.protolog.ProtoLogGroup.WM_DEBUG_ADD_REMOVE;
-import static com.android.internal.protolog.ProtoLogGroup.WM_DEBUG_ORIENTATION;
import static com.android.server.wm.ActivityStackSupervisor.TAG_TASKS;
import static com.android.server.wm.ActivityTaskManagerDebugConfig.DEBUG_STATES;
import static com.android.server.wm.ActivityTaskManagerDebugConfig.DEBUG_TASKS;
@@ -645,6 +643,12 @@ final class TaskDisplayArea extends DisplayArea<Task> {
@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()) {
+ return SCREEN_ORIENTATION_UNSET;
+ }
+
if (isStackVisible(WINDOWING_MODE_SPLIT_SCREEN_PRIMARY)) {
// Apps and their containers are not allowed to specify an orientation while using
// root tasks...except for the home stack if it is not resizable and currently
@@ -671,21 +675,7 @@ final class TaskDisplayArea extends DisplayArea<Task> {
return SCREEN_ORIENTATION_UNSPECIFIED;
}
- final int orientation = super.getOrientation(candidate);
- if (orientation != SCREEN_ORIENTATION_UNSET
- && orientation != SCREEN_ORIENTATION_BEHIND) {
- ProtoLog.v(WM_DEBUG_ORIENTATION,
- "App is requesting an orientation, return %d for display id=%d",
- orientation, mDisplayContent.mDisplayId);
- return orientation;
- }
-
- ProtoLog.v(WM_DEBUG_ORIENTATION,
- "No app is requesting an orientation, return %d for display id=%d",
- mDisplayContent.getLastOrientation(), mDisplayContent.mDisplayId);
- // The next app has not been requested to be visible, so we keep the current orientation
- // to prevent freezing/unfreezing the display too early.
- return mDisplayContent.getLastOrientation();
+ return super.getOrientation(candidate);
}
@Override
@@ -1880,6 +1870,12 @@ final class TaskDisplayArea extends DisplayArea<Task> {
return lastReparentedStack;
}
+ /** Whether this task display area is the last focused one on this logical display. */
+ @VisibleForTesting
+ boolean isLastFocused() {
+ return mDisplayContent.getLastFocusedTaskDisplayArea() == this;
+ }
+
@Override
protected boolean isTaskDisplayArea() {
return true;
diff --git a/services/tests/wmtests/src/com/android/server/wm/SystemServicesTestRule.java b/services/tests/wmtests/src/com/android/server/wm/SystemServicesTestRule.java
index 6a29c5b5424a..da3319acca24 100644
--- a/services/tests/wmtests/src/com/android/server/wm/SystemServicesTestRule.java
+++ b/services/tests/wmtests/src/com/android/server/wm/SystemServicesTestRule.java
@@ -318,6 +318,9 @@ public class SystemServicesTestRule implements TestRule {
display.setDisplayWindowingMode(WINDOWING_MODE_FULLSCREEN);
spyOn(display);
final TaskDisplayArea taskDisplayArea = display.getDefaultTaskDisplayArea();
+
+ // Set the default focused TDA.
+ display.setLastFocusedTaskDisplayArea(taskDisplayArea);
spyOn(taskDisplayArea);
final Task homeStack = taskDisplayArea.getStack(
WINDOWING_MODE_FULLSCREEN, ACTIVITY_TYPE_HOME);
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 bc3b3a4d7ad1..e71f7ec54b0e 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,7 @@ 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.window.DisplayAreaOrganizer.FEATURE_VENDOR_FIRST;
import static com.android.dx.mockito.inline.extended.ExtendedMockito.doReturn;
import static com.android.dx.mockito.inline.extended.ExtendedMockito.spyOn;
@@ -242,6 +243,40 @@ public class TaskDisplayAreaTests extends WindowTestsBase {
assertEquals(rootWindowContainer.getOrientation(), rootHomeTask.getOrientation());
}
+ @Test
+ public void testIsLastFocused() {
+ final TaskDisplayArea firstTaskDisplayArea = mDisplayContent.getDefaultTaskDisplayArea();
+ final TaskDisplayArea secondTaskDisplayArea = createTaskDisplayArea(
+ mDisplayContent, mRootWindowContainer.mWmService, "TestTaskDisplayArea",
+ FEATURE_VENDOR_FIRST);
+ final Task firstStack = firstTaskDisplayArea.createStack(
+ WINDOWING_MODE_FULLSCREEN, ACTIVITY_TYPE_STANDARD, false /* onTop */);
+ final Task secondStack = secondTaskDisplayArea.createStack(
+ WINDOWING_MODE_FULLSCREEN, ACTIVITY_TYPE_STANDARD, false /* onTop */);
+ final ActivityRecord firstActivity = new ActivityBuilder(mAtm).setCreateTask(true)
+ .setStack(firstStack).build();
+ final ActivityRecord secondActivity = new ActivityBuilder(mAtm).setCreateTask(true)
+ .setStack(secondStack).build();
+
+ // Activity on TDA1 is focused
+ mDisplayContent.setFocusedApp(firstActivity);
+
+ assertThat(firstTaskDisplayArea.isLastFocused()).isTrue();
+ assertThat(secondTaskDisplayArea.isLastFocused()).isFalse();
+
+ // No focused app, TDA1 is still recorded as last focused.
+ mDisplayContent.setFocusedApp(null);
+
+ assertThat(firstTaskDisplayArea.isLastFocused()).isTrue();
+ assertThat(secondTaskDisplayArea.isLastFocused()).isFalse();
+
+ // Activity on TDA2 is focused
+ mDisplayContent.setFocusedApp(secondActivity);
+
+ assertThat(firstTaskDisplayArea.isLastFocused()).isFalse();
+ assertThat(secondTaskDisplayArea.isLastFocused()).isTrue();
+ }
+
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/TaskRecordTests.java b/services/tests/wmtests/src/com/android/server/wm/TaskRecordTests.java
index a908bfef98de..d2b7ac4c3b24 100644
--- a/services/tests/wmtests/src/com/android/server/wm/TaskRecordTests.java
+++ b/services/tests/wmtests/src/com/android/server/wm/TaskRecordTests.java
@@ -33,6 +33,7 @@ import static android.util.DisplayMetrics.DENSITY_DEFAULT;
import static android.view.IWindowManager.FIXED_TO_USER_ROTATION_ENABLED;
import static android.view.Surface.ROTATION_0;
import static android.view.Surface.ROTATION_90;
+import static android.window.DisplayAreaOrganizer.FEATURE_VENDOR_FIRST;
import static com.android.dx.mockito.inline.extended.ExtendedMockito.doAnswer;
import static com.android.dx.mockito.inline.extended.ExtendedMockito.doReturn;
@@ -1001,7 +1002,7 @@ public class TaskRecordTests extends WindowTestsBase {
public void testNotSpecifyOrientationByFloatingTask() {
final Task task = getTestTask();
final ActivityRecord activity = task.getTopMostActivity();
- final WindowContainer<?> taskDisplayArea = task.getParent();
+ final TaskDisplayArea taskDisplayArea = task.getDisplayArea();
activity.setRequestedOrientation(SCREEN_ORIENTATION_LANDSCAPE);
assertEquals(SCREEN_ORIENTATION_LANDSCAPE, taskDisplayArea.getOrientation());
@@ -1012,6 +1013,42 @@ public class TaskRecordTests extends WindowTestsBase {
}
@Test
+ public void testNotSpecifyOrientation_taskDisplayAreaNotFocused() {
+ final TaskDisplayArea firstTaskDisplayArea = mDisplayContent.getDefaultTaskDisplayArea();
+ final TaskDisplayArea secondTaskDisplayArea = createTaskDisplayArea(
+ mDisplayContent, mRootWindowContainer.mWmService, "TestTaskDisplayArea",
+ FEATURE_VENDOR_FIRST);
+ final Task firstStack = firstTaskDisplayArea.createStack(
+ WINDOWING_MODE_FULLSCREEN, ACTIVITY_TYPE_STANDARD, false /* onTop */);
+ final Task secondStack = secondTaskDisplayArea.createStack(
+ WINDOWING_MODE_FULLSCREEN, ACTIVITY_TYPE_STANDARD, false /* onTop */);
+ final ActivityRecord firstActivity = new ActivityBuilder(mAtm).setCreateTask(true)
+ .setStack(firstStack).build();
+ final ActivityRecord secondActivity = new ActivityBuilder(mAtm).setCreateTask(true)
+ .setStack(secondStack).build();
+ firstActivity.setRequestedOrientation(SCREEN_ORIENTATION_LANDSCAPE);
+ secondActivity.setRequestedOrientation(SCREEN_ORIENTATION_PORTRAIT);
+
+ // Activity on TDA1 is focused
+ mDisplayContent.setFocusedApp(firstActivity);
+
+ assertEquals(SCREEN_ORIENTATION_LANDSCAPE, firstTaskDisplayArea.getOrientation());
+ assertEquals(SCREEN_ORIENTATION_UNSET, secondTaskDisplayArea.getOrientation());
+
+ // No focused app, TDA1 is still recorded as last focused.
+ mDisplayContent.setFocusedApp(null);
+
+ assertEquals(SCREEN_ORIENTATION_LANDSCAPE, firstTaskDisplayArea.getOrientation());
+ assertEquals(SCREEN_ORIENTATION_UNSET, secondTaskDisplayArea.getOrientation());
+
+ // Activity on TDA2 is focused
+ mDisplayContent.setFocusedApp(secondActivity);
+
+ assertEquals(SCREEN_ORIENTATION_UNSET, firstTaskDisplayArea.getOrientation());
+ assertEquals(SCREEN_ORIENTATION_PORTRAIT, secondTaskDisplayArea.getOrientation());
+ }
+
+ @Test
public void testNotifyOrientationChangeCausedByConfigurationChange() {
final Task task = getTestTask();
final ActivityRecord activity = task.getTopMostActivity();
diff --git a/services/tests/wmtests/src/com/android/server/wm/TestDisplayContent.java b/services/tests/wmtests/src/com/android/server/wm/TestDisplayContent.java
index 213c1f52aa37..ee16a76bcff8 100644
--- a/services/tests/wmtests/src/com/android/server/wm/TestDisplayContent.java
+++ b/services/tests/wmtests/src/com/android/server/wm/TestDisplayContent.java
@@ -156,6 +156,10 @@ class TestDisplayContent extends DisplayContent {
// threads immediately after adding it to hierarchy. Calling doAnswer() type of stubbing
// reduces chance of races, but still doesn't eliminate race conditions.
mService.mRootWindowContainer.addChild(newDisplay, mPosition);
+
+ // Set the default focused TDA.
+ newDisplay.setLastFocusedTaskDisplayArea(newDisplay.getDefaultTaskDisplayArea());
+
return newDisplay;
}
}