Merge "Task letterbox for resizable fixed-orientation app in dual DisplayAreas"

This commit is contained in:
Chris Li
2021-01-20 02:30:03 +00:00
committed by Android (Google) Code Review
4 changed files with 67 additions and 9 deletions

View File

@@ -3329,6 +3329,14 @@ class Task extends WindowContainer<WindowContainer> {
return false;
}
@Override
boolean handlesOrientationChangeFromDescendant() {
return super.handlesOrientationChangeFromDescendant()
// Display won't rotate for the orientation request if the TaskDisplayArea can't
// specify orientation.
&& getDisplayArea().canSpecifyOrientation();
}
void resize(boolean relayout, boolean forced) {
if (setBounds(getRequestedOverrideBounds(), forced) != BOUNDS_CHANGE_NONE && relayout) {
getDisplayContent().layoutAndAssignWindowLayersIfNeeded();

View File

@@ -1902,7 +1902,6 @@ final class TaskDisplayArea extends DisplayArea<WindowContainer> {
}
/** Whether this task display area can request orientation. */
@VisibleForTesting
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

View File

@@ -33,6 +33,7 @@ import static android.window.DisplayAreaOrganizer.FEATURE_VENDOR_FIRST;
import static android.window.DisplayAreaOrganizer.FEATURE_WINDOWED_MAGNIFICATION;
import static com.android.dx.mockito.inline.extended.ExtendedMockito.spyOn;
import static com.android.server.wm.SizeCompatTests.prepareLimitedBounds;
import static com.android.server.wm.SizeCompatTests.prepareUnresizable;
import static com.android.server.wm.SizeCompatTests.rotateDisplay;
@@ -309,6 +310,43 @@ public class DualDisplayAreaGroupPolicyTest extends WindowTestsBase {
assertThat(mSecondRoot.findAreaForToken(imeToken)).isEqualTo(imeContainer);
}
@Test
public void testResizableFixedOrientationApp_taskLevelLetterboxing() {
mFirstRoot.setIgnoreOrientationRequest(false /* ignoreOrientationRequest */);
mSecondRoot.setIgnoreOrientationRequest(false /* ignoreOrientationRequest */);
// Launch portrait on first DAG
mDisplay.onLastFocusedTaskDisplayAreaChanged(mFirstTda);
prepareLimitedBounds(mFirstActivity, SCREEN_ORIENTATION_PORTRAIT,
false /* isUnresizable */);
// Display in landscape (as opposite to DAG), first DAG and activity in portrait
assertThat(mDisplay.getLastOrientation()).isEqualTo(SCREEN_ORIENTATION_LANDSCAPE);
assertThat(mFirstRoot.getConfiguration().orientation).isEqualTo(ORIENTATION_PORTRAIT);
assertThat(mFirstActivity.getConfiguration().orientation).isEqualTo(ORIENTATION_PORTRAIT);
assertThat(mFirstTask.isTaskLetterboxed()).isFalse();
assertThat(mFirstActivity.inSizeCompatMode()).isFalse();
// Launch portrait on second DAG
mDisplay.onLastFocusedTaskDisplayAreaChanged(mSecondTda);
prepareLimitedBounds(mSecondActivity, SCREEN_ORIENTATION_LANDSCAPE,
false /* isUnresizable */);
// Display in portrait (as opposite to DAG), first DAG and activity in landscape
assertThat(mDisplay.getLastOrientation()).isEqualTo(SCREEN_ORIENTATION_PORTRAIT);
assertThat(mSecondRoot.getConfiguration().orientation).isEqualTo(ORIENTATION_LANDSCAPE);
assertThat(mSecondActivity.getConfiguration().orientation).isEqualTo(ORIENTATION_LANDSCAPE);
assertThat(mSecondTask.isTaskLetterboxed()).isFalse();
assertThat(mSecondActivity.inSizeCompatMode()).isFalse();
// First activity is letterboxed in portrait as requested.
assertThat(mFirstRoot.getConfiguration().orientation).isEqualTo(ORIENTATION_LANDSCAPE);
assertThat(mFirstActivity.getConfiguration().orientation).isEqualTo(ORIENTATION_PORTRAIT);
assertThat(mFirstTask.isTaskLetterboxed()).isTrue();
assertThat(mFirstActivity.inSizeCompatMode()).isFalse();
}
private void setupImeWindow() {
final WindowState imeWindow = createWindow(null /* parent */,
TYPE_INPUT_METHOD, mDisplay, "mImeWindow");

View File

@@ -16,6 +16,7 @@
package com.android.server.wm;
import static android.content.pm.ActivityInfo.RESIZE_MODE_RESIZEABLE;
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_PORTRAIT;
@@ -505,7 +506,7 @@ public class SizeCompatTests extends WindowTestsBase {
compatTokens.clear();
// Make the activity resizable again by restarting it
activity.info.resizeMode = ActivityInfo.RESIZE_MODE_RESIZEABLE;
activity.info.resizeMode = RESIZE_MODE_RESIZEABLE;
activity.mVisibleRequested = true;
activity.restartProcessIfVisible();
// The full lifecycle isn't hooked up so manually set state to resumed
@@ -522,7 +523,7 @@ public class SizeCompatTests extends WindowTestsBase {
setUpDisplaySizeWithApp(1000, 2500);
// Make the task root resizable.
mActivity.info.resizeMode = ActivityInfo.RESIZE_MODE_RESIZEABLE;
mActivity.info.resizeMode = RESIZE_MODE_RESIZEABLE;
// Create a size compat activity on the same task.
final ActivityRecord activity = new ActivityBuilder(mAtm)
@@ -550,7 +551,7 @@ public class SizeCompatTests extends WindowTestsBase {
setUpDisplaySizeWithApp(1000, 2500);
// Make the task root resizable.
mActivity.info.resizeMode = ActivityInfo.RESIZE_MODE_RESIZEABLE;
mActivity.info.resizeMode = RESIZE_MODE_RESIZEABLE;
// Create a size compat activity on the same task.
final ActivityRecord activity = new ActivityBuilder(mAtm)
@@ -946,13 +947,25 @@ public class SizeCompatTests extends WindowTestsBase {
prepareUnresizable(activity, -1 /* maxAspect */, screenOrientation);
}
/**
* Setups {@link #mActivity} as a size-compat-mode-able activity with fixed aspect and/or
* orientation.
*/
static void prepareUnresizable(ActivityRecord activity, float maxAspect,
int screenOrientation) {
activity.info.resizeMode = RESIZE_MODE_UNRESIZEABLE;
prepareLimitedBounds(activity, maxAspect, screenOrientation, true /* isUnresizable */);
}
static void prepareLimitedBounds(ActivityRecord activity, int screenOrientation,
boolean isUnresizable) {
prepareLimitedBounds(activity, -1 /* maxAspect */, screenOrientation, isUnresizable);
}
/**
* Setups {@link #mActivity} with restriction on its bounds, such as maxAspect, fixed
* orientation, and/or whether it is resizable.
*/
static void prepareLimitedBounds(ActivityRecord activity, float maxAspect,
int screenOrientation, boolean isUnresizable) {
activity.info.resizeMode = isUnresizable
? RESIZE_MODE_UNRESIZEABLE
: RESIZE_MODE_RESIZEABLE;
activity.mVisibleRequested = true;
if (maxAspect >= 0) {
activity.info.maxAspectRatio = maxAspect;