Letterboxing improvements for tabletop mode
Move letterboxed apps to the top screen and resize when in tabletop pose and move to the left for book mode. Also allow double-tapping to move the app to the alternative half of the screen. Bug: 245740388 Test: locally tested Change-Id: I14434ad23091de3957f04284e03da8701f159fa4
This commit is contained in:
@@ -5204,6 +5204,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
|
||||
@@ -5252,14 +5261,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>
|
||||
@@ -5287,6 +5308,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>
|
||||
|
||||
|
||||
@@ -4434,6 +4434,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" />
|
||||
@@ -4446,10 +4448,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" />
|
||||
|
||||
@@ -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",
|
||||
|
||||
@@ -68,4 +68,8 @@ message LetterboxProto {
|
||||
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;
|
||||
}
|
||||
@@ -8149,7 +8149,7 @@ final class ActivityRecord extends WindowToken implements WindowManagerService.A
|
||||
}
|
||||
|
||||
/**
|
||||
* 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 @@ final class ActivityRecord extends WindowToken implements WindowManagerService.A
|
||||
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 @@ final class ActivityRecord extends WindowToken implements WindowManagerService.A
|
||||
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);
|
||||
}
|
||||
|
||||
@@ -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.Handler;
|
||||
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;
|
||||
@@ -75,6 +77,7 @@ import java.io.PrintWriter;
|
||||
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.
|
||||
@@ -1521,6 +1524,15 @@ public class DisplayRotation {
|
||||
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.
|
||||
*/
|
||||
@@ -1538,6 +1550,63 @@ public class DisplayRotation {
|
||||
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;
|
||||
@@ -1586,6 +1655,15 @@ public class DisplayRotation {
|
||||
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();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -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 @@ import java.util.function.Function;
|
||||
/** 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 @@ final class LetterboxConfiguration {
|
||||
// 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 @@ final class LetterboxConfiguration {
|
||||
|
||||
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 @@ final class LetterboxConfiguration {
|
||||
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 @@ final class LetterboxConfiguration {
|
||||
* 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 @@ final class LetterboxConfiguration {
|
||||
* 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 @@ final class LetterboxConfiguration {
|
||||
*/
|
||||
void resetDefaultPositionForHorizontalReachability() {
|
||||
mDefaultPositionForHorizontalReachability =
|
||||
readLetterboxHorizontalReachabilityPositionFromConfig(mContext);
|
||||
readLetterboxHorizontalReachabilityPositionFromConfig(mContext,
|
||||
false /* forBookMode */);
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -627,27 +679,34 @@ final class LetterboxConfiguration {
|
||||
*/
|
||||
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 @@ final class LetterboxConfiguration {
|
||||
*
|
||||
* <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 @@ final class LetterboxConfiguration {
|
||||
*
|
||||
* <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 @@ final class LetterboxConfiguration {
|
||||
* enabled.
|
||||
*/
|
||||
@LetterboxHorizontalReachabilityPosition
|
||||
int getLetterboxPositionForHorizontalReachability() {
|
||||
return mLetterboxConfigurationPersister.getLetterboxPositionForHorizontalReachability();
|
||||
int getLetterboxPositionForHorizontalReachability(boolean isInFullScreenBookMode) {
|
||||
return mLetterboxConfigurationPersister.getLetterboxPositionForHorizontalReachability(
|
||||
isInFullScreenBookMode);
|
||||
}
|
||||
|
||||
/*
|
||||
@@ -710,8 +772,9 @@ final class LetterboxConfiguration {
|
||||
* 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 @@ final class LetterboxConfiguration {
|
||||
* 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 @@ final class LetterboxConfiguration {
|
||||
}
|
||||
|
||||
/** 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
|
||||
|
||||
@@ -55,6 +55,8 @@ class LetterboxConfigurationPersister {
|
||||
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 @@ class LetterboxConfigurationPersister {
|
||||
@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 @@ class LetterboxConfigurationPersister {
|
||||
@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 @@ class LetterboxConfigurationPersister {
|
||||
|
||||
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 @@ class LetterboxConfigurationPersister {
|
||||
@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 @@ class LetterboxConfigurationPersister {
|
||||
* enabled.
|
||||
*/
|
||||
@LetterboxHorizontalReachabilityPosition
|
||||
int getLetterboxPositionForHorizontalReachability() {
|
||||
return mLetterboxPositionForHorizontalReachability;
|
||||
int getLetterboxPositionForHorizontalReachability(boolean forBookMode) {
|
||||
if (forBookMode) {
|
||||
return mLetterboxPositionForBookModeReachability;
|
||||
} else {
|
||||
return mLetterboxPositionForHorizontalReachability;
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
@@ -126,31 +153,55 @@ class LetterboxConfigurationPersister {
|
||||
* 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 @@ class LetterboxConfigurationPersister {
|
||||
void useDefaultValue() {
|
||||
mLetterboxPositionForHorizontalReachability = mDefaultHorizontalReachabilitySupplier.get();
|
||||
mLetterboxPositionForVerticalReachability = mDefaultVerticalReachabilitySupplier.get();
|
||||
mLetterboxPositionForBookModeReachability =
|
||||
mDefaultBookModeReachabilitySupplier.get();
|
||||
mLetterboxPositionForTabletopModeReachability =
|
||||
mDefaultTabletopModeReachabilitySupplier.get();
|
||||
}
|
||||
|
||||
private void readCurrentConfiguration() {
|
||||
@@ -171,6 +226,10 @@ class LetterboxConfigurationPersister {
|
||||
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 @@ class LetterboxConfigurationPersister {
|
||||
mPersisterQueue.addItem(new UpdateValuesCommand(mConfigurationFile,
|
||||
mLetterboxPositionForHorizontalReachability,
|
||||
mLetterboxPositionForVerticalReachability,
|
||||
mLetterboxPositionForBookModeReachability,
|
||||
mLetterboxPositionForTabletopModeReachability,
|
||||
mCompletionCallback), /* flush */ true);
|
||||
}
|
||||
|
||||
@@ -221,13 +282,18 @@ class LetterboxConfigurationPersister {
|
||||
|
||||
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 @@ class LetterboxConfigurationPersister {
|
||||
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;
|
||||
|
||||
@@ -275,30 +275,62 @@ final class LetterboxUiController {
|
||||
&& 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 @@ final class LetterboxUiController {
|
||||
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 @@ final class LetterboxUiController {
|
||||
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 @@ final class LetterboxUiController {
|
||||
// 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 @@ final class LetterboxUiController {
|
||||
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 @@ final class LetterboxUiController {
|
||||
+ 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 @@ final class LetterboxUiController {
|
||||
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;
|
||||
}
|
||||
|
||||
@@ -1219,9 +1219,17 @@ public class WindowManagerShellCommand extends ShellCommand {
|
||||
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 @@ public class WindowManagerShellCommand extends ShellCommand {
|
||||
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: "
|
||||
|
||||
@@ -67,6 +67,11 @@ public class LetterboxConfigurationPersisterTest {
|
||||
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 @@ public class LetterboxConfigurationPersisterTest {
|
||||
@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 @@ public class LetterboxConfigurationPersisterTest {
|
||||
|
||||
@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 class LetterboxConfigurationPersisterTest {
|
||||
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 @@ public class LetterboxConfigurationPersisterTest {
|
||||
|
||||
@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 @@ public class LetterboxConfigurationPersisterTest {
|
||||
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);
|
||||
|
||||
@@ -26,6 +26,7 @@ import static com.android.server.wm.LetterboxConfiguration.LETTERBOX_VERTICAL_RE
|
||||
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 androidx.test.filters.SmallTest;
|
||||
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 @@ public class LetterboxConfigurationTest {
|
||||
|
||||
@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 @@ public class LetterboxConfigurationTest {
|
||||
/* 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 @@ public class LetterboxConfigurationTest {
|
||||
/* 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);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -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 androidx.test.filters.MediumTest;
|
||||
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;
|
||||
@@ -2820,6 +2822,70 @@ public class SizeCompatTests extends WindowTestsBase {
|
||||
/* sizeCompatScaled */ new Rect(0, 1050, 700, 1400));
|
||||
}
|
||||
|
||||
@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;
|
||||
|
||||
Reference in New Issue
Block a user