Loading data/etc/services.core.protolog.json +12 −12 Original line number Original line Diff line number Diff line Loading @@ -259,6 +259,12 @@ "group": "WM_DEBUG_ORIENTATION", "group": "WM_DEBUG_ORIENTATION", "at": "com\/android\/server\/wm\/WindowState.java" "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": { "-1730156332": { "message": "Display id=%d rotation changed to %d from %d, lastOrientation=%d", "message": "Display id=%d rotation changed to %d from %d, lastOrientation=%d", "level": "VERBOSE", "level": "VERBOSE", Loading Loading @@ -1909,6 +1915,12 @@ "group": "WM_ERROR", "group": "WM_ERROR", "at": "com\/android\/server\/wm\/WindowToken.java" "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": { "853091290": { "message": "Moved stack=%s behind stack=%s", "message": "Moved stack=%s behind stack=%s", "level": "DEBUG", "level": "DEBUG", Loading Loading @@ -2179,12 +2191,6 @@ "group": "WM_DEBUG_IME", "group": "WM_DEBUG_IME", "at": "com\/android\/server\/wm\/ImeInsetsSourceProvider.java" "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": { "1401295262": { "message": "Mode default, asking user", "message": "Mode default, asking user", "level": "WARN", "level": "WARN", Loading Loading @@ -2371,12 +2377,6 @@ "group": "WM_DEBUG_RESIZE", "group": "WM_DEBUG_RESIZE", "at": "com\/android\/server\/wm\/WindowState.java" "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": { "1653210583": { "message": "Removing app %s delayed=%b animation=%s animating=%b", "message": "Removing app %s delayed=%b animation=%s animating=%b", "level": "VERBOSE", "level": "VERBOSE", Loading services/core/java/com/android/server/wm/DisplayContent.java +37 −1 Original line number Original line Diff line number Diff line Loading @@ -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_PINNED; import static android.app.WindowConfiguration.WINDOWING_MODE_SPLIT_SCREEN_SECONDARY; import static android.app.WindowConfiguration.WINDOWING_MODE_SPLIT_SCREEN_SECONDARY; import static android.app.WindowConfiguration.WINDOWING_MODE_UNDEFINED; 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_LANDSCAPE; import static android.content.res.Configuration.ORIENTATION_PORTRAIT; import static android.content.res.Configuration.ORIENTATION_PORTRAIT; import static android.content.res.Configuration.ORIENTATION_UNDEFINED; import static android.content.res.Configuration.ORIENTATION_UNDEFINED; Loading Loading @@ -464,6 +466,9 @@ class DisplayContent extends RootDisplayArea implements WindowManagerPolicy.Disp */ */ ActivityRecord mFocusedApp = null; ActivityRecord mFocusedApp = null; /** The last focused {@link TaskDisplayArea} on this display. */ private TaskDisplayArea mLastFocusedTaskDisplayArea = null; /** /** * The launching activity which is using fixed rotation transformation. * The launching activity which is using fixed rotation transformation. * * Loading Loading @@ -2327,7 +2332,21 @@ class DisplayContent extends RootDisplayArea implements WindowManagerPolicy.Disp return getLastOrientation(); 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() { void updateDisplayInfo() { Loading Loading @@ -3202,6 +3221,10 @@ class DisplayContent extends RootDisplayArea implements WindowManagerPolicy.Disp throw new IllegalStateException(newFocus + " is not on " + getName() throw new IllegalStateException(newFocus + " is not on " + getName() + " but " + ((appDisplay != null) ? appDisplay.getName() : "none")); + " 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) { if (mFocusedApp == newFocus) { return false; return false; Loading @@ -3214,6 +3237,19 @@ class DisplayContent extends RootDisplayArea implements WindowManagerPolicy.Disp return true; 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. */ /** Updates the layer assignment of windows on this display. */ void assignWindowLayers(boolean setLayoutNeeded) { void assignWindowLayers(boolean setLayoutNeeded) { Trace.traceBegin(TRACE_TAG_WINDOW_MANAGER, "assignWindowLayers"); Trace.traceBegin(TRACE_TAG_WINDOW_MANAGER, "assignWindowLayers"); Loading services/core/java/com/android/server/wm/TaskDisplayArea.java +13 −17 Original line number Original line Diff line number Diff line Loading @@ -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_SPLIT_SCREEN_SECONDARY; import static android.app.WindowConfiguration.WINDOWING_MODE_UNDEFINED; import static android.app.WindowConfiguration.WINDOWING_MODE_UNDEFINED; import static android.app.WindowConfiguration.isSplitScreenWindowingMode; 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_UNSET; import static android.content.pm.ActivityInfo.SCREEN_ORIENTATION_UNSPECIFIED; 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_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.ActivityStackSupervisor.TAG_TASKS; import static com.android.server.wm.ActivityTaskManagerDebugConfig.DEBUG_STATES; import static com.android.server.wm.ActivityTaskManagerDebugConfig.DEBUG_STATES; import static com.android.server.wm.ActivityTaskManagerDebugConfig.DEBUG_TASKS; import static com.android.server.wm.ActivityTaskManagerDebugConfig.DEBUG_TASKS; Loading Loading @@ -645,6 +643,12 @@ final class TaskDisplayArea extends DisplayArea<Task> { @Override @Override int getOrientation(int candidate) { 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)) { if (isStackVisible(WINDOWING_MODE_SPLIT_SCREEN_PRIMARY)) { // Apps and their containers are not allowed to specify an orientation while using // 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 // root tasks...except for the home stack if it is not resizable and currently Loading @@ -671,21 +675,7 @@ final class TaskDisplayArea extends DisplayArea<Task> { return SCREEN_ORIENTATION_UNSPECIFIED; return SCREEN_ORIENTATION_UNSPECIFIED; } } final int orientation = super.getOrientation(candidate); return 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(); } } @Override @Override Loading Loading @@ -1880,6 +1870,12 @@ final class TaskDisplayArea extends DisplayArea<Task> { return lastReparentedStack; return lastReparentedStack; } } /** Whether this task display area is the last focused one on this logical display. */ @VisibleForTesting boolean isLastFocused() { return mDisplayContent.getLastFocusedTaskDisplayArea() == this; } @Override @Override protected boolean isTaskDisplayArea() { protected boolean isTaskDisplayArea() { return true; return true; Loading services/tests/wmtests/src/com/android/server/wm/SystemServicesTestRule.java +3 −0 Original line number Original line Diff line number Diff line Loading @@ -318,6 +318,9 @@ public class SystemServicesTestRule implements TestRule { display.setDisplayWindowingMode(WINDOWING_MODE_FULLSCREEN); display.setDisplayWindowingMode(WINDOWING_MODE_FULLSCREEN); spyOn(display); spyOn(display); final TaskDisplayArea taskDisplayArea = display.getDefaultTaskDisplayArea(); final TaskDisplayArea taskDisplayArea = display.getDefaultTaskDisplayArea(); // Set the default focused TDA. display.setLastFocusedTaskDisplayArea(taskDisplayArea); spyOn(taskDisplayArea); spyOn(taskDisplayArea); final Task homeStack = taskDisplayArea.getStack( final Task homeStack = taskDisplayArea.getStack( WINDOWING_MODE_FULLSCREEN, ACTIVITY_TYPE_HOME); WINDOWING_MODE_FULLSCREEN, ACTIVITY_TYPE_HOME); Loading services/tests/wmtests/src/com/android/server/wm/TaskDisplayAreaTests.java +35 −0 Original line number Original line Diff line number Diff line Loading @@ -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_SPLIT_SCREEN_SECONDARY; import static android.app.WindowConfiguration.WINDOWING_MODE_UNDEFINED; import static android.app.WindowConfiguration.WINDOWING_MODE_UNDEFINED; import static android.content.pm.ActivityInfo.RESIZE_MODE_UNRESIZEABLE; 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.doReturn; import static com.android.dx.mockito.inline.extended.ExtendedMockito.spyOn; import static com.android.dx.mockito.inline.extended.ExtendedMockito.spyOn; Loading Loading @@ -242,6 +243,40 @@ public class TaskDisplayAreaTests extends WindowTestsBase { assertEquals(rootWindowContainer.getOrientation(), rootHomeTask.getOrientation()); 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, private void assertGetOrCreateStack(int windowingMode, int activityType, Task candidateTask, boolean reuseCandidate) { boolean reuseCandidate) { final TaskDisplayArea taskDisplayArea = candidateTask.getDisplayArea(); final TaskDisplayArea taskDisplayArea = candidateTask.getDisplayArea(); Loading Loading
data/etc/services.core.protolog.json +12 −12 Original line number Original line Diff line number Diff line Loading @@ -259,6 +259,12 @@ "group": "WM_DEBUG_ORIENTATION", "group": "WM_DEBUG_ORIENTATION", "at": "com\/android\/server\/wm\/WindowState.java" "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": { "-1730156332": { "message": "Display id=%d rotation changed to %d from %d, lastOrientation=%d", "message": "Display id=%d rotation changed to %d from %d, lastOrientation=%d", "level": "VERBOSE", "level": "VERBOSE", Loading Loading @@ -1909,6 +1915,12 @@ "group": "WM_ERROR", "group": "WM_ERROR", "at": "com\/android\/server\/wm\/WindowToken.java" "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": { "853091290": { "message": "Moved stack=%s behind stack=%s", "message": "Moved stack=%s behind stack=%s", "level": "DEBUG", "level": "DEBUG", Loading Loading @@ -2179,12 +2191,6 @@ "group": "WM_DEBUG_IME", "group": "WM_DEBUG_IME", "at": "com\/android\/server\/wm\/ImeInsetsSourceProvider.java" "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": { "1401295262": { "message": "Mode default, asking user", "message": "Mode default, asking user", "level": "WARN", "level": "WARN", Loading Loading @@ -2371,12 +2377,6 @@ "group": "WM_DEBUG_RESIZE", "group": "WM_DEBUG_RESIZE", "at": "com\/android\/server\/wm\/WindowState.java" "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": { "1653210583": { "message": "Removing app %s delayed=%b animation=%s animating=%b", "message": "Removing app %s delayed=%b animation=%s animating=%b", "level": "VERBOSE", "level": "VERBOSE", Loading
services/core/java/com/android/server/wm/DisplayContent.java +37 −1 Original line number Original line Diff line number Diff line Loading @@ -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_PINNED; import static android.app.WindowConfiguration.WINDOWING_MODE_SPLIT_SCREEN_SECONDARY; import static android.app.WindowConfiguration.WINDOWING_MODE_SPLIT_SCREEN_SECONDARY; import static android.app.WindowConfiguration.WINDOWING_MODE_UNDEFINED; 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_LANDSCAPE; import static android.content.res.Configuration.ORIENTATION_PORTRAIT; import static android.content.res.Configuration.ORIENTATION_PORTRAIT; import static android.content.res.Configuration.ORIENTATION_UNDEFINED; import static android.content.res.Configuration.ORIENTATION_UNDEFINED; Loading Loading @@ -464,6 +466,9 @@ class DisplayContent extends RootDisplayArea implements WindowManagerPolicy.Disp */ */ ActivityRecord mFocusedApp = null; ActivityRecord mFocusedApp = null; /** The last focused {@link TaskDisplayArea} on this display. */ private TaskDisplayArea mLastFocusedTaskDisplayArea = null; /** /** * The launching activity which is using fixed rotation transformation. * The launching activity which is using fixed rotation transformation. * * Loading Loading @@ -2327,7 +2332,21 @@ class DisplayContent extends RootDisplayArea implements WindowManagerPolicy.Disp return getLastOrientation(); 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() { void updateDisplayInfo() { Loading Loading @@ -3202,6 +3221,10 @@ class DisplayContent extends RootDisplayArea implements WindowManagerPolicy.Disp throw new IllegalStateException(newFocus + " is not on " + getName() throw new IllegalStateException(newFocus + " is not on " + getName() + " but " + ((appDisplay != null) ? appDisplay.getName() : "none")); + " 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) { if (mFocusedApp == newFocus) { return false; return false; Loading @@ -3214,6 +3237,19 @@ class DisplayContent extends RootDisplayArea implements WindowManagerPolicy.Disp return true; 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. */ /** Updates the layer assignment of windows on this display. */ void assignWindowLayers(boolean setLayoutNeeded) { void assignWindowLayers(boolean setLayoutNeeded) { Trace.traceBegin(TRACE_TAG_WINDOW_MANAGER, "assignWindowLayers"); Trace.traceBegin(TRACE_TAG_WINDOW_MANAGER, "assignWindowLayers"); Loading
services/core/java/com/android/server/wm/TaskDisplayArea.java +13 −17 Original line number Original line Diff line number Diff line Loading @@ -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_SPLIT_SCREEN_SECONDARY; import static android.app.WindowConfiguration.WINDOWING_MODE_UNDEFINED; import static android.app.WindowConfiguration.WINDOWING_MODE_UNDEFINED; import static android.app.WindowConfiguration.isSplitScreenWindowingMode; 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_UNSET; import static android.content.pm.ActivityInfo.SCREEN_ORIENTATION_UNSPECIFIED; 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_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.ActivityStackSupervisor.TAG_TASKS; import static com.android.server.wm.ActivityTaskManagerDebugConfig.DEBUG_STATES; import static com.android.server.wm.ActivityTaskManagerDebugConfig.DEBUG_STATES; import static com.android.server.wm.ActivityTaskManagerDebugConfig.DEBUG_TASKS; import static com.android.server.wm.ActivityTaskManagerDebugConfig.DEBUG_TASKS; Loading Loading @@ -645,6 +643,12 @@ final class TaskDisplayArea extends DisplayArea<Task> { @Override @Override int getOrientation(int candidate) { 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)) { if (isStackVisible(WINDOWING_MODE_SPLIT_SCREEN_PRIMARY)) { // Apps and their containers are not allowed to specify an orientation while using // 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 // root tasks...except for the home stack if it is not resizable and currently Loading @@ -671,21 +675,7 @@ final class TaskDisplayArea extends DisplayArea<Task> { return SCREEN_ORIENTATION_UNSPECIFIED; return SCREEN_ORIENTATION_UNSPECIFIED; } } final int orientation = super.getOrientation(candidate); return 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(); } } @Override @Override Loading Loading @@ -1880,6 +1870,12 @@ final class TaskDisplayArea extends DisplayArea<Task> { return lastReparentedStack; return lastReparentedStack; } } /** Whether this task display area is the last focused one on this logical display. */ @VisibleForTesting boolean isLastFocused() { return mDisplayContent.getLastFocusedTaskDisplayArea() == this; } @Override @Override protected boolean isTaskDisplayArea() { protected boolean isTaskDisplayArea() { return true; return true; Loading
services/tests/wmtests/src/com/android/server/wm/SystemServicesTestRule.java +3 −0 Original line number Original line Diff line number Diff line Loading @@ -318,6 +318,9 @@ public class SystemServicesTestRule implements TestRule { display.setDisplayWindowingMode(WINDOWING_MODE_FULLSCREEN); display.setDisplayWindowingMode(WINDOWING_MODE_FULLSCREEN); spyOn(display); spyOn(display); final TaskDisplayArea taskDisplayArea = display.getDefaultTaskDisplayArea(); final TaskDisplayArea taskDisplayArea = display.getDefaultTaskDisplayArea(); // Set the default focused TDA. display.setLastFocusedTaskDisplayArea(taskDisplayArea); spyOn(taskDisplayArea); spyOn(taskDisplayArea); final Task homeStack = taskDisplayArea.getStack( final Task homeStack = taskDisplayArea.getStack( WINDOWING_MODE_FULLSCREEN, ACTIVITY_TYPE_HOME); WINDOWING_MODE_FULLSCREEN, ACTIVITY_TYPE_HOME); Loading
services/tests/wmtests/src/com/android/server/wm/TaskDisplayAreaTests.java +35 −0 Original line number Original line Diff line number Diff line Loading @@ -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_SPLIT_SCREEN_SECONDARY; import static android.app.WindowConfiguration.WINDOWING_MODE_UNDEFINED; import static android.app.WindowConfiguration.WINDOWING_MODE_UNDEFINED; import static android.content.pm.ActivityInfo.RESIZE_MODE_UNRESIZEABLE; 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.doReturn; import static com.android.dx.mockito.inline.extended.ExtendedMockito.spyOn; import static com.android.dx.mockito.inline.extended.ExtendedMockito.spyOn; Loading Loading @@ -242,6 +243,40 @@ public class TaskDisplayAreaTests extends WindowTestsBase { assertEquals(rootWindowContainer.getOrientation(), rootHomeTask.getOrientation()); 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, private void assertGetOrCreateStack(int windowingMode, int activityType, Task candidateTask, boolean reuseCandidate) { boolean reuseCandidate) { final TaskDisplayArea taskDisplayArea = candidateTask.getDisplayArea(); final TaskDisplayArea taskDisplayArea = candidateTask.getDisplayArea(); Loading