Merge "Letterboxing improvements for tabletop mode" into tm-qpr-dev am: 59326ce728
Original change: https://googleplex-android-review.googlesource.com/c/platform/frameworks/base/+/20111697
Change-Id: I4006f2c9a1a88b530a6d79f83420d268365b6fa5
Signed-off-by: Automerger Merge Worker <android-build-automerger-merge-worker@system.gserviceaccount.com>
diff --git a/core/res/res/values/config.xml b/core/res/res/values/config.xml
index 2060824..4ee8bc3c 100644
--- a/core/res/res/values/config.xml
+++ b/core/res/res/values/config.xml
@@ -5151,6 +5151,15 @@
the format [System DeviceState]:[WM Jetpack Posture], for example: "0:1". -->
<string-array name="config_device_state_postures" translatable="false" />
+ <!-- Which Surface rotations are considered as tabletop posture (horizontal hinge) when the
+ device is half-folded. Other half-folded postures will be assumed to be book (vertical
+ hinge) mode. Units: degrees; valid values: 0, 90, 180, 270. -->
+ <integer-array name="config_deviceTabletopRotations" />
+
+ <!-- This flag indicates that a display with fold-state FLAT should always be considered as
+ having a separating hinge. -->
+ <bool name="config_isDisplayHingeAlwaysSeparating">false</bool>
+
<!-- Aspect ratio of letterboxing for fixed orientation. Values <= 1.0 will be ignored.
Note: Activity min/max aspect ratio restrictions will still be respected.
Therefore this override can control the maximum screen area that can be occupied by
@@ -5199,14 +5208,26 @@
<!-- Horizontal position of a center of the letterboxed app window.
0 corresponds to the left side of the screen and 1 to the right side. If given value < 0
- or > 1, it is ignored and central position is used (0.5). -->
+ or > 1 it is ignored and for non-book mode central position is used (0.5); for book mode
+ left is used (0.0). -->
<item name="config_letterboxHorizontalPositionMultiplier" format="float" type="dimen">0.5</item>
<!-- Vertical position of a center of the letterboxed app window.
0 corresponds to the upper side of the screen and 1 to the lower side. If given value < 0
- or > 1, it is ignored and central position is used (0.5). -->
+ or > 1 it is ignored and for non-tabletop mode central position is used (0.5); for
+ tabletop mode top (0.0) is used. -->
<item name="config_letterboxVerticalPositionMultiplier" format="float" type="dimen">0.0</item>
+ <!-- Horizontal position of a center of the letterboxed app window when in book mode.
+ 0 corresponds to the left side of the screen and 1 to the right side. If given value < 0
+ or > 1, it is ignored and left position is used (0.0). -->
+ <item name="config_letterboxBookModePositionMultiplier" format="float" type="dimen">0.0</item>
+
+ <!-- Vertical position of a center of the letterboxed app window when in tabletop mode.
+ 0 corresponds to the upper side of the screen and 1 to the lower side. If given value < 0
+ or > 1, it is ignored and top position is used (0.0). -->
+ <item name="config_letterboxTabletopModePositionMultiplier" format="float" type="dimen">0.0</item>
+
<!-- Whether horizontal reachability repositioning is allowed for letterboxed fullscreen apps.
-->
<bool name="config_letterboxIsHorizontalReachabilityEnabled">false</bool>
@@ -5234,6 +5255,26 @@
If given value is outside of this range, the option 1 (center) is assummed. -->
<integer name="config_letterboxDefaultPositionForVerticalReachability">1</integer>
+ <!-- Default horizontal position of the letterboxed app window when reachability is
+ enabled and an app is fullscreen in landscape device orientation and in book mode. When
+ reachability is enabled, the position can change between left, center and right. This config
+ defines the default one:
+ - Option 0 - Left.
+ - Option 1 - Center.
+ - Option 2 - Right.
+ If given value is outside of this range, the option 0 (left) is assummed. -->
+ <integer name="config_letterboxDefaultPositionForBookModeReachability">0</integer>
+
+ <!-- Default vertical position of the letterboxed app window when reachability is
+ enabled and an app is fullscreen in portrait device orientation and in tabletop mode. When
+ reachability is enabled, the position can change between top, center and bottom. This config
+ defines the default one:
+ - Option 0 - Top.
+ - Option 1 - Center.
+ - Option 2 - Bottom.
+ If given value is outside of this range, the option 0 (top) is assummed. -->
+ <integer name="config_letterboxDefaultPositionForTabletopModeReachability">0</integer>
+
<!-- Whether displaying letterbox education is enabled for letterboxed fullscreen apps. -->
<bool name="config_letterboxIsEducationEnabled">false</bool>
diff --git a/core/res/res/values/symbols.xml b/core/res/res/values/symbols.xml
index 2b67d64..58c4e5e 100644
--- a/core/res/res/values/symbols.xml
+++ b/core/res/res/values/symbols.xml
@@ -4459,6 +4459,8 @@
<java-symbol type="array" name="config_keep_warming_services" />
<java-symbol type="string" name="config_display_features" />
<java-symbol type="array" name="config_device_state_postures" />
+ <java-symbol type="array" name="config_deviceTabletopRotations" />
+ <java-symbol type="bool" name="config_isDisplayHingeAlwaysSeparating" />
<java-symbol type="dimen" name="controls_thumbnail_image_max_height" />
<java-symbol type="dimen" name="controls_thumbnail_image_max_width" />
@@ -4471,10 +4473,14 @@
<java-symbol type="color" name="config_letterboxBackgroundColor" />
<java-symbol type="dimen" name="config_letterboxHorizontalPositionMultiplier" />
<java-symbol type="dimen" name="config_letterboxVerticalPositionMultiplier" />
+ <java-symbol type="dimen" name="config_letterboxBookModePositionMultiplier" />
+ <java-symbol type="dimen" name="config_letterboxTabletopModePositionMultiplier" />
<java-symbol type="bool" name="config_letterboxIsHorizontalReachabilityEnabled" />
<java-symbol type="bool" name="config_letterboxIsVerticalReachabilityEnabled" />
<java-symbol type="integer" name="config_letterboxDefaultPositionForHorizontalReachability" />
<java-symbol type="integer" name="config_letterboxDefaultPositionForVerticalReachability" />
+ <java-symbol type="integer" name="config_letterboxDefaultPositionForBookModeReachability" />
+ <java-symbol type="integer" name="config_letterboxDefaultPositionForTabletopModeReachability" />
<java-symbol type="bool" name="config_letterboxIsEducationEnabled" />
<java-symbol type="dimen" name="config_letterboxDefaultMinAspectRatioForUnresizableApps" />
<java-symbol type="bool" name="config_letterboxIsSplitScreenAspectRatioForUnresizableAppsEnabled" />
diff --git a/data/etc/services.core.protolog.json b/data/etc/services.core.protolog.json
index 86c8097..49704d9 100644
--- a/data/etc/services.core.protolog.json
+++ b/data/etc/services.core.protolog.json
@@ -1525,6 +1525,12 @@
"group": "WM_DEBUG_FOCUS_LIGHT",
"at": "com\/android\/server\/wm\/DisplayContent.java"
},
+ "-637815408": {
+ "message": "Invalid surface rotation angle in config_deviceTabletopRotations: %d",
+ "level": "ERROR",
+ "group": "WM_DEBUG_ORIENTATION",
+ "at": "com\/android\/server\/wm\/DisplayRotation.java"
+ },
"-636553602": {
"message": "commitVisibility: %s: visible=%b visibleRequested=%b, isInTransition=%b, runningAnimation=%b, caller=%s",
"level": "VERBOSE",
@@ -3193,6 +3199,12 @@
"group": "WM_DEBUG_STATES",
"at": "com\/android\/server\/wm\/TaskFragment.java"
},
+ "939638078": {
+ "message": "config_deviceTabletopRotations is not defined. Half-fold letterboxing will work inconsistently.",
+ "level": "WARN",
+ "group": "WM_DEBUG_ORIENTATION",
+ "at": "com\/android\/server\/wm\/DisplayRotation.java"
+ },
"948208142": {
"message": "Setting Activity.mLauncherTaskBehind to true. Activity=%s",
"level": "DEBUG",
diff --git a/proto/src/windowmanager.proto b/proto/src/windowmanager.proto
index f26404c6..da4dfa9 100644
--- a/proto/src/windowmanager.proto
+++ b/proto/src/windowmanager.proto
@@ -68,4 +68,8 @@
LetterboxHorizontalReachability letterbox_position_for_horizontal_reachability = 1;
// Represents the current vertical position for the letterboxed activity
LetterboxVerticalReachability letterbox_position_for_vertical_reachability = 2;
+ // Represents the current horizontal position for the letterboxed activity in book mode
+ LetterboxHorizontalReachability letterbox_position_for_book_mode_reachability = 3;
+ // Represents the current vertical position for the letterboxed activity in tabletop mode
+ LetterboxVerticalReachability letterbox_position_for_tabletop_mode_reachability = 4;
}
\ No newline at end of file
diff --git a/services/core/java/com/android/server/wm/ActivityRecord.java b/services/core/java/com/android/server/wm/ActivityRecord.java
index 418e1ed..57eeb9a 100644
--- a/services/core/java/com/android/server/wm/ActivityRecord.java
+++ b/services/core/java/com/android/server/wm/ActivityRecord.java
@@ -8149,7 +8149,7 @@
}
/**
- * Adjusts position of resolved bounds if they doesn't fill the parent using gravity
+ * Adjusts position of resolved bounds if they don't fill the parent using gravity
* requested in the config or via an ADB command. For more context see {@link
* LetterboxUiController#getHorizontalPositionMultiplier(Configuration)} and
* {@link LetterboxUiController#getVerticalPositionMultiplier(Configuration)}
@@ -8168,9 +8168,8 @@
int offsetX = 0;
if (parentBounds.width() != screenResolvedBounds.width()) {
if (screenResolvedBounds.width() <= parentAppBounds.width()) {
- float positionMultiplier =
- mLetterboxUiController.getHorizontalPositionMultiplier(
- newParentConfiguration);
+ float positionMultiplier = mLetterboxUiController.getHorizontalPositionMultiplier(
+ newParentConfiguration);
offsetX = (int) Math.ceil((parentAppBounds.width() - screenResolvedBounds.width())
* positionMultiplier);
}
@@ -8180,9 +8179,8 @@
int offsetY = 0;
if (parentBounds.height() != screenResolvedBounds.height()) {
if (screenResolvedBounds.height() <= parentAppBounds.height()) {
- float positionMultiplier =
- mLetterboxUiController.getVerticalPositionMultiplier(
- newParentConfiguration);
+ float positionMultiplier = mLetterboxUiController.getVerticalPositionMultiplier(
+ newParentConfiguration);
offsetY = (int) Math.ceil((parentAppBounds.height() - screenResolvedBounds.height())
* positionMultiplier);
}
diff --git a/services/core/java/com/android/server/wm/DisplayRotation.java b/services/core/java/com/android/server/wm/DisplayRotation.java
index 4fb137b..34bdb7a 100644
--- a/services/core/java/com/android/server/wm/DisplayRotation.java
+++ b/services/core/java/com/android/server/wm/DisplayRotation.java
@@ -16,6 +16,7 @@
package com.android.server.wm;
+import static android.app.WindowConfiguration.WINDOWING_MODE_FULLSCREEN;
import static android.content.pm.ActivityInfo.SCREEN_ORIENTATION_UNSET;
import static android.content.pm.ActivityInfo.SCREEN_ORIENTATION_UNSPECIFIED;
import static android.util.RotationUtils.deltaRotation;
@@ -55,6 +56,7 @@
import android.os.SystemProperties;
import android.os.UserHandle;
import android.provider.Settings;
+import android.util.ArraySet;
import android.util.Slog;
import android.util.TimeUtils;
import android.util.proto.ProtoOutputStream;
@@ -76,6 +78,7 @@
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.util.ArrayDeque;
+import java.util.Set;
/**
* Defines the mapping between orientation and rotation of a display.
@@ -1552,6 +1555,15 @@
proto.end(token);
}
+ boolean isDeviceInPosture(DeviceStateController.FoldState state, boolean isTabletop) {
+ if (mFoldController == null) return false;
+ return mFoldController.isDeviceInPosture(state, isTabletop);
+ }
+
+ boolean isDisplaySeparatingHinge() {
+ return mFoldController != null && mFoldController.isSeparatingHinge();
+ }
+
/**
* Called by the DeviceStateManager callback when the device state changes.
*/
@@ -1569,6 +1581,63 @@
private DeviceStateController.FoldState mFoldState =
DeviceStateController.FoldState.UNKNOWN;
private boolean mInHalfFoldTransition = false;
+ private final boolean mIsDisplayAlwaysSeparatingHinge;
+ private final Set<Integer> mTabletopRotations;
+
+ FoldController() {
+ mTabletopRotations = new ArraySet<>();
+ int[] tabletop_rotations = mContext.getResources().getIntArray(
+ R.array.config_deviceTabletopRotations);
+ if (tabletop_rotations != null) {
+ for (int angle : tabletop_rotations) {
+ switch (angle) {
+ case 0:
+ mTabletopRotations.add(Surface.ROTATION_0);
+ break;
+ case 90:
+ mTabletopRotations.add(Surface.ROTATION_90);
+ break;
+ case 180:
+ mTabletopRotations.add(Surface.ROTATION_180);
+ break;
+ case 270:
+ mTabletopRotations.add(Surface.ROTATION_270);
+ break;
+ default:
+ ProtoLog.e(WM_DEBUG_ORIENTATION,
+ "Invalid surface rotation angle in "
+ + "config_deviceTabletopRotations: %d",
+ angle);
+ }
+ }
+ } else {
+ ProtoLog.w(WM_DEBUG_ORIENTATION,
+ "config_deviceTabletopRotations is not defined. Half-fold "
+ + "letterboxing will work inconsistently.");
+ }
+ mIsDisplayAlwaysSeparatingHinge = mContext.getResources().getBoolean(
+ R.bool.config_isDisplayHingeAlwaysSeparating);
+ }
+
+ boolean isDeviceInPosture(DeviceStateController.FoldState state, boolean isTabletop) {
+ if (state != mFoldState) {
+ return false;
+ }
+ if (mFoldState == DeviceStateController.FoldState.HALF_FOLDED) {
+ return !(isTabletop ^ mTabletopRotations.contains(mRotation));
+ }
+ return true;
+ }
+
+ DeviceStateController.FoldState getFoldState() {
+ return mFoldState;
+ }
+
+ boolean isSeparatingHinge() {
+ return mFoldState == DeviceStateController.FoldState.HALF_FOLDED
+ || (mFoldState == DeviceStateController.FoldState.OPEN
+ && mIsDisplayAlwaysSeparatingHinge);
+ }
boolean overrideFrozenRotation() {
return mFoldState == DeviceStateController.FoldState.HALF_FOLDED;
@@ -1617,6 +1686,15 @@
mService.updateRotation(false /* alwaysSendConfiguration */,
false /* forceRelayout */);
}
+ // Alert the activity of possible new bounds.
+ final Task topFullscreenTask =
+ mDisplayContent.getTask(t -> t.getWindowingMode() == WINDOWING_MODE_FULLSCREEN);
+ if (topFullscreenTask != null) {
+ final ActivityRecord top = topFullscreenTask.topRunningActivity();
+ if (top != null) {
+ top.recomputeConfiguration();
+ }
+ }
}
}
diff --git a/services/core/java/com/android/server/wm/LetterboxConfiguration.java b/services/core/java/com/android/server/wm/LetterboxConfiguration.java
index 127a7bf..3eca364 100644
--- a/services/core/java/com/android/server/wm/LetterboxConfiguration.java
+++ b/services/core/java/com/android/server/wm/LetterboxConfiguration.java
@@ -16,12 +16,16 @@
package com.android.server.wm;
+import static com.android.server.wm.ActivityTaskManagerDebugConfig.TAG_ATM;
+import static com.android.server.wm.ActivityTaskManagerDebugConfig.TAG_WITH_CLASS_NAME;
+
import android.annotation.IntDef;
import android.annotation.NonNull;
import android.annotation.Nullable;
import android.content.Context;
import android.graphics.Color;
import android.provider.DeviceConfig;
+import android.util.Slog;
import com.android.internal.R;
import com.android.internal.annotations.VisibleForTesting;
@@ -33,6 +37,8 @@
/** Reads letterbox configs from resources and controls their overrides at runtime. */
final class LetterboxConfiguration {
+ private static final String TAG = TAG_WITH_CLASS_NAME ? "LetterboxConfiguration" : TAG_ATM;
+
/**
* Override of aspect ratio for fixed orientation letterboxing that is set via ADB with
* set-fixed-orientation-letterbox-aspect-ratio or via {@link
@@ -144,6 +150,14 @@
// side of the screen and 1.0 to the bottom side.
private float mLetterboxVerticalPositionMultiplier;
+ // Horizontal position of a center of the letterboxed app window when the device is half-folded.
+ // 0 corresponds to the left side of the screen and 1.0 to the right side.
+ private float mLetterboxBookModePositionMultiplier;
+
+ // Vertical position of a center of the letterboxed app window when the device is half-folded.
+ // 0 corresponds to the top side of the screen and 1.0 to the bottom side.
+ private float mLetterboxTabletopModePositionMultiplier;
+
// Default horizontal position the letterboxed app window when horizontal reachability is
// enabled and an app is fullscreen in landscape device orientation.
// It is used as a starting point for mLetterboxPositionForHorizontalReachability.
@@ -179,8 +193,15 @@
LetterboxConfiguration(Context systemUiContext) {
this(systemUiContext, new LetterboxConfigurationPersister(systemUiContext,
- () -> readLetterboxHorizontalReachabilityPositionFromConfig(systemUiContext),
- () -> readLetterboxVerticalReachabilityPositionFromConfig(systemUiContext)));
+ () -> readLetterboxHorizontalReachabilityPositionFromConfig(systemUiContext,
+ /* forBookMode */ false),
+ () -> readLetterboxVerticalReachabilityPositionFromConfig(systemUiContext,
+ /* forTabletopMode */ false),
+ () -> readLetterboxHorizontalReachabilityPositionFromConfig(systemUiContext,
+ /* forBookMode */ true),
+ () -> readLetterboxVerticalReachabilityPositionFromConfig(systemUiContext,
+ /* forTabletopMode */ true)
+ ));
}
@VisibleForTesting
@@ -200,14 +221,18 @@
R.dimen.config_letterboxHorizontalPositionMultiplier);
mLetterboxVerticalPositionMultiplier = mContext.getResources().getFloat(
R.dimen.config_letterboxVerticalPositionMultiplier);
+ mLetterboxBookModePositionMultiplier = mContext.getResources().getFloat(
+ R.dimen.config_letterboxBookModePositionMultiplier);
+ mLetterboxTabletopModePositionMultiplier = mContext.getResources().getFloat(
+ R.dimen.config_letterboxTabletopModePositionMultiplier);
mIsHorizontalReachabilityEnabled = mContext.getResources().getBoolean(
R.bool.config_letterboxIsHorizontalReachabilityEnabled);
mIsVerticalReachabilityEnabled = mContext.getResources().getBoolean(
R.bool.config_letterboxIsVerticalReachabilityEnabled);
mDefaultPositionForHorizontalReachability =
- readLetterboxHorizontalReachabilityPositionFromConfig(mContext);
+ readLetterboxHorizontalReachabilityPositionFromConfig(mContext, false);
mDefaultPositionForVerticalReachability =
- readLetterboxVerticalReachabilityPositionFromConfig(mContext);
+ readLetterboxVerticalReachabilityPositionFromConfig(mContext, false);
mIsEducationEnabled = mContext.getResources().getBoolean(
R.bool.config_letterboxIsEducationEnabled);
setDefaultMinAspectRatioForUnresizableApps(mContext.getResources().getFloat(
@@ -460,11 +485,30 @@
* or via an ADB command. 0 corresponds to the left side of the screen and 1 to the
* right side.
*/
- float getLetterboxHorizontalPositionMultiplier() {
- return (mLetterboxHorizontalPositionMultiplier < 0.0f
- || mLetterboxHorizontalPositionMultiplier > 1.0f)
- // Default to central position if invalid value is provided.
- ? 0.5f : mLetterboxHorizontalPositionMultiplier;
+ float getLetterboxHorizontalPositionMultiplier(boolean isInBookMode) {
+ if (isInBookMode) {
+ if (mLetterboxBookModePositionMultiplier < 0.0f
+ || mLetterboxBookModePositionMultiplier > 1.0f) {
+ Slog.w(TAG,
+ "mLetterboxBookModePositionMultiplier out of bounds (isInBookMode=true): "
+ + mLetterboxBookModePositionMultiplier);
+ // Default to left position if invalid value is provided.
+ return 0.0f;
+ } else {
+ return mLetterboxBookModePositionMultiplier;
+ }
+ } else {
+ if (mLetterboxHorizontalPositionMultiplier < 0.0f
+ || mLetterboxHorizontalPositionMultiplier > 1.0f) {
+ Slog.w(TAG,
+ "mLetterboxBookModePositionMultiplier out of bounds (isInBookMode=false):"
+ + mLetterboxBookModePositionMultiplier);
+ // Default to central position if invalid value is provided.
+ return 0.5f;
+ } else {
+ return mLetterboxHorizontalPositionMultiplier;
+ }
+ }
}
/*
@@ -473,11 +517,18 @@
* or via an ADB command. 0 corresponds to the top side of the screen and 1 to the
* bottom side.
*/
- float getLetterboxVerticalPositionMultiplier() {
- return (mLetterboxVerticalPositionMultiplier < 0.0f
- || mLetterboxVerticalPositionMultiplier > 1.0f)
- // Default to central position if invalid value is provided.
- ? 0.5f : mLetterboxVerticalPositionMultiplier;
+ float getLetterboxVerticalPositionMultiplier(boolean isInTabletopMode) {
+ if (isInTabletopMode) {
+ return (mLetterboxTabletopModePositionMultiplier < 0.0f
+ || mLetterboxTabletopModePositionMultiplier > 1.0f)
+ // Default to top position if invalid value is provided.
+ ? 0.0f : mLetterboxTabletopModePositionMultiplier;
+ } else {
+ return (mLetterboxVerticalPositionMultiplier < 0.0f
+ || mLetterboxVerticalPositionMultiplier > 1.0f)
+ // Default to central position if invalid value is provided.
+ ? 0.5f : mLetterboxVerticalPositionMultiplier;
+ }
}
/**
@@ -618,7 +669,8 @@
*/
void resetDefaultPositionForHorizontalReachability() {
mDefaultPositionForHorizontalReachability =
- readLetterboxHorizontalReachabilityPositionFromConfig(mContext);
+ readLetterboxHorizontalReachabilityPositionFromConfig(mContext,
+ false /* forBookMode */);
}
/**
@@ -627,27 +679,34 @@
*/
void resetDefaultPositionForVerticalReachability() {
mDefaultPositionForVerticalReachability =
- readLetterboxVerticalReachabilityPositionFromConfig(mContext);
+ readLetterboxVerticalReachabilityPositionFromConfig(mContext,
+ false /* forTabletopMode */);
}
@LetterboxHorizontalReachabilityPosition
- private static int readLetterboxHorizontalReachabilityPositionFromConfig(Context context) {
+ private static int readLetterboxHorizontalReachabilityPositionFromConfig(Context context,
+ boolean forBookMode) {
int position = context.getResources().getInteger(
- R.integer.config_letterboxDefaultPositionForHorizontalReachability);
+ forBookMode
+ ? R.integer.config_letterboxDefaultPositionForBookModeReachability
+ : R.integer.config_letterboxDefaultPositionForHorizontalReachability);
return position == LETTERBOX_HORIZONTAL_REACHABILITY_POSITION_LEFT
- || position == LETTERBOX_HORIZONTAL_REACHABILITY_POSITION_CENTER
- || position == LETTERBOX_HORIZONTAL_REACHABILITY_POSITION_RIGHT
+ || position == LETTERBOX_HORIZONTAL_REACHABILITY_POSITION_CENTER
+ || position == LETTERBOX_HORIZONTAL_REACHABILITY_POSITION_RIGHT
? position : LETTERBOX_HORIZONTAL_REACHABILITY_POSITION_CENTER;
}
@LetterboxVerticalReachabilityPosition
- private static int readLetterboxVerticalReachabilityPositionFromConfig(Context context) {
+ private static int readLetterboxVerticalReachabilityPositionFromConfig(Context context,
+ boolean forTabletopMode) {
int position = context.getResources().getInteger(
- R.integer.config_letterboxDefaultPositionForVerticalReachability);
+ forTabletopMode
+ ? R.integer.config_letterboxDefaultPositionForTabletopModeReachability
+ : R.integer.config_letterboxDefaultPositionForVerticalReachability);
return position == LETTERBOX_VERTICAL_REACHABILITY_POSITION_TOP
|| position == LETTERBOX_VERTICAL_REACHABILITY_POSITION_CENTER
|| position == LETTERBOX_VERTICAL_REACHABILITY_POSITION_BOTTOM
- ? position : LETTERBOX_VERTICAL_REACHABILITY_POSITION_CENTER;
+ ? position : LETTERBOX_VERTICAL_REACHABILITY_POSITION_CENTER;
}
/*
@@ -656,9 +715,10 @@
*
* <p>The position multiplier is changed after each double tap in the letterbox area.
*/
- float getHorizontalMultiplierForReachability() {
+ float getHorizontalMultiplierForReachability(boolean isDeviceInBookMode) {
final int letterboxPositionForHorizontalReachability =
- mLetterboxConfigurationPersister.getLetterboxPositionForHorizontalReachability();
+ mLetterboxConfigurationPersister.getLetterboxPositionForHorizontalReachability(
+ isDeviceInBookMode);
switch (letterboxPositionForHorizontalReachability) {
case LETTERBOX_HORIZONTAL_REACHABILITY_POSITION_LEFT:
return 0.0f;
@@ -679,9 +739,10 @@
*
* <p>The position multiplier is changed after each double tap in the letterbox area.
*/
- float getVerticalMultiplierForReachability() {
+ float getVerticalMultiplierForReachability(boolean isDeviceInTabletopMode) {
final int letterboxPositionForVerticalReachability =
- mLetterboxConfigurationPersister.getLetterboxPositionForVerticalReachability();
+ mLetterboxConfigurationPersister.getLetterboxPositionForVerticalReachability(
+ isDeviceInTabletopMode);
switch (letterboxPositionForVerticalReachability) {
case LETTERBOX_VERTICAL_REACHABILITY_POSITION_TOP:
return 0.0f;
@@ -701,8 +762,9 @@
* enabled.
*/
@LetterboxHorizontalReachabilityPosition
- int getLetterboxPositionForHorizontalReachability() {
- return mLetterboxConfigurationPersister.getLetterboxPositionForHorizontalReachability();
+ int getLetterboxPositionForHorizontalReachability(boolean isInFullScreenBookMode) {
+ return mLetterboxConfigurationPersister.getLetterboxPositionForHorizontalReachability(
+ isInFullScreenBookMode);
}
/*
@@ -710,8 +772,9 @@
* enabled.
*/
@LetterboxVerticalReachabilityPosition
- int getLetterboxPositionForVerticalReachability() {
- return mLetterboxConfigurationPersister.getLetterboxPositionForVerticalReachability();
+ int getLetterboxPositionForVerticalReachability(boolean isInFullScreenTabletopMode) {
+ return mLetterboxConfigurationPersister.getLetterboxPositionForVerticalReachability(
+ isInFullScreenTabletopMode);
}
/** Returns a string representing the given {@link LetterboxHorizontalReachabilityPosition}. */
@@ -750,34 +813,41 @@
* Changes letterbox position for horizontal reachability to the next available one on the
* right side.
*/
- void movePositionForHorizontalReachabilityToNextRightStop() {
- updatePositionForHorizontalReachability(prev -> Math.min(
- prev + 1, LETTERBOX_HORIZONTAL_REACHABILITY_POSITION_RIGHT));
+ void movePositionForHorizontalReachabilityToNextRightStop(boolean isDeviceInBookMode) {
+ updatePositionForHorizontalReachability(isDeviceInBookMode, prev -> Math.min(
+ prev + (isDeviceInBookMode ? 2 : 1), // Move 2 stops in book mode to avoid center.
+ LETTERBOX_HORIZONTAL_REACHABILITY_POSITION_RIGHT));
}
/**
* Changes letterbox position for horizontal reachability to the next available one on the left
* side.
*/
- void movePositionForHorizontalReachabilityToNextLeftStop() {
- updatePositionForHorizontalReachability(prev -> Math.max(prev - 1, 0));
+ void movePositionForHorizontalReachabilityToNextLeftStop(boolean isDeviceInBookMode) {
+ updatePositionForHorizontalReachability(isDeviceInBookMode, prev -> Math.max(
+ prev - (isDeviceInBookMode ? 2 : 1), 0)); // Move 2 stops in book mode to avoid
+ // center.
}
/**
* Changes letterbox position for vertical reachability to the next available one on the bottom
* side.
*/
- void movePositionForVerticalReachabilityToNextBottomStop() {
- updatePositionForVerticalReachability(prev -> Math.min(
- prev + 1, LETTERBOX_VERTICAL_REACHABILITY_POSITION_BOTTOM));
+ void movePositionForVerticalReachabilityToNextBottomStop(boolean isDeviceInTabletopMode) {
+ updatePositionForVerticalReachability(isDeviceInTabletopMode, prev -> Math.min(
+ prev + (isDeviceInTabletopMode ? 2 : 1), // Move 2 stops in tabletop mode to avoid
+ // center.
+ LETTERBOX_VERTICAL_REACHABILITY_POSITION_BOTTOM));
}
/**
* Changes letterbox position for vertical reachability to the next available one on the top
* side.
*/
- void movePositionForVerticalReachabilityToNextTopStop() {
- updatePositionForVerticalReachability(prev -> Math.max(prev - 1, 0));
+ void movePositionForVerticalReachabilityToNextTopStop(boolean isDeviceInTabletopMode) {
+ updatePositionForVerticalReachability(isDeviceInTabletopMode, prev -> Math.max(
+ prev - (isDeviceInTabletopMode ? 2 : 1), 0)); // Move 2 stops in tabletop mode to
+ // avoid center.
}
/**
@@ -854,25 +924,27 @@
}
/** Calculates a new letterboxPositionForHorizontalReachability value and updates the store */
- private void updatePositionForHorizontalReachability(
+ private void updatePositionForHorizontalReachability(boolean isDeviceInBookMode,
Function<Integer, Integer> newHorizonalPositionFun) {
final int letterboxPositionForHorizontalReachability =
- mLetterboxConfigurationPersister.getLetterboxPositionForHorizontalReachability();
+ mLetterboxConfigurationPersister.getLetterboxPositionForHorizontalReachability(
+ isDeviceInBookMode);
final int nextHorizontalPosition = newHorizonalPositionFun.apply(
letterboxPositionForHorizontalReachability);
mLetterboxConfigurationPersister.setLetterboxPositionForHorizontalReachability(
- nextHorizontalPosition);
+ isDeviceInBookMode, nextHorizontalPosition);
}
/** Calculates a new letterboxPositionForVerticalReachability value and updates the store */
- private void updatePositionForVerticalReachability(
+ private void updatePositionForVerticalReachability(boolean isDeviceInTabletopMode,
Function<Integer, Integer> newVerticalPositionFun) {
final int letterboxPositionForVerticalReachability =
- mLetterboxConfigurationPersister.getLetterboxPositionForVerticalReachability();
+ mLetterboxConfigurationPersister.getLetterboxPositionForVerticalReachability(
+ isDeviceInTabletopMode);
final int nextVerticalPosition = newVerticalPositionFun.apply(
letterboxPositionForVerticalReachability);
mLetterboxConfigurationPersister.setLetterboxPositionForVerticalReachability(
- nextVerticalPosition);
+ isDeviceInTabletopMode, nextVerticalPosition);
}
// TODO(b/262378106): Cache runtime flag and implement DeviceConfig.OnPropertiesChangedListener
diff --git a/services/core/java/com/android/server/wm/LetterboxConfigurationPersister.java b/services/core/java/com/android/server/wm/LetterboxConfigurationPersister.java
index 70639b1..4a99db5 100644
--- a/services/core/java/com/android/server/wm/LetterboxConfigurationPersister.java
+++ b/services/core/java/com/android/server/wm/LetterboxConfigurationPersister.java
@@ -55,6 +55,8 @@
private final Context mContext;
private final Supplier<Integer> mDefaultHorizontalReachabilitySupplier;
private final Supplier<Integer> mDefaultVerticalReachabilitySupplier;
+ private final Supplier<Integer> mDefaultBookModeReachabilitySupplier;
+ private final Supplier<Integer> mDefaultTabletopModeReachabilitySupplier;
// Horizontal position of a center of the letterboxed app window which is global to prevent
// "jumps" when switching between letterboxed apps. It's updated to reposition the app window
@@ -64,6 +66,11 @@
@LetterboxHorizontalReachabilityPosition
private volatile int mLetterboxPositionForHorizontalReachability;
+ // The same as mLetterboxPositionForHorizontalReachability but used when the device is
+ // half-folded.
+ @LetterboxHorizontalReachabilityPosition
+ private volatile int mLetterboxPositionForBookModeReachability;
+
// Vertical position of a center of the letterboxed app window which is global to prevent
// "jumps" when switching between letterboxed apps. It's updated to reposition the app window
// in response to a double tap gesture (see LetterboxUiController#handleDoubleTap). Used in
@@ -72,6 +79,11 @@
@LetterboxVerticalReachabilityPosition
private volatile int mLetterboxPositionForVerticalReachability;
+ // The same as mLetterboxPositionForVerticalReachability but used when the device is
+ // half-folded.
+ @LetterboxVerticalReachabilityPosition
+ private volatile int mLetterboxPositionForTabletopModeReachability;
+
@NonNull
private final AtomicFile mConfigurationFile;
@@ -83,9 +95,13 @@
LetterboxConfigurationPersister(Context systemUiContext,
Supplier<Integer> defaultHorizontalReachabilitySupplier,
- Supplier<Integer> defaultVerticalReachabilitySupplier) {
+ Supplier<Integer> defaultVerticalReachabilitySupplier,
+ Supplier<Integer> defaultBookModeReachabilitySupplier,
+ Supplier<Integer> defaultTabletopModeReachabilitySupplier) {
this(systemUiContext, defaultHorizontalReachabilitySupplier,
defaultVerticalReachabilitySupplier,
+ defaultBookModeReachabilitySupplier,
+ defaultTabletopModeReachabilitySupplier,
Environment.getDataSystemDirectory(), new PersisterQueue(),
/* completionCallback */ null);
}
@@ -93,11 +109,18 @@
@VisibleForTesting
LetterboxConfigurationPersister(Context systemUiContext,
Supplier<Integer> defaultHorizontalReachabilitySupplier,
- Supplier<Integer> defaultVerticalReachabilitySupplier, File configFolder,
+ Supplier<Integer> defaultVerticalReachabilitySupplier,
+ Supplier<Integer> defaultBookModeReachabilitySupplier,
+ Supplier<Integer> defaultTabletopModeReachabilitySupplier,
+ File configFolder,
PersisterQueue persisterQueue, @Nullable Consumer<String> completionCallback) {
mContext = systemUiContext.createDeviceProtectedStorageContext();
mDefaultHorizontalReachabilitySupplier = defaultHorizontalReachabilitySupplier;
mDefaultVerticalReachabilitySupplier = defaultVerticalReachabilitySupplier;
+ mDefaultBookModeReachabilitySupplier =
+ defaultBookModeReachabilitySupplier;
+ mDefaultTabletopModeReachabilitySupplier =
+ defaultTabletopModeReachabilitySupplier;
mCompletionCallback = completionCallback;
final File prefFiles = new File(configFolder, LETTERBOX_CONFIGURATION_FILENAME);
mConfigurationFile = new AtomicFile(prefFiles);
@@ -117,8 +140,12 @@
* enabled.
*/
@LetterboxHorizontalReachabilityPosition
- int getLetterboxPositionForHorizontalReachability() {
- return mLetterboxPositionForHorizontalReachability;
+ int getLetterboxPositionForHorizontalReachability(boolean forBookMode) {
+ if (forBookMode) {
+ return mLetterboxPositionForBookModeReachability;
+ } else {
+ return mLetterboxPositionForHorizontalReachability;
+ }
}
/*
@@ -126,31 +153,55 @@
* enabled.
*/
@LetterboxVerticalReachabilityPosition
- int getLetterboxPositionForVerticalReachability() {
- return mLetterboxPositionForVerticalReachability;
- }
-
- /**
- * Updates letterboxPositionForVerticalReachability if different from the current value
- */
- void setLetterboxPositionForHorizontalReachability(
- int letterboxPositionForHorizontalReachability) {
- if (mLetterboxPositionForHorizontalReachability
- != letterboxPositionForHorizontalReachability) {
- mLetterboxPositionForHorizontalReachability =
- letterboxPositionForHorizontalReachability;
- updateConfiguration();
+ int getLetterboxPositionForVerticalReachability(boolean forTabletopMode) {
+ if (forTabletopMode) {
+ return mLetterboxPositionForTabletopModeReachability;
+ } else {
+ return mLetterboxPositionForVerticalReachability;
}
}
/**
* Updates letterboxPositionForVerticalReachability if different from the current value
*/
- void setLetterboxPositionForVerticalReachability(
+ void setLetterboxPositionForHorizontalReachability(boolean forBookMode,
+ int letterboxPositionForHorizontalReachability) {
+ if (forBookMode) {
+ if (mLetterboxPositionForBookModeReachability
+ != letterboxPositionForHorizontalReachability) {
+ mLetterboxPositionForBookModeReachability =
+ letterboxPositionForHorizontalReachability;
+ updateConfiguration();
+ }
+ } else {
+ if (mLetterboxPositionForHorizontalReachability
+ != letterboxPositionForHorizontalReachability) {
+ mLetterboxPositionForHorizontalReachability =
+ letterboxPositionForHorizontalReachability;
+ updateConfiguration();
+ }
+ }
+ }
+
+ /**
+ * Updates letterboxPositionForVerticalReachability if different from the current value
+ */
+ void setLetterboxPositionForVerticalReachability(boolean forTabletopMode,
int letterboxPositionForVerticalReachability) {
- if (mLetterboxPositionForVerticalReachability != letterboxPositionForVerticalReachability) {
- mLetterboxPositionForVerticalReachability = letterboxPositionForVerticalReachability;
- updateConfiguration();
+ if (forTabletopMode) {
+ if (mLetterboxPositionForTabletopModeReachability
+ != letterboxPositionForVerticalReachability) {
+ mLetterboxPositionForTabletopModeReachability =
+ letterboxPositionForVerticalReachability;
+ updateConfiguration();
+ }
+ } else {
+ if (mLetterboxPositionForVerticalReachability
+ != letterboxPositionForVerticalReachability) {
+ mLetterboxPositionForVerticalReachability =
+ letterboxPositionForVerticalReachability;
+ updateConfiguration();
+ }
}
}
@@ -158,6 +209,10 @@
void useDefaultValue() {
mLetterboxPositionForHorizontalReachability = mDefaultHorizontalReachabilitySupplier.get();
mLetterboxPositionForVerticalReachability = mDefaultVerticalReachabilitySupplier.get();
+ mLetterboxPositionForBookModeReachability =
+ mDefaultBookModeReachabilitySupplier.get();
+ mLetterboxPositionForTabletopModeReachability =
+ mDefaultTabletopModeReachabilitySupplier.get();
}
private void readCurrentConfiguration() {
@@ -171,6 +226,10 @@
letterboxData.letterboxPositionForHorizontalReachability;
mLetterboxPositionForVerticalReachability =
letterboxData.letterboxPositionForVerticalReachability;
+ mLetterboxPositionForBookModeReachability =
+ letterboxData.letterboxPositionForBookModeReachability;
+ mLetterboxPositionForTabletopModeReachability =
+ letterboxData.letterboxPositionForTabletopModeReachability;
} catch (IOException ioe) {
Slog.e(TAG,
"Error reading from LetterboxConfigurationPersister. "
@@ -192,6 +251,8 @@
mPersisterQueue.addItem(new UpdateValuesCommand(mConfigurationFile,
mLetterboxPositionForHorizontalReachability,
mLetterboxPositionForVerticalReachability,
+ mLetterboxPositionForBookModeReachability,
+ mLetterboxPositionForTabletopModeReachability,
mCompletionCallback), /* flush */ true);
}
@@ -221,13 +282,18 @@
private final int mHorizontalReachability;
private final int mVerticalReachability;
+ private final int mBookModeReachability;
+ private final int mTabletopModeReachability;
UpdateValuesCommand(@NonNull AtomicFile fileToUpdate,
int horizontalReachability, int verticalReachability,
+ int bookModeReachability, int tabletopModeReachability,
@Nullable Consumer<String> onComplete) {
mFileToUpdate = fileToUpdate;
mHorizontalReachability = horizontalReachability;
mVerticalReachability = verticalReachability;
+ mBookModeReachability = bookModeReachability;
+ mTabletopModeReachability = tabletopModeReachability;
mOnComplete = onComplete;
}
@@ -237,6 +303,10 @@
new WindowManagerProtos.LetterboxProto();
letterboxData.letterboxPositionForHorizontalReachability = mHorizontalReachability;
letterboxData.letterboxPositionForVerticalReachability = mVerticalReachability;
+ letterboxData.letterboxPositionForBookModeReachability =
+ mBookModeReachability;
+ letterboxData.letterboxPositionForTabletopModeReachability =
+ mTabletopModeReachability;
final byte[] bytes = WindowManagerProtos.LetterboxProto.toByteArray(letterboxData);
FileOutputStream fos = null;
diff --git a/services/core/java/com/android/server/wm/LetterboxUiController.java b/services/core/java/com/android/server/wm/LetterboxUiController.java
index a53a5fc..9cb94c6 100644
--- a/services/core/java/com/android/server/wm/LetterboxUiController.java
+++ b/services/core/java/com/android/server/wm/LetterboxUiController.java
@@ -275,30 +275,62 @@
&& mActivityRecord.fillsParent();
}
+ // Check if we are in the given pose and in fullscreen mode.
+ // Note that we check the task rather than the parent as with ActivityEmbedding the parent might
+ // be a TaskFragment, and its windowing mode is always MULTI_WINDOW, even if the task is
+ // actually fullscreen.
+ private boolean isDisplayFullScreenAndInPosture(DeviceStateController.FoldState state,
+ boolean isTabletop) {
+ Task task = mActivityRecord.getTask();
+ return mActivityRecord.mDisplayContent != null
+ && mActivityRecord.mDisplayContent.getDisplayRotation().isDeviceInPosture(state,
+ isTabletop)
+ && task != null
+ && task.getWindowingMode() == WINDOWING_MODE_FULLSCREEN;
+ }
+
+ // Note that we check the task rather than the parent as with ActivityEmbedding the parent might
+ // be a TaskFragment, and its windowing mode is always MULTI_WINDOW, even if the task is
+ // actually fullscreen.
+ private boolean isDisplayFullScreenAndSeparatingHinge() {
+ Task task = mActivityRecord.getTask();
+ return mActivityRecord.mDisplayContent != null
+ && mActivityRecord.mDisplayContent.getDisplayRotation().isDisplaySeparatingHinge()
+ && task != null
+ && task.getWindowingMode() == WINDOWING_MODE_FULLSCREEN;
+ }
+
+
float getHorizontalPositionMultiplier(Configuration parentConfiguration) {
// Don't check resolved configuration because it may not be updated yet during
// configuration change.
+ boolean bookMode = isDisplayFullScreenAndInPosture(
+ DeviceStateController.FoldState.HALF_FOLDED, false /* isTabletop */);
return isHorizontalReachabilityEnabled(parentConfiguration)
// Using the last global dynamic position to avoid "jumps" when moving
// between apps or activities.
- ? mLetterboxConfiguration.getHorizontalMultiplierForReachability()
- : mLetterboxConfiguration.getLetterboxHorizontalPositionMultiplier();
+ ? mLetterboxConfiguration.getHorizontalMultiplierForReachability(bookMode)
+ : mLetterboxConfiguration.getLetterboxHorizontalPositionMultiplier(bookMode);
}
float getVerticalPositionMultiplier(Configuration parentConfiguration) {
// Don't check resolved configuration because it may not be updated yet during
// configuration change.
+ boolean tabletopMode = isDisplayFullScreenAndInPosture(
+ DeviceStateController.FoldState.HALF_FOLDED, true /* isTabletop */);
return isVerticalReachabilityEnabled(parentConfiguration)
// Using the last global dynamic position to avoid "jumps" when moving
// between apps or activities.
- ? mLetterboxConfiguration.getVerticalMultiplierForReachability()
- : mLetterboxConfiguration.getLetterboxVerticalPositionMultiplier();
+ ? mLetterboxConfiguration.getVerticalMultiplierForReachability(tabletopMode)
+ : mLetterboxConfiguration.getLetterboxVerticalPositionMultiplier(tabletopMode);
}
float getFixedOrientationLetterboxAspectRatio() {
- return mActivityRecord.shouldCreateCompatDisplayInsets()
- ? getDefaultMinAspectRatioForUnresizableApps()
- : mLetterboxConfiguration.getFixedOrientationLetterboxAspectRatio();
+ return isDisplayFullScreenAndSeparatingHinge()
+ ? getSplitScreenAspectRatio()
+ : mActivityRecord.shouldCreateCompatDisplayInsets()
+ ? getDefaultMinAspectRatioForUnresizableApps()
+ : mLetterboxConfiguration.getFixedOrientationLetterboxAspectRatio();
}
private float getDefaultMinAspectRatioForUnresizableApps() {
@@ -351,11 +383,13 @@
return;
}
+ boolean isInFullScreenBookMode = isDisplayFullScreenAndSeparatingHinge();
int letterboxPositionForHorizontalReachability = mLetterboxConfiguration
- .getLetterboxPositionForHorizontalReachability();
+ .getLetterboxPositionForHorizontalReachability(isInFullScreenBookMode);
if (mLetterbox.getInnerFrame().left > x) {
// Moving to the next stop on the left side of the app window: right > center > left.
- mLetterboxConfiguration.movePositionForHorizontalReachabilityToNextLeftStop();
+ mLetterboxConfiguration.movePositionForHorizontalReachabilityToNextLeftStop(
+ isInFullScreenBookMode);
int changeToLog =
letterboxPositionForHorizontalReachability
== LETTERBOX_HORIZONTAL_REACHABILITY_POSITION_CENTER
@@ -364,7 +398,8 @@
logLetterboxPositionChange(changeToLog);
} else if (mLetterbox.getInnerFrame().right < x) {
// Moving to the next stop on the right side of the app window: left > center > right.
- mLetterboxConfiguration.movePositionForHorizontalReachabilityToNextRightStop();
+ mLetterboxConfiguration.movePositionForHorizontalReachabilityToNextRightStop(
+ isInFullScreenBookMode);
int changeToLog =
letterboxPositionForHorizontalReachability
== LETTERBOX_HORIZONTAL_REACHABILITY_POSITION_CENTER
@@ -388,11 +423,13 @@
// Only react to clicks at the top and bottom of the letterboxed app window.
return;
}
+ boolean isInFullScreenTabletopMode = isDisplayFullScreenAndSeparatingHinge();
int letterboxPositionForVerticalReachability = mLetterboxConfiguration
- .getLetterboxPositionForVerticalReachability();
+ .getLetterboxPositionForVerticalReachability(isInFullScreenTabletopMode);
if (mLetterbox.getInnerFrame().top > y) {
// Moving to the next stop on the top side of the app window: bottom > center > top.
- mLetterboxConfiguration.movePositionForVerticalReachabilityToNextTopStop();
+ mLetterboxConfiguration.movePositionForVerticalReachabilityToNextTopStop(
+ isInFullScreenTabletopMode);
int changeToLog =
letterboxPositionForVerticalReachability
== LETTERBOX_VERTICAL_REACHABILITY_POSITION_CENTER
@@ -401,7 +438,8 @@
logLetterboxPositionChange(changeToLog);
} else if (mLetterbox.getInnerFrame().bottom < y) {
// Moving to the next stop on the bottom side of the app window: top > center > bottom.
- mLetterboxConfiguration.movePositionForVerticalReachabilityToNextBottomStop();
+ mLetterboxConfiguration.movePositionForVerticalReachabilityToNextBottomStop(
+ isInFullScreenTabletopMode);
int changeToLog =
letterboxPositionForVerticalReachability
== LETTERBOX_VERTICAL_REACHABILITY_POSITION_CENTER
@@ -712,10 +750,10 @@
+ getVerticalPositionMultiplier(mActivityRecord.getParent().getConfiguration()));
pw.println(prefix + " letterboxPositionForHorizontalReachability="
+ LetterboxConfiguration.letterboxHorizontalReachabilityPositionToString(
- mLetterboxConfiguration.getLetterboxPositionForHorizontalReachability()));
+ mLetterboxConfiguration.getLetterboxPositionForHorizontalReachability(false)));
pw.println(prefix + " letterboxPositionForVerticalReachability="
+ LetterboxConfiguration.letterboxVerticalReachabilityPositionToString(
- mLetterboxConfiguration.getLetterboxPositionForVerticalReachability()));
+ mLetterboxConfiguration.getLetterboxPositionForVerticalReachability(false)));
pw.println(prefix + " fixedOrientationLetterboxAspectRatio="
+ mLetterboxConfiguration.getFixedOrientationLetterboxAspectRatio());
pw.println(prefix + " defaultMinAspectRatioForUnresizableApps="
@@ -780,14 +818,20 @@
int positionToLog = APP_COMPAT_STATE_CHANGED__LETTERBOX_POSITION__UNKNOWN_POSITION;
if (isHorizontalReachabilityEnabled()) {
int letterboxPositionForHorizontalReachability = getLetterboxConfiguration()
- .getLetterboxPositionForHorizontalReachability();
+ .getLetterboxPositionForHorizontalReachability(
+ isDisplayFullScreenAndInPosture(
+ DeviceStateController.FoldState.HALF_FOLDED,
+ false /* isTabletop */));
positionToLog = letterboxHorizontalReachabilityPositionToLetterboxPosition(
- letterboxPositionForHorizontalReachability);
+ letterboxPositionForHorizontalReachability);
} else if (isVerticalReachabilityEnabled()) {
int letterboxPositionForVerticalReachability = getLetterboxConfiguration()
- .getLetterboxPositionForVerticalReachability();
+ .getLetterboxPositionForVerticalReachability(
+ isDisplayFullScreenAndInPosture(
+ DeviceStateController.FoldState.HALF_FOLDED,
+ true /* isTabletop */));
positionToLog = letterboxVerticalReachabilityPositionToLetterboxPosition(
- letterboxPositionForVerticalReachability);
+ letterboxPositionForVerticalReachability);
}
return positionToLog;
}
diff --git a/services/core/java/com/android/server/wm/WindowManagerShellCommand.java b/services/core/java/com/android/server/wm/WindowManagerShellCommand.java
index 4e692e2d..85aa942 100644
--- a/services/core/java/com/android/server/wm/WindowManagerShellCommand.java
+++ b/services/core/java/com/android/server/wm/WindowManagerShellCommand.java
@@ -1219,9 +1219,17 @@
pw.println("Corner radius: "
+ mLetterboxConfiguration.getLetterboxActivityCornersRadius());
pw.println("Horizontal position multiplier: "
- + mLetterboxConfiguration.getLetterboxHorizontalPositionMultiplier());
+ + mLetterboxConfiguration.getLetterboxHorizontalPositionMultiplier(
+ false /* isInBookMode */));
pw.println("Vertical position multiplier: "
- + mLetterboxConfiguration.getLetterboxVerticalPositionMultiplier());
+ + mLetterboxConfiguration.getLetterboxVerticalPositionMultiplier(
+ false /* isInTabletopMode */));
+ pw.println("Horizontal position multiplier (book mode): "
+ + mLetterboxConfiguration.getLetterboxHorizontalPositionMultiplier(
+ true /* isInBookMode */));
+ pw.println("Vertical position multiplier (tabletop mode): "
+ + mLetterboxConfiguration.getLetterboxVerticalPositionMultiplier(
+ true /* isInTabletopMode */));
pw.println("Aspect ratio: "
+ mLetterboxConfiguration.getFixedOrientationLetterboxAspectRatio());
pw.println("Default min aspect ratio for unresizable apps: "
@@ -1238,10 +1246,10 @@
mLetterboxConfiguration.getDefaultPositionForVerticalReachability()));
pw.println("Current position for horizontal reachability:"
+ LetterboxConfiguration.letterboxHorizontalReachabilityPositionToString(
- mLetterboxConfiguration.getLetterboxPositionForHorizontalReachability()));
+ mLetterboxConfiguration.getLetterboxPositionForHorizontalReachability(false)));
pw.println("Current position for vertical reachability:"
+ LetterboxConfiguration.letterboxVerticalReachabilityPositionToString(
- mLetterboxConfiguration.getLetterboxPositionForVerticalReachability()));
+ mLetterboxConfiguration.getLetterboxPositionForVerticalReachability(false)));
pw.println("Is education enabled: "
+ mLetterboxConfiguration.getIsEducationEnabled());
pw.println("Is using split screen aspect ratio as aspect ratio for unresizable apps: "
diff --git a/services/tests/wmtests/src/com/android/server/wm/LetterboxConfigurationPersisterTest.java b/services/tests/wmtests/src/com/android/server/wm/LetterboxConfigurationPersisterTest.java
index 1be9de7..51a7e74 100644
--- a/services/tests/wmtests/src/com/android/server/wm/LetterboxConfigurationPersisterTest.java
+++ b/services/tests/wmtests/src/com/android/server/wm/LetterboxConfigurationPersisterTest.java
@@ -67,6 +67,11 @@
R.integer.config_letterboxDefaultPositionForHorizontalReachability),
() -> mContext.getResources().getInteger(
R.integer.config_letterboxDefaultPositionForVerticalReachability),
+ () -> mContext.getResources().getInteger(
+ R.integer.config_letterboxDefaultPositionForBookModeReachability),
+ () -> mContext.getResources().getInteger(
+ R.integer.config_letterboxDefaultPositionForTabletopModeReachability
+ ),
mConfigFolder, mPersisterQueue, mQueueState);
mQueueListener = queueEmpty -> mQueueState.onItemAdded();
mPersisterQueue.addListener(mQueueListener);
@@ -84,14 +89,15 @@
@Test
public void test_whenStoreIsCreated_valuesAreDefaults() {
final int positionForHorizontalReachability =
- mLetterboxConfigurationPersister.getLetterboxPositionForHorizontalReachability();
+ mLetterboxConfigurationPersister.getLetterboxPositionForHorizontalReachability(
+ false);
final int defaultPositionForHorizontalReachability =
mContext.getResources().getInteger(
R.integer.config_letterboxDefaultPositionForHorizontalReachability);
Assert.assertEquals(defaultPositionForHorizontalReachability,
positionForHorizontalReachability);
final int positionForVerticalReachability =
- mLetterboxConfigurationPersister.getLetterboxPositionForVerticalReachability();
+ mLetterboxConfigurationPersister.getLetterboxPositionForVerticalReachability(false);
final int defaultPositionForVerticalReachability =
mContext.getResources().getInteger(
R.integer.config_letterboxDefaultPositionForVerticalReachability);
@@ -101,15 +107,16 @@
@Test
public void test_whenUpdatedWithNewValues_valuesAreWritten() {
- mLetterboxConfigurationPersister.setLetterboxPositionForHorizontalReachability(
+ mLetterboxConfigurationPersister.setLetterboxPositionForHorizontalReachability(false,
LETTERBOX_HORIZONTAL_REACHABILITY_POSITION_LEFT);
- mLetterboxConfigurationPersister.setLetterboxPositionForVerticalReachability(
+ mLetterboxConfigurationPersister.setLetterboxPositionForVerticalReachability(false,
LETTERBOX_VERTICAL_REACHABILITY_POSITION_TOP);
waitForCompletion(mPersisterQueue);
final int newPositionForHorizontalReachability =
- mLetterboxConfigurationPersister.getLetterboxPositionForHorizontalReachability();
+ mLetterboxConfigurationPersister.getLetterboxPositionForHorizontalReachability(
+ false);
final int newPositionForVerticalReachability =
- mLetterboxConfigurationPersister.getLetterboxPositionForVerticalReachability();
+ mLetterboxConfigurationPersister.getLetterboxPositionForVerticalReachability(false);
Assert.assertEquals(LETTERBOX_HORIZONTAL_REACHABILITY_POSITION_LEFT,
newPositionForHorizontalReachability);
Assert.assertEquals(LETTERBOX_VERTICAL_REACHABILITY_POSITION_TOP,
@@ -120,24 +127,24 @@
public void test_whenUpdatedWithNewValues_valuesAreReadAfterRestart() {
final PersisterQueue firstPersisterQueue = new PersisterQueue();
final LetterboxConfigurationPersister firstPersister = new LetterboxConfigurationPersister(
- mContext, () -> -1, () -> -1, mContext.getFilesDir(), firstPersisterQueue,
- mQueueState);
+ mContext, () -> -1, () -> -1, () -> -1, () -> -1, mContext.getFilesDir(),
+ firstPersisterQueue, mQueueState);
firstPersister.start();
- firstPersister.setLetterboxPositionForHorizontalReachability(
+ firstPersister.setLetterboxPositionForHorizontalReachability(false,
LETTERBOX_HORIZONTAL_REACHABILITY_POSITION_LEFT);
- firstPersister.setLetterboxPositionForVerticalReachability(
+ firstPersister.setLetterboxPositionForVerticalReachability(false,
LETTERBOX_VERTICAL_REACHABILITY_POSITION_TOP);
waitForCompletion(firstPersisterQueue);
stopPersisterSafe(firstPersisterQueue);
final PersisterQueue secondPersisterQueue = new PersisterQueue();
final LetterboxConfigurationPersister secondPersister = new LetterboxConfigurationPersister(
- mContext, () -> -1, () -> -1, mContext.getFilesDir(), secondPersisterQueue,
- mQueueState);
+ mContext, () -> -1, () -> -1, () -> -1, () -> -1, mContext.getFilesDir(),
+ secondPersisterQueue, mQueueState);
secondPersister.start();
final int newPositionForHorizontalReachability =
- secondPersister.getLetterboxPositionForHorizontalReachability();
+ secondPersister.getLetterboxPositionForHorizontalReachability(false);
final int newPositionForVerticalReachability =
- secondPersister.getLetterboxPositionForVerticalReachability();
+ secondPersister.getLetterboxPositionForVerticalReachability(false);
Assert.assertEquals(LETTERBOX_HORIZONTAL_REACHABILITY_POSITION_LEFT,
newPositionForHorizontalReachability);
Assert.assertEquals(LETTERBOX_VERTICAL_REACHABILITY_POSITION_TOP,
@@ -149,15 +156,16 @@
@Test
public void test_whenUpdatedWithNewValuesAndDeleted_valuesAreDefaults() {
- mLetterboxConfigurationPersister.setLetterboxPositionForHorizontalReachability(
+ mLetterboxConfigurationPersister.setLetterboxPositionForHorizontalReachability(false,
LETTERBOX_HORIZONTAL_REACHABILITY_POSITION_LEFT);
- mLetterboxConfigurationPersister.setLetterboxPositionForVerticalReachability(
+ mLetterboxConfigurationPersister.setLetterboxPositionForVerticalReachability(false,
LETTERBOX_VERTICAL_REACHABILITY_POSITION_TOP);
waitForCompletion(mPersisterQueue);
final int newPositionForHorizontalReachability =
- mLetterboxConfigurationPersister.getLetterboxPositionForHorizontalReachability();
+ mLetterboxConfigurationPersister.getLetterboxPositionForHorizontalReachability(
+ false);
final int newPositionForVerticalReachability =
- mLetterboxConfigurationPersister.getLetterboxPositionForVerticalReachability();
+ mLetterboxConfigurationPersister.getLetterboxPositionForVerticalReachability(false);
Assert.assertEquals(LETTERBOX_HORIZONTAL_REACHABILITY_POSITION_LEFT,
newPositionForHorizontalReachability);
Assert.assertEquals(LETTERBOX_VERTICAL_REACHABILITY_POSITION_TOP,
@@ -165,14 +173,15 @@
deleteConfiguration(mLetterboxConfigurationPersister, mPersisterQueue);
waitForCompletion(mPersisterQueue);
final int positionForHorizontalReachability =
- mLetterboxConfigurationPersister.getLetterboxPositionForHorizontalReachability();
+ mLetterboxConfigurationPersister.getLetterboxPositionForHorizontalReachability(
+ false);
final int defaultPositionForHorizontalReachability =
mContext.getResources().getInteger(
R.integer.config_letterboxDefaultPositionForHorizontalReachability);
Assert.assertEquals(defaultPositionForHorizontalReachability,
positionForHorizontalReachability);
final int positionForVerticalReachability =
- mLetterboxConfigurationPersister.getLetterboxPositionForVerticalReachability();
+ mLetterboxConfigurationPersister.getLetterboxPositionForVerticalReachability(false);
final int defaultPositionForVerticalReachability =
mContext.getResources().getInteger(
R.integer.config_letterboxDefaultPositionForVerticalReachability);
diff --git a/services/tests/wmtests/src/com/android/server/wm/LetterboxConfigurationTest.java b/services/tests/wmtests/src/com/android/server/wm/LetterboxConfigurationTest.java
index c927f9e..e196704 100644
--- a/services/tests/wmtests/src/com/android/server/wm/LetterboxConfigurationTest.java
+++ b/services/tests/wmtests/src/com/android/server/wm/LetterboxConfigurationTest.java
@@ -26,6 +26,7 @@
import static com.android.server.wm.LetterboxConfiguration.LETTERBOX_VERTICAL_REACHABILITY_POSITION_TOP;
import static org.mockito.ArgumentMatchers.anyInt;
+import static org.mockito.ArgumentMatchers.eq;
import static org.mockito.Mockito.mock;
import static org.mockito.Mockito.times;
import static org.mockito.Mockito.verify;
@@ -39,7 +40,8 @@
import org.junit.Before;
import org.junit.Test;
-import java.util.function.Consumer;
+import java.util.Arrays;
+import java.util.function.BiConsumer;
@SmallTest
@Presubmit
@@ -58,20 +60,28 @@
@Test
public void test_whenReadingValues_storeIsInvoked() {
- mLetterboxConfiguration.getLetterboxPositionForHorizontalReachability();
- verify(mLetterboxConfigurationPersister).getLetterboxPositionForHorizontalReachability();
- mLetterboxConfiguration.getLetterboxPositionForVerticalReachability();
- verify(mLetterboxConfigurationPersister).getLetterboxPositionForVerticalReachability();
+ for (boolean halfFoldPose : Arrays.asList(false, true)) {
+ mLetterboxConfiguration.getLetterboxPositionForHorizontalReachability(halfFoldPose);
+ verify(mLetterboxConfigurationPersister).getLetterboxPositionForHorizontalReachability(
+ halfFoldPose);
+ mLetterboxConfiguration.getLetterboxPositionForVerticalReachability(halfFoldPose);
+ verify(mLetterboxConfigurationPersister).getLetterboxPositionForVerticalReachability(
+ halfFoldPose);
+ }
}
@Test
public void test_whenSettingValues_updateConfigurationIsInvoked() {
- mLetterboxConfiguration.movePositionForHorizontalReachabilityToNextRightStop();
- verify(mLetterboxConfigurationPersister).setLetterboxPositionForHorizontalReachability(
- anyInt());
- mLetterboxConfiguration.movePositionForVerticalReachabilityToNextBottomStop();
- verify(mLetterboxConfigurationPersister).setLetterboxPositionForVerticalReachability(
- anyInt());
+ for (boolean halfFoldPose : Arrays.asList(false, true)) {
+ mLetterboxConfiguration.movePositionForHorizontalReachabilityToNextRightStop(
+ halfFoldPose);
+ verify(mLetterboxConfigurationPersister).setLetterboxPositionForHorizontalReachability(
+ eq(halfFoldPose), anyInt());
+ mLetterboxConfiguration.movePositionForVerticalReachabilityToNextBottomStop(
+ halfFoldPose);
+ verify(mLetterboxConfigurationPersister).setLetterboxPositionForVerticalReachability(
+ eq(halfFoldPose), anyInt());
+ }
}
@Test
@@ -81,33 +91,65 @@
/* from */ LETTERBOX_HORIZONTAL_REACHABILITY_POSITION_CENTER,
/* expected */ LETTERBOX_HORIZONTAL_REACHABILITY_POSITION_LEFT,
/* expectedTime */ 1,
+ /* halfFoldPose */ false,
LetterboxConfiguration::movePositionForHorizontalReachabilityToNextLeftStop);
assertForHorizontalMove(
/* from */ LETTERBOX_HORIZONTAL_REACHABILITY_POSITION_CENTER,
/* expected */ LETTERBOX_HORIZONTAL_REACHABILITY_POSITION_RIGHT,
/* expectedTime */ 1,
+ /* halfFoldPose */ false,
LetterboxConfiguration::movePositionForHorizontalReachabilityToNextRightStop);
// Starting from left
assertForHorizontalMove(
/* from */ LETTERBOX_HORIZONTAL_REACHABILITY_POSITION_LEFT,
/* expected */ LETTERBOX_HORIZONTAL_REACHABILITY_POSITION_LEFT,
/* expectedTime */ 2,
+ /* halfFoldPose */ false,
LetterboxConfiguration::movePositionForHorizontalReachabilityToNextLeftStop);
assertForHorizontalMove(
/* from */ LETTERBOX_HORIZONTAL_REACHABILITY_POSITION_LEFT,
/* expected */ LETTERBOX_HORIZONTAL_REACHABILITY_POSITION_CENTER,
/* expectedTime */ 1,
+ /* halfFoldPose */ false,
LetterboxConfiguration::movePositionForHorizontalReachabilityToNextRightStop);
// Starting from right
assertForHorizontalMove(
/* from */ LETTERBOX_HORIZONTAL_REACHABILITY_POSITION_RIGHT,
/* expected */ LETTERBOX_HORIZONTAL_REACHABILITY_POSITION_RIGHT,
/* expectedTime */ 2,
+ /* halfFoldPose */ false,
LetterboxConfiguration::movePositionForHorizontalReachabilityToNextRightStop);
assertForHorizontalMove(
/* from */ LETTERBOX_HORIZONTAL_REACHABILITY_POSITION_RIGHT,
/* expected */ LETTERBOX_HORIZONTAL_REACHABILITY_POSITION_CENTER,
/* expectedTime */ 2,
+ /* halfFoldPose */ false,
+ LetterboxConfiguration::movePositionForHorizontalReachabilityToNextLeftStop);
+ // Starting from left - book mode
+ assertForHorizontalMove(
+ /* from */ LETTERBOX_HORIZONTAL_REACHABILITY_POSITION_LEFT,
+ /* expected */ LETTERBOX_HORIZONTAL_REACHABILITY_POSITION_LEFT,
+ /* expectedTime */ 1,
+ /* halfFoldPose */ true,
+ LetterboxConfiguration::movePositionForHorizontalReachabilityToNextLeftStop);
+ assertForHorizontalMove(
+ /* from */ LETTERBOX_HORIZONTAL_REACHABILITY_POSITION_LEFT,
+ /* expected */ LETTERBOX_HORIZONTAL_REACHABILITY_POSITION_RIGHT,
+ /* expectedTime */ 1,
+ /* halfFoldPose */ true,
+ LetterboxConfiguration::movePositionForHorizontalReachabilityToNextRightStop);
+ // Starting from right - book mode
+ assertForHorizontalMove(
+ /* from */ LETTERBOX_HORIZONTAL_REACHABILITY_POSITION_RIGHT,
+ /* expected */ LETTERBOX_HORIZONTAL_REACHABILITY_POSITION_RIGHT,
+ /* expectedTime */ 2,
+ /* halfFoldPose */ true,
+ LetterboxConfiguration::movePositionForHorizontalReachabilityToNextRightStop);
+ assertForHorizontalMove(
+ /* from */ LETTERBOX_HORIZONTAL_REACHABILITY_POSITION_RIGHT,
+ /* expected */ LETTERBOX_HORIZONTAL_REACHABILITY_POSITION_LEFT,
+ /* expectedTime */ 2,
+ /* halfFoldPose */ true,
LetterboxConfiguration::movePositionForHorizontalReachabilityToNextLeftStop);
}
@@ -118,55 +160,87 @@
/* from */ LETTERBOX_VERTICAL_REACHABILITY_POSITION_CENTER,
/* expected */ LETTERBOX_VERTICAL_REACHABILITY_POSITION_BOTTOM,
/* expectedTime */ 1,
+ /* halfFoldPose */ false,
LetterboxConfiguration::movePositionForVerticalReachabilityToNextBottomStop);
assertForVerticalMove(
/* from */ LETTERBOX_VERTICAL_REACHABILITY_POSITION_CENTER,
/* expected */ LETTERBOX_VERTICAL_REACHABILITY_POSITION_TOP,
/* expectedTime */ 1,
+ /* halfFoldPose */ false,
LetterboxConfiguration::movePositionForVerticalReachabilityToNextTopStop);
// Starting from top
assertForVerticalMove(
/* from */ LETTERBOX_VERTICAL_REACHABILITY_POSITION_TOP,
/* expected */ LETTERBOX_VERTICAL_REACHABILITY_POSITION_CENTER,
/* expectedTime */ 1,
+ /* halfFoldPose */ false,
LetterboxConfiguration::movePositionForVerticalReachabilityToNextBottomStop);
assertForVerticalMove(
/* from */ LETTERBOX_VERTICAL_REACHABILITY_POSITION_TOP,
/* expected */ LETTERBOX_VERTICAL_REACHABILITY_POSITION_TOP,
/* expectedTime */ 2,
+ /* halfFoldPose */ false,
LetterboxConfiguration::movePositionForVerticalReachabilityToNextTopStop);
// Starting from bottom
assertForVerticalMove(
/* from */ LETTERBOX_VERTICAL_REACHABILITY_POSITION_BOTTOM,
/* expected */ LETTERBOX_VERTICAL_REACHABILITY_POSITION_CENTER,
/* expectedTime */ 2,
+ /* halfFoldPose */ false,
LetterboxConfiguration::movePositionForVerticalReachabilityToNextTopStop);
assertForVerticalMove(
/* from */ LETTERBOX_VERTICAL_REACHABILITY_POSITION_BOTTOM,
/* expected */ LETTERBOX_VERTICAL_REACHABILITY_POSITION_BOTTOM,
/* expectedTime */ 2,
+ /* halfFoldPose */ false,
+ LetterboxConfiguration::movePositionForVerticalReachabilityToNextBottomStop);
+ // Starting from top - tabletop mode
+ assertForVerticalMove(
+ /* from */ LETTERBOX_VERTICAL_REACHABILITY_POSITION_TOP,
+ /* expected */ LETTERBOX_VERTICAL_REACHABILITY_POSITION_BOTTOM,
+ /* expectedTime */ 1,
+ /* halfFoldPose */ true,
+ LetterboxConfiguration::movePositionForVerticalReachabilityToNextBottomStop);
+ assertForVerticalMove(
+ /* from */ LETTERBOX_VERTICAL_REACHABILITY_POSITION_TOP,
+ /* expected */ LETTERBOX_VERTICAL_REACHABILITY_POSITION_TOP,
+ /* expectedTime */ 1,
+ /* halfFoldPose */ true,
+ LetterboxConfiguration::movePositionForVerticalReachabilityToNextTopStop);
+ // Starting from bottom - tabletop mode
+ assertForVerticalMove(
+ /* from */ LETTERBOX_VERTICAL_REACHABILITY_POSITION_BOTTOM,
+ /* expected */ LETTERBOX_VERTICAL_REACHABILITY_POSITION_TOP,
+ /* expectedTime */ 2,
+ /* halfFoldPose */ true,
+ LetterboxConfiguration::movePositionForVerticalReachabilityToNextTopStop);
+ assertForVerticalMove(
+ /* from */ LETTERBOX_VERTICAL_REACHABILITY_POSITION_BOTTOM,
+ /* expected */ LETTERBOX_VERTICAL_REACHABILITY_POSITION_BOTTOM,
+ /* expectedTime */ 2,
+ /* halfFoldPose */ true,
LetterboxConfiguration::movePositionForVerticalReachabilityToNextBottomStop);
}
private void assertForHorizontalMove(int from, int expected, int expectedTime,
- Consumer<LetterboxConfiguration> move) {
+ boolean halfFoldPose, BiConsumer<LetterboxConfiguration, Boolean> move) {
// We are in the current position
- when(mLetterboxConfiguration.getLetterboxPositionForHorizontalReachability())
+ when(mLetterboxConfiguration.getLetterboxPositionForHorizontalReachability(halfFoldPose))
.thenReturn(from);
- move.accept(mLetterboxConfiguration);
+ move.accept(mLetterboxConfiguration, halfFoldPose);
verify(mLetterboxConfigurationPersister,
- times(expectedTime)).setLetterboxPositionForHorizontalReachability(
+ times(expectedTime)).setLetterboxPositionForHorizontalReachability(halfFoldPose,
expected);
}
private void assertForVerticalMove(int from, int expected, int expectedTime,
- Consumer<LetterboxConfiguration> move) {
+ boolean halfFoldPose, BiConsumer<LetterboxConfiguration, Boolean> move) {
// We are in the current position
- when(mLetterboxConfiguration.getLetterboxPositionForVerticalReachability())
+ when(mLetterboxConfiguration.getLetterboxPositionForVerticalReachability(halfFoldPose))
.thenReturn(from);
- move.accept(mLetterboxConfiguration);
+ move.accept(mLetterboxConfiguration, halfFoldPose);
verify(mLetterboxConfigurationPersister,
- times(expectedTime)).setLetterboxPositionForVerticalReachability(
+ times(expectedTime)).setLetterboxPositionForVerticalReachability(halfFoldPose,
expected);
}
}
diff --git a/services/tests/wmtests/src/com/android/server/wm/SizeCompatTests.java b/services/tests/wmtests/src/com/android/server/wm/SizeCompatTests.java
index 94c33f2..7488e1c 100644
--- a/services/tests/wmtests/src/com/android/server/wm/SizeCompatTests.java
+++ b/services/tests/wmtests/src/com/android/server/wm/SizeCompatTests.java
@@ -16,6 +16,7 @@
package com.android.server.wm;
+import static android.app.WindowConfiguration.WINDOWING_MODE_FULLSCREEN;
import static android.app.WindowConfiguration.WINDOWING_MODE_MULTI_WINDOW;
import static android.content.pm.ActivityInfo.RESIZE_MODE_RESIZEABLE;
import static android.content.pm.ActivityInfo.RESIZE_MODE_UNRESIZEABLE;
@@ -95,6 +96,7 @@
import com.android.internal.policy.SystemBarUtils;
import com.android.internal.statusbar.LetterboxDetails;
import com.android.server.statusbar.StatusBarManagerInternal;
+import com.android.server.wm.DeviceStateController.FoldState;
import libcore.junit.util.compat.CoreCompatChangeRule.DisableCompatChanges;
import libcore.junit.util.compat.CoreCompatChangeRule.EnableCompatChanges;
@@ -2821,6 +2823,70 @@
}
@Test
+ public void testUpdateResolvedBoundsVerticalPosition_tabletop() {
+
+ // Set up a display in portrait with a fixed-orientation LANDSCAPE app
+ setUpDisplaySizeWithApp(1400, 2800);
+ mActivity.mDisplayContent.setIgnoreOrientationRequest(true /* ignoreOrientationRequest */);
+ mActivity.mWmService.mLetterboxConfiguration.setLetterboxVerticalPositionMultiplier(
+ 1.0f /*letterboxVerticalPositionMultiplier*/);
+ prepareUnresizable(mActivity, SCREEN_ORIENTATION_LANDSCAPE);
+
+ Rect letterboxNoFold = new Rect(0, 2100, 1400, 2800);
+ assertEquals(letterboxNoFold, mActivity.getBounds());
+
+ // Make the activity full-screen
+ mTask.setWindowingMode(WINDOWING_MODE_FULLSCREEN);
+
+ setFoldablePosture(true /* isHalfFolded */, true /* isTabletop */);
+
+ Rect letterboxHalfFold = new Rect(0, 0, 1400, 700);
+ assertEquals(letterboxHalfFold, mActivity.getBounds());
+
+ setFoldablePosture(false /* isHalfFolded */, false /* isTabletop */);
+
+ assertEquals(letterboxNoFold, mActivity.getBounds());
+
+ }
+
+ @Test
+ public void testUpdateResolvedBoundsHorizontalPosition_book() {
+
+ // Set up a display in landscape with a fixed-orientation PORTRAIT app
+ setUpDisplaySizeWithApp(2800, 1400);
+ mActivity.mDisplayContent.setIgnoreOrientationRequest(true /* ignoreOrientationRequest */);
+ mActivity.mWmService.mLetterboxConfiguration.setLetterboxHorizontalPositionMultiplier(
+ 1.0f /*letterboxVerticalPositionMultiplier*/);
+ prepareUnresizable(mActivity, SCREEN_ORIENTATION_PORTRAIT);
+
+ Rect letterboxNoFold = new Rect(2100, 0, 2800, 1400);
+ assertEquals(letterboxNoFold, mActivity.getBounds());
+
+ // Make the activity full-screen
+ mTask.setWindowingMode(WINDOWING_MODE_FULLSCREEN);
+
+ setFoldablePosture(true /* isHalfFolded */, false /* isTabletop */);
+
+ Rect letterboxHalfFold = new Rect(0, 0, 700, 1400);
+ assertEquals(letterboxHalfFold, mActivity.getBounds());
+
+ setFoldablePosture(false /* isHalfFolded */, false /* isTabletop */);
+
+ assertEquals(letterboxNoFold, mActivity.getBounds());
+
+ }
+
+ private void setFoldablePosture(boolean isHalfFolded, boolean isTabletop) {
+ final DisplayRotation r = mActivity.mDisplayContent.getDisplayRotation();
+ doReturn(isHalfFolded).when(r).isDisplaySeparatingHinge();
+ doReturn(false).when(r).isDeviceInPosture(any(FoldState.class), anyBoolean());
+ if (isHalfFolded) {
+ doReturn(true).when(r).isDeviceInPosture(FoldState.HALF_FOLDED, isTabletop);
+ }
+ mActivity.recomputeConfiguration();
+ }
+
+ @Test
public void testUpdateResolvedBoundsPosition_alignToTop() {
final int notchHeight = 100;
final DisplayContent display = new TestDisplayContent.Builder(mAtm, 1000, 2800)