Loading services/core/java/com/android/server/wm/ActivityRecord.java +262 −118 File changed.Preview size limit exceeded, changes collapsed. Show changes services/core/java/com/android/server/wm/Task.java +2 −127 Original line number Diff line number Diff line Loading @@ -35,7 +35,6 @@ 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.activityTypeToString; import static android.app.WindowConfiguration.isSplitScreenWindowingMode; import static android.app.WindowConfiguration.windowingModeToString; import static android.content.Intent.FLAG_ACTIVITY_NEW_DOCUMENT; import static android.content.Intent.FLAG_ACTIVITY_NEW_TASK; Loading Loading @@ -148,7 +147,6 @@ import static com.android.server.wm.WindowContainerChildProto.TASK; import static com.android.server.wm.WindowManagerDebugConfig.DEBUG_ROOT_TASK; import static com.android.server.wm.WindowManagerDebugConfig.DEBUG_TASK_MOVEMENT; import static com.android.server.wm.WindowManagerDebugConfig.TAG_WM; import static com.android.server.wm.WindowManagerService.MIN_TASK_LETTERBOX_ASPECT_RATIO; import static com.android.server.wm.WindowManagerService.dipToPixel; import static com.android.server.wm.WindowStateAnimator.ROOT_TASK_CLIP_BEFORE_ANIM; Loading Loading @@ -597,10 +595,6 @@ class Task extends WindowContainer<WindowContainer> { @Nullable private ActivityRecord mResumedActivity = null; /** Last activity that is used to compute the Task bounds. */ @Nullable private ActivityRecord mLastTaskBoundsComputeActivity; private boolean mForceShowForAllUsers; /** When set, will force the task to report as invisible. */ Loading Loading @@ -1496,11 +1490,6 @@ class Task extends WindowContainer<WindowContainer> { } void cleanUpActivityReferences(ActivityRecord r) { // mLastTaskBoundsComputeActivity is set at leaf Task if (mLastTaskBoundsComputeActivity == r) { mLastTaskBoundsComputeActivity = null; } // mPausingActivity is set at leaf task if (mPausingActivity != null && mPausingActivity == r) { mPausingActivity = null; Loading Loading @@ -2863,7 +2852,6 @@ class Task extends WindowContainer<WindowContainer> { private void resolveLeafOnlyOverrideConfigs(Configuration newParentConfig, Rect previousBounds) { mLastTaskBoundsComputeActivity = getTopNonFinishingActivity(false /* includeOverlays */); int windowingMode = getResolvedOverrideConfiguration().windowConfiguration.getWindowingMode(); Loading @@ -2877,7 +2865,8 @@ class Task extends WindowContainer<WindowContainer> { getResolvedOverrideConfiguration().windowConfiguration.getBounds(); if (windowingMode == WINDOWING_MODE_FULLSCREEN) { computeFullscreenBounds(outOverrideBounds, newParentConfig); // Use empty bounds to indicate "fill parent". outOverrideBounds.setEmpty(); // The bounds for fullscreen mode shouldn't be adjusted by minimal size. Otherwise if // the parent or display is smaller than the size, the content may be cropped. return; Loading @@ -2888,21 +2877,6 @@ class Task extends WindowContainer<WindowContainer> { computeFreeformBounds(outOverrideBounds, newParentConfig); return; } if (isSplitScreenWindowingMode(windowingMode) || windowingMode == WINDOWING_MODE_MULTI_WINDOW) { // This is to compute whether the task should be letterboxed to handle non-resizable app // in multi window. There is no split screen only logic. computeLetterboxBounds(outOverrideBounds, newParentConfig); } } /** Computes bounds for {@link WindowConfiguration#WINDOWING_MODE_FULLSCREEN}. */ @VisibleForTesting void computeFullscreenBounds(@NonNull Rect outBounds, @NonNull Configuration newParentConfig) { // In FULLSCREEN mode, always start with empty bounds to indicate "fill parent". outBounds.setEmpty(); computeLetterboxBounds(outBounds, newParentConfig); } /** Computes bounds for {@link WindowConfiguration#WINDOWING_MODE_FREEFORM}. */ Loading Loading @@ -2934,94 +2908,6 @@ class Task extends WindowContainer<WindowContainer> { } } /** * Computes bounds (letterbox or pillarbox) when the parent doesn't handle the orientation * change and the requested orientation is different from the parent. */ private void computeLetterboxBounds(@NonNull Rect outBounds, @NonNull Configuration newParentConfig) { if (handlesOrientationChangeFromDescendant()) { // No need to letterbox at task level. Display will handle fixed-orientation requests. return; } final int parentOrientation = newParentConfig.orientation; // Use the top activity as the reference of orientation. Don't include overlays because // it is usually not the actual content or just temporarily shown. // E.g. ForcedResizableInfoActivity. final ActivityRecord refActivity = getTopNonFinishingActivity(false /* includeOverlays */); // If the task or the reference activity requires a different orientation (either by // override or activityInfo), make it fit the available bounds by scaling down its bounds. final int overrideOrientation = getRequestedOverrideConfiguration().orientation; final int forcedOrientation = (overrideOrientation != ORIENTATION_UNDEFINED || refActivity == null) ? overrideOrientation : refActivity.getRequestedConfigurationOrientation(); if (forcedOrientation == ORIENTATION_UNDEFINED || forcedOrientation == parentOrientation) { return; } final ActivityRecord.CompatDisplayInsets compatDisplayInsets = refActivity == null ? null : refActivity.getCompatDisplayInsets(); if (compatDisplayInsets != null && !compatDisplayInsets.mIsTaskLetterboxed) { // App prefers to keep its original size. // If the size compat is from previous task letterboxing, we may want to have task // letterbox again, otherwise it will show the size compat restart button even if the // restart bounds will be the same. return; } final Rect parentBounds = newParentConfig.windowConfiguration.getBounds(); final int parentWidth = parentBounds.width(); final int parentHeight = parentBounds.height(); float aspect = Math.max(parentWidth, parentHeight) / (float) Math.min(parentWidth, parentHeight); // Adjust the Task letterbox bounds to fit the app request aspect ratio in order to use the // extra available space. if (refActivity != null) { final float maxAspectRatio = refActivity.info.maxAspectRatio; final float minAspectRatio = refActivity.info.minAspectRatio; if (aspect > maxAspectRatio && maxAspectRatio != 0) { aspect = maxAspectRatio; } else if (aspect < minAspectRatio) { aspect = minAspectRatio; } } // Override from config_letterboxAspectRatio or via ADB with set-letterbox-aspect-ratio. final float letterboxAspectRatioOverride = mWmService.getTaskLetterboxAspectRatio(); // Activity min/max aspect ratio restrictions will be respected by the activity-level // letterboxing (size-compat mode). Therefore this override can control the maximum screen // area that can be occupied by the app in the letterbox mode. aspect = letterboxAspectRatioOverride > MIN_TASK_LETTERBOX_ASPECT_RATIO ? letterboxAspectRatioOverride : aspect; // Store the current bounds to be able to revert to size compat mode values below if needed. mTmpFullBounds.set(outBounds); if (forcedOrientation == ORIENTATION_LANDSCAPE) { final int height = (int) Math.rint(parentWidth / aspect); final int top = parentBounds.centerY() - height / 2; outBounds.set(parentBounds.left, top, parentBounds.right, top + height); } else { final int width = (int) Math.rint(parentHeight / aspect); final int left = parentBounds.centerX() - width / 2; outBounds.set(left, parentBounds.top, left + width, parentBounds.bottom); } if (compatDisplayInsets != null) { compatDisplayInsets.getBoundsByRotation( mTmpBounds, newParentConfig.windowConfiguration.getRotation()); if (outBounds.width() != mTmpBounds.width() || outBounds.height() != mTmpBounds.height()) { // The app shouldn't be resized, we only do task letterboxing if the compat bounds // is also from the same task letterbox. Otherwise, clear the task bounds to show // app in size compat mode. outBounds.set(mTmpFullBounds); } } } Rect updateOverrideConfigurationFromLaunchBounds() { // If the task is controlled by another organized task, do not set override // configurations and let its parent (organized task) to control it; Loading @@ -3036,11 +2922,6 @@ class Task extends WindowContainer<WindowContainer> { return bounds; } @Nullable ActivityRecord getLastTaskBoundsComputeActivity() { return mLastTaskBoundsComputeActivity; } /** Updates the task's bounds and override configuration to match what is expected for the * input root task. */ void updateOverrideConfigurationForRootTask(Task inRootTask) { Loading Loading @@ -3939,12 +3820,6 @@ class Task extends WindowContainer<WindowContainer> { || activityType == ACTIVITY_TYPE_ASSISTANT; } boolean isTaskLetterboxed() { // No letterbox for multi window root task return !matchParentBounds() && (getWindowingMode() == WINDOWING_MODE_FULLSCREEN || !isRootTask()); } @Override boolean fillsParent() { // From the perspective of policy, we still want to report that this task fills parent Loading services/core/java/com/android/server/wm/WindowState.java +15 −7 Original line number Diff line number Diff line Loading @@ -3827,13 +3827,21 @@ class WindowState extends WindowContainer<WindowState> implements WindowManagerP /** @return true when the window should be letterboxed. */ boolean isLetterboxedAppWindow() { // Fullscreen mode but doesn't fill display area. return (!inMultiWindowMode() && !matchesDisplayAreaBounds()) if (!inMultiWindowMode() && !matchesDisplayAreaBounds()) { return true; } if (mActivityRecord != null) { // Activity in size compat. || (mActivityRecord != null && mActivityRecord.inSizeCompatMode()) // Task letterboxed. || (getTask() != null && getTask().isTaskLetterboxed()) if (mActivityRecord.inSizeCompatMode()) { return true; } // Letterbox for fixed orientation. if (mActivityRecord.isLetterboxedForFixedOrientationAndAspectRatio()) { return true; } } // Letterboxed for display cutout. || isLetterboxedForDisplayCutout(); return isLetterboxedForDisplayCutout(); } /** Returns {@code true} if the window is letterboxed for the display cutout. */ Loading services/tests/wmtests/src/com/android/server/wm/ActivityRecordTests.java +3 −2 Original line number Diff line number Diff line Loading @@ -555,9 +555,10 @@ public class ActivityRecordTests extends WindowTestsBase { activity.setRequestedOrientation( isScreenPortrait ? SCREEN_ORIENTATION_PORTRAIT : SCREEN_ORIENTATION_LANDSCAPE); // Asserts it has orientation derived from bounds. assertEquals(isScreenPortrait ? ORIENTATION_LANDSCAPE : ORIENTATION_PORTRAIT, // Asserts it has orientation derived requested orientation (fixed orientation letterbox). assertEquals(isScreenPortrait ? ORIENTATION_PORTRAIT : ORIENTATION_LANDSCAPE, activity.getConfiguration().orientation); assertTrue(activity.isLetterboxedForFixedOrientationAndAspectRatio()); } @Test Loading services/tests/wmtests/src/com/android/server/wm/DualDisplayAreaGroupPolicyTest.java +17 −17 Original line number Diff line number Diff line Loading @@ -171,7 +171,7 @@ public class DualDisplayAreaGroupPolicyTest extends WindowTestsBase { final Rect activityBounds = new Rect(mFirstActivity.getBounds()); // DAG is portrait (860x1200), so Task and Activity fill DAG. assertThat(mFirstTask.isTaskLetterboxed()).isFalse(); assertThat(mFirstActivity.isLetterboxedForFixedOrientationAndAspectRatio()).isFalse(); assertThat(mFirstActivity.inSizeCompatMode()).isFalse(); assertThat(taskBounds).isEqualTo(dagBounds); assertThat(activityBounds).isEqualTo(taskBounds); Loading @@ -194,8 +194,8 @@ public class DualDisplayAreaGroupPolicyTest extends WindowTestsBase { final Rect activityConfigBounds = new Rect(mFirstActivity.getConfiguration().windowConfiguration.getBounds()); // DAG is landscape (1200x860), Task fills parent assertThat(mFirstTask.isTaskLetterboxed()).isFalse(); // DAG is landscape (1200x860), no fixed orientation letterbox assertThat(mFirstActivity.isLetterboxedForFixedOrientationAndAspectRatio()).isFalse(); assertThat(mFirstActivity.inSizeCompatMode()).isTrue(); assertThat(newDagBounds.width()).isEqualTo(dagBounds.height()); assertThat(newDagBounds.height()).isEqualTo(dagBounds.width()); Loading @@ -211,7 +211,7 @@ public class DualDisplayAreaGroupPolicyTest extends WindowTestsBase { } @Test public void testLaunchLandscapeApp_taskIsLetterboxInDisplayAreaGroup() { public void testLaunchLandscapeApp_activityIsLetterboxForFixedOrientationInDisplayAreaGroup() { mFirstRoot.setIgnoreOrientationRequest(true /* ignoreOrientationRequest */); mSecondRoot.setIgnoreOrientationRequest(true /* ignoreOrientationRequest */); mDisplay.onLastFocusedTaskDisplayAreaChanged(mFirstTda); Loading @@ -221,17 +221,18 @@ public class DualDisplayAreaGroupPolicyTest extends WindowTestsBase { final Rect taskBounds = new Rect(mFirstTask.getBounds()); final Rect activityBounds = new Rect(mFirstActivity.getBounds()); // DAG is portrait (860x1200), so Task is letterbox (860x[860x860/1200=616]) assertThat(mFirstTask.isTaskLetterboxed()).isTrue(); // DAG is portrait (860x1200), and activity is letterboxed for fixed orientation // (860x[860x860/1200=616]). Task fills DAG. assertThat(mFirstActivity.isLetterboxedForFixedOrientationAndAspectRatio()).isTrue(); assertThat(mFirstActivity.inSizeCompatMode()).isFalse(); assertThat(taskBounds.width()).isEqualTo(dagBounds.width()); assertThat(taskBounds.height()) assertThat(taskBounds).isEqualTo(dagBounds); assertThat(activityBounds.width()).isEqualTo(dagBounds.width()); assertThat(activityBounds.height()) .isEqualTo(dagBounds.width() * dagBounds.width() / dagBounds.height()); assertThat(activityBounds).isEqualTo(taskBounds); } @Test public void testLaunchLandscapeApp_taskLetterboxBecomesActivityLetterboxAfterRotation() { public void testLaunchLandscapeApp_fixedOrientationLetterboxBecomesSizeCompatAfterRotation() { mFirstRoot.setIgnoreOrientationRequest(true /* ignoreOrientationRequest */); mSecondRoot.setIgnoreOrientationRequest(true /* ignoreOrientationRequest */); mDisplay.onLastFocusedTaskDisplayAreaChanged(mFirstTda); Loading @@ -245,9 +246,8 @@ public class DualDisplayAreaGroupPolicyTest extends WindowTestsBase { final Rect newTaskBounds = new Rect(mFirstTask.getBounds()); final Rect newActivityBounds = new Rect(mFirstActivity.getBounds()); // DAG is landscape (1200x860), Task fills parent // Task letterbox size assertThat(mFirstTask.isTaskLetterboxed()).isFalse(); // DAG is landscape (1200x860), no fixed orientation letterbox assertThat(mFirstActivity.isLetterboxedForFixedOrientationAndAspectRatio()).isFalse(); assertThat(mFirstActivity.inSizeCompatMode()).isTrue(); assertThat(newDagBounds.width()).isEqualTo(dagBounds.height()); assertThat(newDagBounds.height()).isEqualTo(dagBounds.width()); Loading Loading @@ -311,7 +311,7 @@ public class DualDisplayAreaGroupPolicyTest extends WindowTestsBase { } @Test public void testResizableFixedOrientationApp_taskLevelLetterboxing() { public void testResizableFixedOrientationApp_fixedOrientationLetterboxing() { mFirstRoot.setIgnoreOrientationRequest(false /* ignoreOrientationRequest */); mSecondRoot.setIgnoreOrientationRequest(false /* ignoreOrientationRequest */); Loading @@ -324,7 +324,7 @@ public class DualDisplayAreaGroupPolicyTest extends WindowTestsBase { 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.isLetterboxedForFixedOrientationAndAspectRatio()).isFalse(); assertThat(mFirstActivity.inSizeCompatMode()).isFalse(); // Launch portrait on second DAG Loading @@ -336,13 +336,13 @@ public class DualDisplayAreaGroupPolicyTest extends WindowTestsBase { 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.isLetterboxedForFixedOrientationAndAspectRatio()).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.isLetterboxedForFixedOrientationAndAspectRatio()).isTrue(); assertThat(mFirstActivity.inSizeCompatMode()).isFalse(); } Loading Loading
services/core/java/com/android/server/wm/ActivityRecord.java +262 −118 File changed.Preview size limit exceeded, changes collapsed. Show changes
services/core/java/com/android/server/wm/Task.java +2 −127 Original line number Diff line number Diff line Loading @@ -35,7 +35,6 @@ 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.activityTypeToString; import static android.app.WindowConfiguration.isSplitScreenWindowingMode; import static android.app.WindowConfiguration.windowingModeToString; import static android.content.Intent.FLAG_ACTIVITY_NEW_DOCUMENT; import static android.content.Intent.FLAG_ACTIVITY_NEW_TASK; Loading Loading @@ -148,7 +147,6 @@ import static com.android.server.wm.WindowContainerChildProto.TASK; import static com.android.server.wm.WindowManagerDebugConfig.DEBUG_ROOT_TASK; import static com.android.server.wm.WindowManagerDebugConfig.DEBUG_TASK_MOVEMENT; import static com.android.server.wm.WindowManagerDebugConfig.TAG_WM; import static com.android.server.wm.WindowManagerService.MIN_TASK_LETTERBOX_ASPECT_RATIO; import static com.android.server.wm.WindowManagerService.dipToPixel; import static com.android.server.wm.WindowStateAnimator.ROOT_TASK_CLIP_BEFORE_ANIM; Loading Loading @@ -597,10 +595,6 @@ class Task extends WindowContainer<WindowContainer> { @Nullable private ActivityRecord mResumedActivity = null; /** Last activity that is used to compute the Task bounds. */ @Nullable private ActivityRecord mLastTaskBoundsComputeActivity; private boolean mForceShowForAllUsers; /** When set, will force the task to report as invisible. */ Loading Loading @@ -1496,11 +1490,6 @@ class Task extends WindowContainer<WindowContainer> { } void cleanUpActivityReferences(ActivityRecord r) { // mLastTaskBoundsComputeActivity is set at leaf Task if (mLastTaskBoundsComputeActivity == r) { mLastTaskBoundsComputeActivity = null; } // mPausingActivity is set at leaf task if (mPausingActivity != null && mPausingActivity == r) { mPausingActivity = null; Loading Loading @@ -2863,7 +2852,6 @@ class Task extends WindowContainer<WindowContainer> { private void resolveLeafOnlyOverrideConfigs(Configuration newParentConfig, Rect previousBounds) { mLastTaskBoundsComputeActivity = getTopNonFinishingActivity(false /* includeOverlays */); int windowingMode = getResolvedOverrideConfiguration().windowConfiguration.getWindowingMode(); Loading @@ -2877,7 +2865,8 @@ class Task extends WindowContainer<WindowContainer> { getResolvedOverrideConfiguration().windowConfiguration.getBounds(); if (windowingMode == WINDOWING_MODE_FULLSCREEN) { computeFullscreenBounds(outOverrideBounds, newParentConfig); // Use empty bounds to indicate "fill parent". outOverrideBounds.setEmpty(); // The bounds for fullscreen mode shouldn't be adjusted by minimal size. Otherwise if // the parent or display is smaller than the size, the content may be cropped. return; Loading @@ -2888,21 +2877,6 @@ class Task extends WindowContainer<WindowContainer> { computeFreeformBounds(outOverrideBounds, newParentConfig); return; } if (isSplitScreenWindowingMode(windowingMode) || windowingMode == WINDOWING_MODE_MULTI_WINDOW) { // This is to compute whether the task should be letterboxed to handle non-resizable app // in multi window. There is no split screen only logic. computeLetterboxBounds(outOverrideBounds, newParentConfig); } } /** Computes bounds for {@link WindowConfiguration#WINDOWING_MODE_FULLSCREEN}. */ @VisibleForTesting void computeFullscreenBounds(@NonNull Rect outBounds, @NonNull Configuration newParentConfig) { // In FULLSCREEN mode, always start with empty bounds to indicate "fill parent". outBounds.setEmpty(); computeLetterboxBounds(outBounds, newParentConfig); } /** Computes bounds for {@link WindowConfiguration#WINDOWING_MODE_FREEFORM}. */ Loading Loading @@ -2934,94 +2908,6 @@ class Task extends WindowContainer<WindowContainer> { } } /** * Computes bounds (letterbox or pillarbox) when the parent doesn't handle the orientation * change and the requested orientation is different from the parent. */ private void computeLetterboxBounds(@NonNull Rect outBounds, @NonNull Configuration newParentConfig) { if (handlesOrientationChangeFromDescendant()) { // No need to letterbox at task level. Display will handle fixed-orientation requests. return; } final int parentOrientation = newParentConfig.orientation; // Use the top activity as the reference of orientation. Don't include overlays because // it is usually not the actual content or just temporarily shown. // E.g. ForcedResizableInfoActivity. final ActivityRecord refActivity = getTopNonFinishingActivity(false /* includeOverlays */); // If the task or the reference activity requires a different orientation (either by // override or activityInfo), make it fit the available bounds by scaling down its bounds. final int overrideOrientation = getRequestedOverrideConfiguration().orientation; final int forcedOrientation = (overrideOrientation != ORIENTATION_UNDEFINED || refActivity == null) ? overrideOrientation : refActivity.getRequestedConfigurationOrientation(); if (forcedOrientation == ORIENTATION_UNDEFINED || forcedOrientation == parentOrientation) { return; } final ActivityRecord.CompatDisplayInsets compatDisplayInsets = refActivity == null ? null : refActivity.getCompatDisplayInsets(); if (compatDisplayInsets != null && !compatDisplayInsets.mIsTaskLetterboxed) { // App prefers to keep its original size. // If the size compat is from previous task letterboxing, we may want to have task // letterbox again, otherwise it will show the size compat restart button even if the // restart bounds will be the same. return; } final Rect parentBounds = newParentConfig.windowConfiguration.getBounds(); final int parentWidth = parentBounds.width(); final int parentHeight = parentBounds.height(); float aspect = Math.max(parentWidth, parentHeight) / (float) Math.min(parentWidth, parentHeight); // Adjust the Task letterbox bounds to fit the app request aspect ratio in order to use the // extra available space. if (refActivity != null) { final float maxAspectRatio = refActivity.info.maxAspectRatio; final float minAspectRatio = refActivity.info.minAspectRatio; if (aspect > maxAspectRatio && maxAspectRatio != 0) { aspect = maxAspectRatio; } else if (aspect < minAspectRatio) { aspect = minAspectRatio; } } // Override from config_letterboxAspectRatio or via ADB with set-letterbox-aspect-ratio. final float letterboxAspectRatioOverride = mWmService.getTaskLetterboxAspectRatio(); // Activity min/max aspect ratio restrictions will be respected by the activity-level // letterboxing (size-compat mode). Therefore this override can control the maximum screen // area that can be occupied by the app in the letterbox mode. aspect = letterboxAspectRatioOverride > MIN_TASK_LETTERBOX_ASPECT_RATIO ? letterboxAspectRatioOverride : aspect; // Store the current bounds to be able to revert to size compat mode values below if needed. mTmpFullBounds.set(outBounds); if (forcedOrientation == ORIENTATION_LANDSCAPE) { final int height = (int) Math.rint(parentWidth / aspect); final int top = parentBounds.centerY() - height / 2; outBounds.set(parentBounds.left, top, parentBounds.right, top + height); } else { final int width = (int) Math.rint(parentHeight / aspect); final int left = parentBounds.centerX() - width / 2; outBounds.set(left, parentBounds.top, left + width, parentBounds.bottom); } if (compatDisplayInsets != null) { compatDisplayInsets.getBoundsByRotation( mTmpBounds, newParentConfig.windowConfiguration.getRotation()); if (outBounds.width() != mTmpBounds.width() || outBounds.height() != mTmpBounds.height()) { // The app shouldn't be resized, we only do task letterboxing if the compat bounds // is also from the same task letterbox. Otherwise, clear the task bounds to show // app in size compat mode. outBounds.set(mTmpFullBounds); } } } Rect updateOverrideConfigurationFromLaunchBounds() { // If the task is controlled by another organized task, do not set override // configurations and let its parent (organized task) to control it; Loading @@ -3036,11 +2922,6 @@ class Task extends WindowContainer<WindowContainer> { return bounds; } @Nullable ActivityRecord getLastTaskBoundsComputeActivity() { return mLastTaskBoundsComputeActivity; } /** Updates the task's bounds and override configuration to match what is expected for the * input root task. */ void updateOverrideConfigurationForRootTask(Task inRootTask) { Loading Loading @@ -3939,12 +3820,6 @@ class Task extends WindowContainer<WindowContainer> { || activityType == ACTIVITY_TYPE_ASSISTANT; } boolean isTaskLetterboxed() { // No letterbox for multi window root task return !matchParentBounds() && (getWindowingMode() == WINDOWING_MODE_FULLSCREEN || !isRootTask()); } @Override boolean fillsParent() { // From the perspective of policy, we still want to report that this task fills parent Loading
services/core/java/com/android/server/wm/WindowState.java +15 −7 Original line number Diff line number Diff line Loading @@ -3827,13 +3827,21 @@ class WindowState extends WindowContainer<WindowState> implements WindowManagerP /** @return true when the window should be letterboxed. */ boolean isLetterboxedAppWindow() { // Fullscreen mode but doesn't fill display area. return (!inMultiWindowMode() && !matchesDisplayAreaBounds()) if (!inMultiWindowMode() && !matchesDisplayAreaBounds()) { return true; } if (mActivityRecord != null) { // Activity in size compat. || (mActivityRecord != null && mActivityRecord.inSizeCompatMode()) // Task letterboxed. || (getTask() != null && getTask().isTaskLetterboxed()) if (mActivityRecord.inSizeCompatMode()) { return true; } // Letterbox for fixed orientation. if (mActivityRecord.isLetterboxedForFixedOrientationAndAspectRatio()) { return true; } } // Letterboxed for display cutout. || isLetterboxedForDisplayCutout(); return isLetterboxedForDisplayCutout(); } /** Returns {@code true} if the window is letterboxed for the display cutout. */ Loading
services/tests/wmtests/src/com/android/server/wm/ActivityRecordTests.java +3 −2 Original line number Diff line number Diff line Loading @@ -555,9 +555,10 @@ public class ActivityRecordTests extends WindowTestsBase { activity.setRequestedOrientation( isScreenPortrait ? SCREEN_ORIENTATION_PORTRAIT : SCREEN_ORIENTATION_LANDSCAPE); // Asserts it has orientation derived from bounds. assertEquals(isScreenPortrait ? ORIENTATION_LANDSCAPE : ORIENTATION_PORTRAIT, // Asserts it has orientation derived requested orientation (fixed orientation letterbox). assertEquals(isScreenPortrait ? ORIENTATION_PORTRAIT : ORIENTATION_LANDSCAPE, activity.getConfiguration().orientation); assertTrue(activity.isLetterboxedForFixedOrientationAndAspectRatio()); } @Test Loading
services/tests/wmtests/src/com/android/server/wm/DualDisplayAreaGroupPolicyTest.java +17 −17 Original line number Diff line number Diff line Loading @@ -171,7 +171,7 @@ public class DualDisplayAreaGroupPolicyTest extends WindowTestsBase { final Rect activityBounds = new Rect(mFirstActivity.getBounds()); // DAG is portrait (860x1200), so Task and Activity fill DAG. assertThat(mFirstTask.isTaskLetterboxed()).isFalse(); assertThat(mFirstActivity.isLetterboxedForFixedOrientationAndAspectRatio()).isFalse(); assertThat(mFirstActivity.inSizeCompatMode()).isFalse(); assertThat(taskBounds).isEqualTo(dagBounds); assertThat(activityBounds).isEqualTo(taskBounds); Loading @@ -194,8 +194,8 @@ public class DualDisplayAreaGroupPolicyTest extends WindowTestsBase { final Rect activityConfigBounds = new Rect(mFirstActivity.getConfiguration().windowConfiguration.getBounds()); // DAG is landscape (1200x860), Task fills parent assertThat(mFirstTask.isTaskLetterboxed()).isFalse(); // DAG is landscape (1200x860), no fixed orientation letterbox assertThat(mFirstActivity.isLetterboxedForFixedOrientationAndAspectRatio()).isFalse(); assertThat(mFirstActivity.inSizeCompatMode()).isTrue(); assertThat(newDagBounds.width()).isEqualTo(dagBounds.height()); assertThat(newDagBounds.height()).isEqualTo(dagBounds.width()); Loading @@ -211,7 +211,7 @@ public class DualDisplayAreaGroupPolicyTest extends WindowTestsBase { } @Test public void testLaunchLandscapeApp_taskIsLetterboxInDisplayAreaGroup() { public void testLaunchLandscapeApp_activityIsLetterboxForFixedOrientationInDisplayAreaGroup() { mFirstRoot.setIgnoreOrientationRequest(true /* ignoreOrientationRequest */); mSecondRoot.setIgnoreOrientationRequest(true /* ignoreOrientationRequest */); mDisplay.onLastFocusedTaskDisplayAreaChanged(mFirstTda); Loading @@ -221,17 +221,18 @@ public class DualDisplayAreaGroupPolicyTest extends WindowTestsBase { final Rect taskBounds = new Rect(mFirstTask.getBounds()); final Rect activityBounds = new Rect(mFirstActivity.getBounds()); // DAG is portrait (860x1200), so Task is letterbox (860x[860x860/1200=616]) assertThat(mFirstTask.isTaskLetterboxed()).isTrue(); // DAG is portrait (860x1200), and activity is letterboxed for fixed orientation // (860x[860x860/1200=616]). Task fills DAG. assertThat(mFirstActivity.isLetterboxedForFixedOrientationAndAspectRatio()).isTrue(); assertThat(mFirstActivity.inSizeCompatMode()).isFalse(); assertThat(taskBounds.width()).isEqualTo(dagBounds.width()); assertThat(taskBounds.height()) assertThat(taskBounds).isEqualTo(dagBounds); assertThat(activityBounds.width()).isEqualTo(dagBounds.width()); assertThat(activityBounds.height()) .isEqualTo(dagBounds.width() * dagBounds.width() / dagBounds.height()); assertThat(activityBounds).isEqualTo(taskBounds); } @Test public void testLaunchLandscapeApp_taskLetterboxBecomesActivityLetterboxAfterRotation() { public void testLaunchLandscapeApp_fixedOrientationLetterboxBecomesSizeCompatAfterRotation() { mFirstRoot.setIgnoreOrientationRequest(true /* ignoreOrientationRequest */); mSecondRoot.setIgnoreOrientationRequest(true /* ignoreOrientationRequest */); mDisplay.onLastFocusedTaskDisplayAreaChanged(mFirstTda); Loading @@ -245,9 +246,8 @@ public class DualDisplayAreaGroupPolicyTest extends WindowTestsBase { final Rect newTaskBounds = new Rect(mFirstTask.getBounds()); final Rect newActivityBounds = new Rect(mFirstActivity.getBounds()); // DAG is landscape (1200x860), Task fills parent // Task letterbox size assertThat(mFirstTask.isTaskLetterboxed()).isFalse(); // DAG is landscape (1200x860), no fixed orientation letterbox assertThat(mFirstActivity.isLetterboxedForFixedOrientationAndAspectRatio()).isFalse(); assertThat(mFirstActivity.inSizeCompatMode()).isTrue(); assertThat(newDagBounds.width()).isEqualTo(dagBounds.height()); assertThat(newDagBounds.height()).isEqualTo(dagBounds.width()); Loading Loading @@ -311,7 +311,7 @@ public class DualDisplayAreaGroupPolicyTest extends WindowTestsBase { } @Test public void testResizableFixedOrientationApp_taskLevelLetterboxing() { public void testResizableFixedOrientationApp_fixedOrientationLetterboxing() { mFirstRoot.setIgnoreOrientationRequest(false /* ignoreOrientationRequest */); mSecondRoot.setIgnoreOrientationRequest(false /* ignoreOrientationRequest */); Loading @@ -324,7 +324,7 @@ public class DualDisplayAreaGroupPolicyTest extends WindowTestsBase { 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.isLetterboxedForFixedOrientationAndAspectRatio()).isFalse(); assertThat(mFirstActivity.inSizeCompatMode()).isFalse(); // Launch portrait on second DAG Loading @@ -336,13 +336,13 @@ public class DualDisplayAreaGroupPolicyTest extends WindowTestsBase { 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.isLetterboxedForFixedOrientationAndAspectRatio()).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.isLetterboxedForFixedOrientationAndAspectRatio()).isTrue(); assertThat(mFirstActivity.inSizeCompatMode()).isFalse(); } Loading