darkScrimAlphaSupplier,
- IntConsumer doubleTapCallback) {
+ IntConsumer doubleTapCallbackX,
+ IntConsumer doubleTapCallbackY) {
mSurfaceControlFactory = surfaceControlFactory;
mTransactionFactory = transactionFactory;
mAreCornersRounded = areCornersRounded;
@@ -94,7 +96,8 @@ public class Letterbox {
mHasWallpaperBackgroundSupplier = hasWallpaperBackgroundSupplier;
mBlurRadiusSupplier = blurRadiusSupplier;
mDarkScrimAlphaSupplier = darkScrimAlphaSupplier;
- mDoubleTapCallback = doubleTapCallback;
+ mDoubleTapCallbackX = doubleTapCallbackX;
+ mDoubleTapCallbackY = doubleTapCallbackY;
}
/**
@@ -264,7 +267,8 @@ public class Letterbox {
@Override
public boolean onDoubleTapEvent(MotionEvent e) {
if (e.getAction() == MotionEvent.ACTION_UP) {
- mDoubleTapCallback.accept((int) e.getX());
+ mDoubleTapCallbackX.accept((int) e.getX());
+ mDoubleTapCallbackY.accept((int) e.getY());
return true;
}
return false;
diff --git a/services/core/java/com/android/server/wm/LetterboxConfiguration.java b/services/core/java/com/android/server/wm/LetterboxConfiguration.java
index ad2767c41e82e..bef8da8ff9173 100644
--- a/services/core/java/com/android/server/wm/LetterboxConfiguration.java
+++ b/services/core/java/com/android/server/wm/LetterboxConfiguration.java
@@ -55,25 +55,48 @@ final class LetterboxConfiguration {
static final int LETTERBOX_BACKGROUND_WALLPAPER = 3;
/**
- * Enum for Letterbox reachability position types.
+ * Enum for Letterbox horizontal reachability position types.
*
* Order from left to right is important since it's used in {@link
* #movePositionForReachabilityToNextRightStop} and {@link
* #movePositionForReachabilityToNextLeftStop}.
*/
@Retention(RetentionPolicy.SOURCE)
- @IntDef({LETTERBOX_REACHABILITY_POSITION_LEFT, LETTERBOX_REACHABILITY_POSITION_CENTER,
- LETTERBOX_REACHABILITY_POSITION_RIGHT})
- @interface LetterboxReachabilityPosition {};
+ @IntDef({LETTERBOX_HORIZONTAL_REACHABILITY_POSITION_LEFT,
+ LETTERBOX_HORIZONTAL_REACHABILITY_POSITION_CENTER,
+ LETTERBOX_HORIZONTAL_REACHABILITY_POSITION_RIGHT})
+ @interface LetterboxHorizontalReachabilityPosition {};
/** Letterboxed app window is aligned to the left side. */
- static final int LETTERBOX_REACHABILITY_POSITION_LEFT = 0;
+ static final int LETTERBOX_HORIZONTAL_REACHABILITY_POSITION_LEFT = 0;
/** Letterboxed app window is positioned in the horizontal center. */
- static final int LETTERBOX_REACHABILITY_POSITION_CENTER = 1;
+ static final int LETTERBOX_HORIZONTAL_REACHABILITY_POSITION_CENTER = 1;
/** Letterboxed app window is aligned to the right side. */
- static final int LETTERBOX_REACHABILITY_POSITION_RIGHT = 2;
+ static final int LETTERBOX_HORIZONTAL_REACHABILITY_POSITION_RIGHT = 2;
+
+ /**
+ * Enum for Letterbox vertical reachability position types.
+ *
+ *
Order from top to bottom is important since it's used in {@link
+ * #movePositionForReachabilityToNextBottomStop} and {@link
+ * #movePositionForReachabilityToNextTopStop}.
+ */
+ @Retention(RetentionPolicy.SOURCE)
+ @IntDef({LETTERBOX_VERTICAL_REACHABILITY_POSITION_TOP,
+ LETTERBOX_VERTICAL_REACHABILITY_POSITION_CENTER,
+ LETTERBOX_VERTICAL_REACHABILITY_POSITION_BOTTOM})
+ @interface LetterboxVerticalReachabilityPosition {};
+
+ /** Letterboxed app window is aligned to the left side. */
+ static final int LETTERBOX_VERTICAL_REACHABILITY_POSITION_TOP = 0;
+
+ /** Letterboxed app window is positioned in the vertical center. */
+ static final int LETTERBOX_VERTICAL_REACHABILITY_POSITION_CENTER = 1;
+
+ /** Letterboxed app window is aligned to the right side. */
+ static final int LETTERBOX_VERTICAL_REACHABILITY_POSITION_BOTTOM = 2;
final Context mContext;
@@ -106,25 +129,50 @@ final class LetterboxConfiguration {
// side of the screen and 1.0 to the right side.
private float mLetterboxHorizontalPositionMultiplier;
- // Default horizontal position the letterboxed app window when reachability is enabled and
- // an app is fullscreen in landscape device orientatio.
- // It is used as a starting point for mLetterboxPositionForReachability.
- @LetterboxReachabilityPosition
- private int mDefaultPositionForReachability;
+ // Vertical position of a center of the letterboxed app window. 0 corresponds to the top
+ // side of the screen and 1.0 to the bottom side.
+ private float mLetterboxVerticalPositionMultiplier;
+
+ // 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.
+ @LetterboxHorizontalReachabilityPosition
+ private int mDefaultPositionForHorizontalReachability;
+
+ // Default vertical position the letterboxed app window when vertical reachability is enabled
+ // and an app is fullscreen in portrait device orientation.
+ // It is used as a starting point for mLetterboxPositionForVerticalReachability.
+ @LetterboxVerticalReachabilityPosition
+ private int mDefaultPositionForVerticalReachability;
+
+ // Whether horizontal reachability repositioning is allowed for letterboxed fullscreen apps in
+ // landscape device orientation.
+ private boolean mIsHorizontalReachabilityEnabled;
+
+ // Whether vertical reachability repositioning is allowed for letterboxed fullscreen apps in
+ // portrait device orientation.
+ private boolean mIsVerticalReachabilityEnabled;
- // Whether reachability repositioning is allowed for letterboxed fullscreen apps in landscape
- // device orientation.
- private boolean mIsReachabilityEnabled;
// 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
// in response to a double tap gesture (see LetterboxUiController#handleDoubleTap). Used in
// LetterboxUiController#getHorizontalPositionMultiplier which is called from
- // ActivityRecord#updateResolvedBoundsHorizontalPosition.
+ // ActivityRecord#updateResolvedBoundsPosition.
// TODO(b/199426138): Global reachability setting causes a jump when resuming an app from
// Overview after changing position in another app.
- @LetterboxReachabilityPosition
- private volatile int mLetterboxPositionForReachability;
+ @LetterboxHorizontalReachabilityPosition
+ private volatile int mLetterboxPositionForHorizontalReachability;
+
+ // 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
+ // LetterboxUiController#getVerticalPositionMultiplier which is called from
+ // ActivityRecord#updateResolvedBoundsPosition.
+ // TODO(b/199426138): Global reachability setting causes a jump when resuming an app from
+ // Overview after changing position in another app.
+ @LetterboxVerticalReachabilityPosition
+ private volatile int mLetterboxPositionForVerticalReachability;
// Whether education is allowed for letterboxed fullscreen apps.
private boolean mIsEducationEnabled;
@@ -142,10 +190,16 @@ final class LetterboxConfiguration {
R.dimen.config_letterboxBackgroundWallaperDarkScrimAlpha);
mLetterboxHorizontalPositionMultiplier = mContext.getResources().getFloat(
R.dimen.config_letterboxHorizontalPositionMultiplier);
- mIsReachabilityEnabled = mContext.getResources().getBoolean(
- R.bool.config_letterboxIsReachabilityEnabled);
- mDefaultPositionForReachability = readLetterboxReachabilityPositionFromConfig(mContext);
- mLetterboxPositionForReachability = mDefaultPositionForReachability;
+ mIsHorizontalReachabilityEnabled = mContext.getResources().getBoolean(
+ R.bool.config_letterboxIsHorizontalReachabilityEnabled);
+ mIsVerticalReachabilityEnabled = mContext.getResources().getBoolean(
+ R.bool.config_letterboxIsVerticalReachabilityEnabled);
+ mDefaultPositionForHorizontalReachability =
+ readLetterboxHorizontalReachabilityPositionFromConfig(mContext);
+ mDefaultPositionForVerticalReachability =
+ readLetterboxVerticalReachabilityPositionFromConfig(mContext);
+ mLetterboxPositionForHorizontalReachability = mDefaultPositionForHorizontalReachability;
+ mLetterboxPositionForVerticalReachability = mDefaultPositionForVerticalReachability;
mIsEducationEnabled = mContext.getResources().getBoolean(
R.bool.config_letterboxIsEducationEnabled);
}
@@ -375,6 +429,19 @@ final class LetterboxConfiguration {
? 0.5f : mLetterboxHorizontalPositionMultiplier;
}
+ /*
+ * Gets vertical position of a center of the letterboxed app window specified
+ * in {@link com.android.internal.R.dimen.config_letterboxVerticalPositionMultiplier}
+ * 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;
+ }
+
/**
* Overrides horizontal position of a center of the letterboxed app window. If given value < 0
* or > 1, then it and a value of {@link
@@ -385,6 +452,16 @@ final class LetterboxConfiguration {
mLetterboxHorizontalPositionMultiplier = multiplier;
}
+ /**
+ * Overrides vertical position of a center of the letterboxed app window. If given value < 0
+ * or > 1, then it and a value of {@link
+ * com.android.internal.R.dimen.config_letterboxVerticalPositionMultiplier} are ignored and
+ * central position (0.5) is used.
+ */
+ void setLetterboxVerticalPositionMultiplier(float multiplier) {
+ mLetterboxVerticalPositionMultiplier = multiplier;
+ }
+
/**
* Resets horizontal position of a center of the letterboxed app window to {@link
* com.android.internal.R.dimen.config_letterboxHorizontalPositionMultiplier}.
@@ -394,65 +471,145 @@ final class LetterboxConfiguration {
com.android.internal.R.dimen.config_letterboxHorizontalPositionMultiplier);
}
- /*
- * Whether reachability repositioning is allowed for letterboxed fullscreen apps in landscape
- * device orientation.
+ /**
+ * Resets vertical position of a center of the letterboxed app window to {@link
+ * com.android.internal.R.dimen.config_letterboxVerticalPositionMultiplier}.
*/
- boolean getIsReachabilityEnabled() {
- return mIsReachabilityEnabled;
+ void resetLetterboxVerticalPositionMultiplier() {
+ mLetterboxVerticalPositionMultiplier = mContext.getResources().getFloat(
+ com.android.internal.R.dimen.config_letterboxVerticalPositionMultiplier);
}
- /**
- * Overrides whether reachability repositioning is allowed for letterboxed fullscreen apps in
+ /*
+ * Whether horizontal reachability repositioning is allowed for letterboxed fullscreen apps in
* landscape device orientation.
*/
- void setIsReachabilityEnabled(boolean enabled) {
- mIsReachabilityEnabled = enabled;
- }
-
- /**
- * Resets whether reachability repositioning is allowed for letterboxed fullscreen apps in
- * landscape device orientation to {@link R.bool.config_letterboxIsReachabilityEnabled}.
- */
- void resetIsReachabilityEnabled() {
- mIsReachabilityEnabled = mContext.getResources().getBoolean(
- R.bool.config_letterboxIsReachabilityEnabled);
+ boolean getIsHorizontalReachabilityEnabled() {
+ return mIsHorizontalReachabilityEnabled;
}
/*
- * Gets default horizontal position of the letterboxed app window when reachability is enabled.
- * Specified in {@link R.integer.config_letterboxDefaultPositionForReachability} or via an ADB
- * command.
+ * Whether vertical reachability repositioning is allowed for letterboxed fullscreen apps in
+ * portrait device orientation.
*/
- @LetterboxReachabilityPosition
- int getDefaultPositionForReachability() {
- return mDefaultPositionForReachability;
+ boolean getIsVerticalReachabilityEnabled() {
+ return mIsVerticalReachabilityEnabled;
}
/**
- * Overrides default horizonal position of the letterboxed app window when reachability
+ * Overrides whether horizontal reachability repositioning is allowed for letterboxed fullscreen
+ * apps in landscape device orientation.
+ */
+ void setIsHorizontalReachabilityEnabled(boolean enabled) {
+ mIsHorizontalReachabilityEnabled = enabled;
+ }
+
+ /**
+ * Overrides whether vertical reachability repositioning is allowed for letterboxed fullscreen
+ * apps in portrait device orientation.
+ */
+ void setIsVerticalReachabilityEnabled(boolean enabled) {
+ mIsVerticalReachabilityEnabled = enabled;
+ }
+
+ /**
+ * Resets whether horizontal reachability repositioning is allowed for letterboxed fullscreen
+ * apps in landscape device orientation to
+ * {@link R.bool.config_letterboxIsHorizontalReachabilityEnabled}.
+ */
+ void resetIsHorizontalReachabilityEnabled() {
+ mIsHorizontalReachabilityEnabled = mContext.getResources().getBoolean(
+ R.bool.config_letterboxIsHorizontalReachabilityEnabled);
+ }
+
+ /**
+ * Resets whether vertical reachability repositioning is allowed for letterboxed fullscreen apps
+ * in portrait device orientation to
+ * {@link R.bool.config_letterboxIsVerticalReachabilityEnabled}.
+ */
+ void resetIsVerticalReachabilityEnabled() {
+ mIsVerticalReachabilityEnabled = mContext.getResources().getBoolean(
+ R.bool.config_letterboxIsVerticalReachabilityEnabled);
+ }
+
+ /*
+ * Gets default horizontal position of the letterboxed app window when horizontal reachability
* is enabled.
+ *
+ *
Specified in {@link R.integer.config_letterboxDefaultPositionForHorizontalReachability}
+ * or via an ADB command.
*/
- void setDefaultPositionForReachability(@LetterboxReachabilityPosition int position) {
- mDefaultPositionForReachability = position;
+ @LetterboxHorizontalReachabilityPosition
+ int getDefaultPositionForHorizontalReachability() {
+ return mDefaultPositionForHorizontalReachability;
+ }
+
+ /*
+ * Gets default vertical position of the letterboxed app window when vertical reachability is
+ * enabled.
+ *
+ *
Specified in {@link R.integer.config_letterboxDefaultPositionForVerticalReachability} or
+ * via an ADB command.
+ */
+ @LetterboxVerticalReachabilityPosition
+ int getDefaultPositionForVerticalReachability() {
+ return mDefaultPositionForVerticalReachability;
}
/**
- * Resets default horizontal position of the letterboxed app window when reachability is
- * enabled to {@link R.integer.config_letterboxDefaultPositionForReachability}.
+ * Overrides default horizontal position of the letterboxed app window when horizontal
+ * reachability is enabled.
*/
- void resetDefaultPositionForReachability() {
- mDefaultPositionForReachability = readLetterboxReachabilityPositionFromConfig(mContext);
+ void setDefaultPositionForHorizontalReachability(
+ @LetterboxHorizontalReachabilityPosition int position) {
+ mDefaultPositionForHorizontalReachability = position;
}
- @LetterboxReachabilityPosition
- private static int readLetterboxReachabilityPositionFromConfig(Context context) {
+ /**
+ * Overrides default vertical position of the letterboxed app window when vertical
+ * reachability is enabled.
+ */
+ void setDefaultPositionForVerticalReachability(
+ @LetterboxVerticalReachabilityPosition int position) {
+ mDefaultPositionForVerticalReachability = position;
+ }
+
+ /**
+ * Resets default horizontal position of the letterboxed app window when horizontal reachability
+ * is enabled to {@link R.integer.config_letterboxDefaultPositionForHorizontalReachability}.
+ */
+ void resetDefaultPositionForHorizontalReachability() {
+ mDefaultPositionForHorizontalReachability =
+ readLetterboxHorizontalReachabilityPositionFromConfig(mContext);
+ }
+
+ /**
+ * Resets default vertical position of the letterboxed app window when vertical reachability
+ * is enabled to {@link R.integer.config_letterboxDefaultPositionForVerticalReachability}.
+ */
+ void resetDefaultPositionForVerticalReachability() {
+ mDefaultPositionForVerticalReachability =
+ readLetterboxVerticalReachabilityPositionFromConfig(mContext);
+ }
+
+ @LetterboxHorizontalReachabilityPosition
+ private static int readLetterboxHorizontalReachabilityPositionFromConfig(Context context) {
int position = context.getResources().getInteger(
- R.integer.config_letterboxDefaultPositionForReachability);
- return position == LETTERBOX_REACHABILITY_POSITION_LEFT
- || position == LETTERBOX_REACHABILITY_POSITION_CENTER
- || position == LETTERBOX_REACHABILITY_POSITION_RIGHT
- ? position : LETTERBOX_REACHABILITY_POSITION_CENTER;
+ 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;
+ }
+
+ @LetterboxVerticalReachabilityPosition
+ private static int readLetterboxVerticalReachabilityPositionFromConfig(Context context) {
+ int position = context.getResources().getInteger(
+ 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;
}
/*
@@ -462,48 +619,108 @@ final class LetterboxConfiguration {
*
The position multiplier is changed after each double tap in the letterbox area.
*/
float getHorizontalMultiplierForReachability() {
- switch (mLetterboxPositionForReachability) {
- case LETTERBOX_REACHABILITY_POSITION_LEFT:
+ switch (mLetterboxPositionForHorizontalReachability) {
+ case LETTERBOX_HORIZONTAL_REACHABILITY_POSITION_LEFT:
return 0.0f;
- case LETTERBOX_REACHABILITY_POSITION_CENTER:
+ case LETTERBOX_HORIZONTAL_REACHABILITY_POSITION_CENTER:
return 0.5f;
- case LETTERBOX_REACHABILITY_POSITION_RIGHT:
+ case LETTERBOX_HORIZONTAL_REACHABILITY_POSITION_RIGHT:
return 1.0f;
default:
throw new AssertionError(
- "Unexpected letterbox position type: " + mLetterboxPositionForReachability);
+ "Unexpected letterbox position type: "
+ + mLetterboxPositionForHorizontalReachability);
+ }
+ }
+ /*
+ * Gets vertical position of a center of the letterboxed app window when reachability
+ * is enabled specified. 0 corresponds to the top side of the screen and 1 to the bottom side.
+ *
+ *
The position multiplier is changed after each double tap in the letterbox area.
+ */
+ float getVerticalMultiplierForReachability() {
+ switch (mLetterboxPositionForVerticalReachability) {
+ case LETTERBOX_VERTICAL_REACHABILITY_POSITION_TOP:
+ return 0.0f;
+ case LETTERBOX_VERTICAL_REACHABILITY_POSITION_CENTER:
+ return 0.5f;
+ case LETTERBOX_VERTICAL_REACHABILITY_POSITION_BOTTOM:
+ return 1.0f;
+ default:
+ throw new AssertionError(
+ "Unexpected letterbox position type: "
+ + mLetterboxPositionForVerticalReachability);
}
}
- /** Returns a string representing the given {@link LetterboxReachabilityPosition}. */
- static String letterboxReachabilityPositionToString(
- @LetterboxReachabilityPosition int position) {
+ /** Returns a string representing the given {@link LetterboxHorizontalReachabilityPosition}. */
+ static String letterboxHorizontalReachabilityPositionToString(
+ @LetterboxHorizontalReachabilityPosition int position) {
switch (position) {
- case LETTERBOX_REACHABILITY_POSITION_LEFT:
- return "LETTERBOX_REACHABILITY_POSITION_LEFT";
- case LETTERBOX_REACHABILITY_POSITION_CENTER:
- return "LETTERBOX_REACHABILITY_POSITION_CENTER";
- case LETTERBOX_REACHABILITY_POSITION_RIGHT:
- return "LETTERBOX_REACHABILITY_POSITION_RIGHT";
+ case LETTERBOX_HORIZONTAL_REACHABILITY_POSITION_LEFT:
+ return "LETTERBOX_HORIZONTAL_REACHABILITY_POSITION_LEFT";
+ case LETTERBOX_HORIZONTAL_REACHABILITY_POSITION_CENTER:
+ return "LETTERBOX_HORIZONTAL_REACHABILITY_POSITION_CENTER";
+ case LETTERBOX_HORIZONTAL_REACHABILITY_POSITION_RIGHT:
+ return "LETTERBOX_HORIZONTAL_REACHABILITY_POSITION_RIGHT";
default:
throw new AssertionError(
"Unexpected letterbox position type: " + position);
}
}
- /**
- * Changes letterbox position for reachability to the next available one on the right side.
- */
- void movePositionForReachabilityToNextRightStop() {
- mLetterboxPositionForReachability = Math.min(
- mLetterboxPositionForReachability + 1, LETTERBOX_REACHABILITY_POSITION_RIGHT);
+ /** Returns a string representing the given {@link LetterboxVerticalReachabilityPosition}. */
+ static String letterboxVerticalReachabilityPositionToString(
+ @LetterboxVerticalReachabilityPosition int position) {
+ switch (position) {
+ case LETTERBOX_VERTICAL_REACHABILITY_POSITION_TOP:
+ return "LETTERBOX_VERTICAL_REACHABILITY_POSITION_TOP";
+ case LETTERBOX_VERTICAL_REACHABILITY_POSITION_CENTER:
+ return "LETTERBOX_VERTICAL_REACHABILITY_POSITION_CENTER";
+ case LETTERBOX_VERTICAL_REACHABILITY_POSITION_BOTTOM:
+ return "LETTERBOX_VERTICAL_REACHABILITY_POSITION_BOTTOM";
+ default:
+ throw new AssertionError(
+ "Unexpected letterbox position type: " + position);
+ }
}
/**
- * Changes letterbox position for reachability to the next available one on the left side.
+ * Changes letterbox position for horizontal reachability to the next available one on the
+ * right side.
*/
- void movePositionForReachabilityToNextLeftStop() {
- mLetterboxPositionForReachability = Math.max(mLetterboxPositionForReachability - 1, 0);
+ void movePositionForHorizontalReachabilityToNextRightStop() {
+ mLetterboxPositionForHorizontalReachability = Math.min(
+ mLetterboxPositionForHorizontalReachability + 1,
+ LETTERBOX_HORIZONTAL_REACHABILITY_POSITION_RIGHT);
+ }
+
+ /**
+ * Changes letterbox position for horizontal reachability to the next available one on the left
+ * side.
+ */
+ void movePositionForHorizontalReachabilityToNextLeftStop() {
+ mLetterboxPositionForHorizontalReachability =
+ Math.max(mLetterboxPositionForHorizontalReachability - 1, 0);
+ }
+
+ /**
+ * Changes letterbox position for vertical reachability to the next available one on the bottom
+ * side.
+ */
+ void movePositionForVerticalReachabilityToNextBottomStop() {
+ mLetterboxPositionForVerticalReachability = Math.min(
+ mLetterboxPositionForVerticalReachability + 1,
+ LETTERBOX_VERTICAL_REACHABILITY_POSITION_BOTTOM);
+ }
+
+ /**
+ * Changes letterbox position for vertical reachability to the next available one on the top
+ * side.
+ */
+ void movePositionForVerticalReachabilityToNextTopStop() {
+ mLetterboxPositionForVerticalReachability =
+ Math.max(mLetterboxPositionForVerticalReachability - 1, 0);
}
/**
diff --git a/services/core/java/com/android/server/wm/LetterboxUiController.java b/services/core/java/com/android/server/wm/LetterboxUiController.java
index bb15d76c3bac0..201520677b26d 100644
--- a/services/core/java/com/android/server/wm/LetterboxUiController.java
+++ b/services/core/java/com/android/server/wm/LetterboxUiController.java
@@ -163,7 +163,8 @@ final class LetterboxUiController {
this::hasWallpaperBackgroudForLetterbox,
this::getLetterboxWallpaperBlurRadius,
this::getLetterboxWallpaperDarkScrimAlpha,
- this::handleDoubleTap);
+ this::handleHorizontalDoubleTap,
+ this::handleVerticalDoubleTap);
mLetterbox.attachInput(w);
}
mActivityRecord.getPosition(mTmpPoint);
@@ -193,17 +194,28 @@ final class LetterboxUiController {
float getHorizontalPositionMultiplier(Configuration parentConfiguration) {
// Don't check resolved configuration because it may not be updated yet during
// configuration change.
- return isReachabilityEnabled(parentConfiguration)
+ return isHorizontalReachabilityEnabled(parentConfiguration)
// Using the last global dynamic position to avoid "jumps" when moving
// between apps or activities.
? mLetterboxConfiguration.getHorizontalMultiplierForReachability()
: mLetterboxConfiguration.getLetterboxHorizontalPositionMultiplier();
}
+ float getVerticalPositionMultiplier(Configuration parentConfiguration) {
+ // Don't check resolved configuration because it may not be updated yet during
+ // configuration change.
+ return isVerticalReachabilityEnabled(parentConfiguration)
+ // Using the last global dynamic position to avoid "jumps" when moving
+ // between apps or activities.
+ ? mLetterboxConfiguration.getVerticalMultiplierForReachability()
+ : mLetterboxConfiguration.getLetterboxVerticalPositionMultiplier();
+ }
+
float getFixedOrientationLetterboxAspectRatio(Configuration parentConfiguration) {
// Don't check resolved windowing mode because it may not be updated yet during
// configuration change.
- if (!isReachabilityEnabled(parentConfiguration)) {
+ if (!isHorizontalReachabilityEnabled(parentConfiguration)
+ && !isVerticalReachabilityEnabled(parentConfiguration)) {
return mLetterboxConfiguration.getFixedOrientationLetterboxAspectRatio();
}
@@ -225,8 +237,8 @@ final class LetterboxUiController {
return mActivityRecord.mWmService.mContext.getResources();
}
- private void handleDoubleTap(int x) {
- if (!isReachabilityEnabled() || mActivityRecord.isInTransition()) {
+ private void handleHorizontalDoubleTap(int x) {
+ if (!isHorizontalReachabilityEnabled() || mActivityRecord.isInTransition()) {
return;
}
@@ -237,10 +249,32 @@ final class LetterboxUiController {
if (mLetterbox.getInnerFrame().left > x) {
// Moving to the next stop on the left side of the app window: right > center > left.
- mLetterboxConfiguration.movePositionForReachabilityToNextLeftStop();
+ mLetterboxConfiguration.movePositionForHorizontalReachabilityToNextLeftStop();
} else if (mLetterbox.getInnerFrame().right < x) {
// Moving to the next stop on the right side of the app window: left > center > right.
- mLetterboxConfiguration.movePositionForReachabilityToNextRightStop();
+ mLetterboxConfiguration.movePositionForHorizontalReachabilityToNextRightStop();
+ }
+
+ // TODO(197549949): Add animation for transition.
+ mActivityRecord.recomputeConfiguration();
+ }
+
+ private void handleVerticalDoubleTap(int y) {
+ if (!isVerticalReachabilityEnabled() || mActivityRecord.isInTransition()) {
+ return;
+ }
+
+ if (mLetterbox.getInnerFrame().top <= y && mLetterbox.getInnerFrame().bottom >= y) {
+ // Only react to clicks at the top and bottom of the letterboxed app window.
+ return;
+ }
+
+ if (mLetterbox.getInnerFrame().top > y) {
+ // Moving to the next stop on the top side of the app window: bottom > center > top.
+ mLetterboxConfiguration.movePositionForVerticalReachabilityToNextTopStop();
+ } else if (mLetterbox.getInnerFrame().bottom < y) {
+ // Moving to the next stop on the bottom side of the app window: top > center > bottom.
+ mLetterboxConfiguration.movePositionForVerticalReachabilityToNextBottomStop();
}
// TODO(197549949): Add animation for transition.
@@ -248,25 +282,47 @@ final class LetterboxUiController {
}
/**
- * Whether reachability is enabled for an activity in the curren configuration.
+ * Whether horizontal reachability is enabled for an activity in the current configuration.
*
*
Conditions that needs to be met:
*
* - Activity is portrait-only.
*
- Fullscreen window in landscape device orientation.
- *
- Reachability is enabled.
+ *
- Horizontal Reachability is enabled.
*
*/
- private boolean isReachabilityEnabled(Configuration parentConfiguration) {
- return mLetterboxConfiguration.getIsReachabilityEnabled()
+ private boolean isHorizontalReachabilityEnabled(Configuration parentConfiguration) {
+ return mLetterboxConfiguration.getIsHorizontalReachabilityEnabled()
&& parentConfiguration.windowConfiguration.getWindowingMode()
== WINDOWING_MODE_FULLSCREEN
- && parentConfiguration.orientation == ORIENTATION_LANDSCAPE
- && mActivityRecord.getRequestedConfigurationOrientation() == ORIENTATION_PORTRAIT;
+ && (parentConfiguration.orientation == ORIENTATION_LANDSCAPE
+ && mActivityRecord.getRequestedConfigurationOrientation() == ORIENTATION_PORTRAIT);
}
- private boolean isReachabilityEnabled() {
- return isReachabilityEnabled(mActivityRecord.getParent().getConfiguration());
+ private boolean isHorizontalReachabilityEnabled() {
+ return isHorizontalReachabilityEnabled(mActivityRecord.getParent().getConfiguration());
+ }
+
+ /**
+ * Whether vertical reachability is enabled for an activity in the current configuration.
+ *
+ * Conditions that needs to be met:
+ *
+ * - Activity is landscape-only.
+ *
- Fullscreen window in portrait device orientation.
+ *
- Vertical Reachability is enabled.
+ *
+ */
+ private boolean isVerticalReachabilityEnabled(Configuration parentConfiguration) {
+ return mLetterboxConfiguration.getIsVerticalReachabilityEnabled()
+ && parentConfiguration.windowConfiguration.getWindowingMode()
+ == WINDOWING_MODE_FULLSCREEN
+ && (parentConfiguration.orientation == ORIENTATION_PORTRAIT
+ && mActivityRecord.getRequestedConfigurationOrientation() == ORIENTATION_LANDSCAPE);
+ }
+
+ private boolean isVerticalReachabilityEnabled() {
+ return isVerticalReachabilityEnabled(mActivityRecord.getParent().getConfiguration());
}
@VisibleForTesting
@@ -474,9 +530,13 @@ final class LetterboxUiController {
+ getLetterboxWallpaperBlurRadius());
}
- pw.println(prefix + " isReachabilityEnabled=" + isReachabilityEnabled());
+ pw.println(prefix + " isHorizontalReachabilityEnabled="
+ + isHorizontalReachabilityEnabled());
+ pw.println(prefix + " isVerticalReachabilityEnabled=" + isVerticalReachabilityEnabled());
pw.println(prefix + " letterboxHorizontalPositionMultiplier="
+ getHorizontalPositionMultiplier(mActivityRecord.getParent().getConfiguration()));
+ pw.println(prefix + " letterboxVerticalPositionMultiplier="
+ + getVerticalPositionMultiplier(mActivityRecord.getParent().getConfiguration()));
pw.println(prefix + " fixedOrientationLetterboxAspectRatio="
+ getFixedOrientationLetterboxAspectRatio(
mActivityRecord.getParent().getConfiguration()));
diff --git a/services/core/java/com/android/server/wm/WindowManagerShellCommand.java b/services/core/java/com/android/server/wm/WindowManagerShellCommand.java
index 5a2f28f4a3658..1284bb3062759 100644
--- a/services/core/java/com/android/server/wm/WindowManagerShellCommand.java
+++ b/services/core/java/com/android/server/wm/WindowManagerShellCommand.java
@@ -23,9 +23,12 @@ import static com.android.server.wm.LetterboxConfiguration.LETTERBOX_BACKGROUND_
import static com.android.server.wm.LetterboxConfiguration.LETTERBOX_BACKGROUND_APP_COLOR_BACKGROUND_FLOATING;
import static com.android.server.wm.LetterboxConfiguration.LETTERBOX_BACKGROUND_SOLID_COLOR;
import static com.android.server.wm.LetterboxConfiguration.LETTERBOX_BACKGROUND_WALLPAPER;
-import static com.android.server.wm.LetterboxConfiguration.LETTERBOX_REACHABILITY_POSITION_CENTER;
-import static com.android.server.wm.LetterboxConfiguration.LETTERBOX_REACHABILITY_POSITION_LEFT;
-import static com.android.server.wm.LetterboxConfiguration.LETTERBOX_REACHABILITY_POSITION_RIGHT;
+import static com.android.server.wm.LetterboxConfiguration.LETTERBOX_HORIZONTAL_REACHABILITY_POSITION_CENTER;
+import static com.android.server.wm.LetterboxConfiguration.LETTERBOX_HORIZONTAL_REACHABILITY_POSITION_LEFT;
+import static com.android.server.wm.LetterboxConfiguration.LETTERBOX_HORIZONTAL_REACHABILITY_POSITION_RIGHT;
+import static com.android.server.wm.LetterboxConfiguration.LETTERBOX_VERTICAL_REACHABILITY_POSITION_BOTTOM;
+import static com.android.server.wm.LetterboxConfiguration.LETTERBOX_VERTICAL_REACHABILITY_POSITION_CENTER;
+import static com.android.server.wm.LetterboxConfiguration.LETTERBOX_VERTICAL_REACHABILITY_POSITION_TOP;
import android.content.res.Resources.NotFoundException;
import android.graphics.Color;
@@ -47,7 +50,8 @@ import com.android.internal.protolog.ProtoLogImpl;
import com.android.server.LocalServices;
import com.android.server.statusbar.StatusBarManagerInternal;
import com.android.server.wm.LetterboxConfiguration.LetterboxBackgroundType;
-import com.android.server.wm.LetterboxConfiguration.LetterboxReachabilityPosition;
+import com.android.server.wm.LetterboxConfiguration.LetterboxHorizontalReachabilityPosition;
+import com.android.server.wm.LetterboxConfiguration.LetterboxVerticalReachabilityPosition;
import java.io.IOException;
import java.io.PrintWriter;
@@ -773,7 +777,27 @@ public class WindowManagerShellCommand extends ShellCommand {
return 0;
}
- private int runSetLetterboxIsReachabilityEnabled(PrintWriter pw) throws RemoteException {
+ private int runSetLetterboxVerticalPositionMultiplier(PrintWriter pw) throws RemoteException {
+ final float multiplier;
+ try {
+ String arg = getNextArgRequired();
+ multiplier = Float.parseFloat(arg);
+ } catch (NumberFormatException e) {
+ getErrPrintWriter().println("Error: bad multiplier format " + e);
+ return -1;
+ } catch (IllegalArgumentException e) {
+ getErrPrintWriter().println(
+ "Error: multiplier should be provided as an argument " + e);
+ return -1;
+ }
+ synchronized (mInternal.mGlobalLock) {
+ mLetterboxConfiguration.setLetterboxVerticalPositionMultiplier(multiplier);
+ }
+ return 0;
+ }
+
+ private int runSetLetterboxIsHorizontalReachabilityEnabled(PrintWriter pw)
+ throws RemoteException {
String arg = getNextArg();
final boolean enabled;
switch (arg) {
@@ -791,25 +815,49 @@ public class WindowManagerShellCommand extends ShellCommand {
}
synchronized (mInternal.mGlobalLock) {
- mLetterboxConfiguration.setIsReachabilityEnabled(enabled);
+ mLetterboxConfiguration.setIsHorizontalReachabilityEnabled(enabled);
}
return 0;
}
- private int runSetLetterboxDefaultPositionForReachability(PrintWriter pw)
+ private int runSetLetterboxIsVerticalReachabilityEnabled(PrintWriter pw)
throws RemoteException {
- @LetterboxReachabilityPosition final int position;
+ String arg = getNextArg();
+ final boolean enabled;
+ switch (arg) {
+ case "true":
+ case "1":
+ enabled = true;
+ break;
+ case "false":
+ case "0":
+ enabled = false;
+ break;
+ default:
+ getErrPrintWriter().println("Error: expected true, 1, false, 0, but got " + arg);
+ return -1;
+ }
+
+ synchronized (mInternal.mGlobalLock) {
+ mLetterboxConfiguration.setIsVerticalReachabilityEnabled(enabled);
+ }
+ return 0;
+ }
+
+ private int runSetLetterboxDefaultPositionForHorizontalReachability(PrintWriter pw)
+ throws RemoteException {
+ @LetterboxHorizontalReachabilityPosition final int position;
try {
String arg = getNextArgRequired();
switch (arg) {
case "left":
- position = LETTERBOX_REACHABILITY_POSITION_LEFT;
+ position = LETTERBOX_HORIZONTAL_REACHABILITY_POSITION_LEFT;
break;
case "center":
- position = LETTERBOX_REACHABILITY_POSITION_CENTER;
+ position = LETTERBOX_HORIZONTAL_REACHABILITY_POSITION_CENTER;
break;
case "right":
- position = LETTERBOX_REACHABILITY_POSITION_RIGHT;
+ position = LETTERBOX_HORIZONTAL_REACHABILITY_POSITION_RIGHT;
break;
default:
getErrPrintWriter().println(
@@ -822,7 +870,38 @@ public class WindowManagerShellCommand extends ShellCommand {
return -1;
}
synchronized (mInternal.mGlobalLock) {
- mLetterboxConfiguration.setDefaultPositionForReachability(position);
+ mLetterboxConfiguration.setDefaultPositionForHorizontalReachability(position);
+ }
+ return 0;
+ }
+
+ private int runSetLetterboxDefaultPositionForVerticalReachability(PrintWriter pw)
+ throws RemoteException {
+ @LetterboxVerticalReachabilityPosition final int position;
+ try {
+ String arg = getNextArgRequired();
+ switch (arg) {
+ case "top":
+ position = LETTERBOX_VERTICAL_REACHABILITY_POSITION_TOP;
+ break;
+ case "center":
+ position = LETTERBOX_VERTICAL_REACHABILITY_POSITION_CENTER;
+ break;
+ case "bottom":
+ position = LETTERBOX_VERTICAL_REACHABILITY_POSITION_BOTTOM;
+ break;
+ default:
+ getErrPrintWriter().println(
+ "Error: 'top', 'center' or 'bottom' are expected as an argument");
+ return -1;
+ }
+ } catch (IllegalArgumentException e) {
+ getErrPrintWriter().println(
+ "Error: 'top', 'center' or 'bottom' are expected as an argument" + e);
+ return -1;
+ }
+ synchronized (mInternal.mGlobalLock) {
+ mLetterboxConfiguration.setDefaultPositionForVerticalReachability(position);
}
return 0;
}
@@ -881,11 +960,20 @@ public class WindowManagerShellCommand extends ShellCommand {
case "--horizontalPositionMultiplier":
runSetLetterboxHorizontalPositionMultiplier(pw);
break;
- case "--isReachabilityEnabled":
- runSetLetterboxIsReachabilityEnabled(pw);
+ case "--verticalPositionMultiplier":
+ runSetLetterboxVerticalPositionMultiplier(pw);
break;
- case "--defaultPositionForReachability":
- runSetLetterboxDefaultPositionForReachability(pw);
+ case "--isHorizontalReachabilityEnabled":
+ runSetLetterboxIsHorizontalReachabilityEnabled(pw);
+ break;
+ case "--isVerticalReachabilityEnabled":
+ runSetLetterboxIsVerticalReachabilityEnabled(pw);
+ break;
+ case "--defaultPositionForHorizontalReachability":
+ runSetLetterboxDefaultPositionForHorizontalReachability(pw);
+ break;
+ case "--defaultPositionForVerticalReachability":
+ runSetLetterboxDefaultPositionForVerticalReachability(pw);
break;
case "--isEducationEnabled":
runSetLetterboxIsEducationEnabled(pw);
@@ -928,11 +1016,20 @@ public class WindowManagerShellCommand extends ShellCommand {
case "horizontalPositionMultiplier":
mLetterboxConfiguration.resetLetterboxHorizontalPositionMultiplier();
break;
- case "isReachabilityEnabled":
- mLetterboxConfiguration.getIsReachabilityEnabled();
+ case "verticalPositionMultiplier":
+ mLetterboxConfiguration.resetLetterboxVerticalPositionMultiplier();
break;
- case "defaultPositionForReachability":
- mLetterboxConfiguration.getDefaultPositionForReachability();
+ case "isHorizontalReachabilityEnabled":
+ mLetterboxConfiguration.getIsHorizontalReachabilityEnabled();
+ break;
+ case "isVerticalReachabilityEnabled":
+ mLetterboxConfiguration.getIsVerticalReachabilityEnabled();
+ break;
+ case "defaultPositionForHorizontalReachability":
+ mLetterboxConfiguration.getDefaultPositionForHorizontalReachability();
+ break;
+ case "defaultPositionForVerticalReachability":
+ mLetterboxConfiguration.getDefaultPositionForVerticalReachability();
break;
case "isEducationEnabled":
mLetterboxConfiguration.getIsEducationEnabled();
@@ -1030,8 +1127,10 @@ public class WindowManagerShellCommand extends ShellCommand {
mLetterboxConfiguration.resetLetterboxBackgroundWallpaperBlurRadius();
mLetterboxConfiguration.resetLetterboxBackgroundWallpaperDarkScrimAlpha();
mLetterboxConfiguration.resetLetterboxHorizontalPositionMultiplier();
- mLetterboxConfiguration.resetIsReachabilityEnabled();
- mLetterboxConfiguration.resetDefaultPositionForReachability();
+ mLetterboxConfiguration.resetIsHorizontalReachabilityEnabled();
+ mLetterboxConfiguration.resetIsVerticalReachabilityEnabled();
+ mLetterboxConfiguration.resetDefaultPositionForHorizontalReachability();
+ mLetterboxConfiguration.resetDefaultPositionForVerticalReachability();
mLetterboxConfiguration.resetIsEducationEnabled();
}
}
@@ -1044,11 +1143,16 @@ public class WindowManagerShellCommand extends ShellCommand {
+ mLetterboxConfiguration.getLetterboxHorizontalPositionMultiplier());
pw.println("Aspect ratio: "
+ mLetterboxConfiguration.getFixedOrientationLetterboxAspectRatio());
- pw.println("Is reachability enabled: "
- + mLetterboxConfiguration.getIsReachabilityEnabled());
- pw.println("Default position for reachability: "
- + LetterboxConfiguration.letterboxReachabilityPositionToString(
- mLetterboxConfiguration.getDefaultPositionForReachability()));
+ pw.println("Is horizontal reachability enabled: "
+ + mLetterboxConfiguration.getIsHorizontalReachabilityEnabled());
+ pw.println("Is vertical reachability enabled: "
+ + mLetterboxConfiguration.getIsVerticalReachabilityEnabled());
+ pw.println("Default position for horizontal reachability: "
+ + LetterboxConfiguration.letterboxHorizontalReachabilityPositionToString(
+ mLetterboxConfiguration.getDefaultPositionForHorizontalReachability()));
+ pw.println("Default position for vertical reachability: "
+ + LetterboxConfiguration.letterboxVerticalReachabilityPositionToString(
+ mLetterboxConfiguration.getDefaultPositionForVerticalReachability()));
pw.println("Is education enabled: "
+ mLetterboxConfiguration.getIsEducationEnabled());
@@ -1185,18 +1289,30 @@ public class WindowManagerShellCommand extends ShellCommand {
pw.println(" Horizontal position of app window center. If multiplier < 0 or > 1,");
pw.println(" both it and R.dimen.config_letterboxHorizontalPositionMultiplier");
pw.println(" are ignored and central position (0.5) is used.");
- pw.println(" --isReachabilityEnabled [true|1|false|0]");
- pw.println(" Whether reachability repositioning is allowed for letterboxed");
- pw.println(" fullscreen apps in landscape device orientation.");
- pw.println(" --defaultPositionForReachability [left|center|right]");
- pw.println(" Default horizontal position of app window when reachability is.");
+ pw.println(" --verticalPositionMultiplier multiplier");
+ pw.println(" Vertical position of app window center. If multiplier < 0 or > 1,");
+ pw.println(" both it and R.dimen.config_letterboxVerticalPositionMultiplier");
+ pw.println(" are ignored and central position (0.5) is used.");
+ pw.println(" --isHorizontalReachabilityEnabled [true|1|false|0]");
+ pw.println(" Whether horizontal reachability repositioning is allowed for ");
+ pw.println(" letterboxed fullscreen apps in landscape device orientation.");
+ pw.println(" --isVerticalReachabilityEnabled [true|1|false|0]");
+ pw.println(" Whether vertical reachability repositioning is allowed for ");
+ pw.println(" letterboxed fullscreen apps in portrait device orientation.");
+ pw.println(" --defaultPositionForHorizontalReachability [left|center|right]");
+ pw.println(" Default position of app window when horizontal reachability is.");
+ pw.println(" enabled.");
+ pw.println(" --defaultPositionForVerticalReachability [top|center|bottom]");
+ pw.println(" Default position of app window when vertical reachability is.");
pw.println(" enabled.");
pw.println(" --isEducationEnabled [true|1|false|0]");
pw.println(" Whether education is allowed for letterboxed fullscreen apps.");
pw.println(" reset-letterbox-style [aspectRatio|cornerRadius|backgroundType");
pw.println(" |backgroundColor|wallpaperBlurRadius|wallpaperDarkScrimAlpha");
- pw.println(" |horizontalPositionMultiplier|isReachabilityEnabled");
- pw.println(" isEducationEnabled||defaultPositionMultiplierForReachability]");
+ pw.println(" |horizontalPositionMultiplier|verticalPositionMultiplier");
+ pw.println(" |isHorizontalReachabilityEnabled|isVerticalReachabilityEnabled");
+ pw.println(" isEducationEnabled||defaultPositionMultiplierForHorizontalReachability");
+ pw.println(" ||defaultPositionMultiplierForVerticalReachability]");
pw.println(" Resets overrides to default values for specified properties separated");
pw.println(" by space, e.g. 'reset-letterbox-style aspectRatio cornerRadius'.");
pw.println(" If no arguments provided, all values will be reset.");
diff --git a/services/tests/wmtests/src/com/android/server/wm/LetterboxTest.java b/services/tests/wmtests/src/com/android/server/wm/LetterboxTest.java
index 1e86522a23073..e502f2fbd1734 100644
--- a/services/tests/wmtests/src/com/android/server/wm/LetterboxTest.java
+++ b/services/tests/wmtests/src/com/android/server/wm/LetterboxTest.java
@@ -63,7 +63,7 @@ public class LetterboxTest {
mLetterbox = new Letterbox(mSurfaces, StubTransaction::new,
() -> mAreCornersRounded, () -> Color.valueOf(mColor),
() -> mHasWallpaperBackground, () -> mBlurRadius, () -> mDarkScrimAlpha,
- /* doubleTapCallback= */ x -> {});
+ /* doubleTapCallbackX= */ x -> {}, /* doubleTapCallbackY= */ y -> {});
mTransaction = spy(StubTransaction.class);
}
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 76fb7ff2e6f86..aca2d5989f957 100644
--- a/services/tests/wmtests/src/com/android/server/wm/SizeCompatTests.java
+++ b/services/tests/wmtests/src/com/android/server/wm/SizeCompatTests.java
@@ -1928,7 +1928,7 @@ public class SizeCompatTests extends WindowTestsBase {
prepareUnresizable(mActivity, /* maxAspect */ 1.1f, SCREEN_ORIENTATION_UNSPECIFIED);
// Bounds are letterboxed to respect the provided max aspect ratio.
- assertEquals(mActivity.getBounds(), new Rect(0, 0, 1000, 1100));
+ assertEquals(mActivity.getBounds(), new Rect(0, 850, 1000, 1950));
// Move activity to split screen which has landscape size.
mTask.reparent(organizer.mPrimary, POSITION_TOP, /* moveParents */ false, "test");
@@ -2045,19 +2045,14 @@ public class SizeCompatTests extends WindowTestsBase {
mActivity.mWmService.mLetterboxConfiguration.setLetterboxHorizontalPositionMultiplier(
letterboxHorizontalPositionMultiplier);
prepareUnresizable(mActivity, SCREEN_ORIENTATION_PORTRAIT);
-
assertEquals(fixedOrientationLetterbox, mActivity.getBounds());
-
// Rotate to put activity in size compat mode.
rotateDisplay(mActivity.mDisplayContent, ROTATION_90);
-
assertTrue(mActivity.inSizeCompatMode());
// Activity is in size compat mode but not scaled.
assertEquals(sizeCompatUnscaled, mActivity.getBounds());
-
// Force activity to scaled down for size compat mode.
resizeDisplay(mTask.mDisplayContent, 700, 1400);
-
assertTrue(mActivity.inSizeCompatMode());
assertScaled();
assertEquals(sizeCompatScaled, mActivity.getBounds());
@@ -2074,6 +2069,109 @@ public class SizeCompatTests extends WindowTestsBase {
/* letterboxHorizontalPositionMultiplier */ 1.0f);
}
+ @Test
+ public void testUpdateResolvedBoundsVerticalPosition_top() {
+ // Display configured as (1400, 2800).
+ assertVerticalPositionForDifferentDisplayConfigsForLandscapeActivity(
+ /* letterboxVerticalPositionMultiplier */ 0.0f,
+ // At launch.
+ /* fixedOrientationLetterbox */ new Rect(0, 0, 1400, 700),
+ // After 90 degree rotation.
+ /* sizeCompatUnscaled */ new Rect(700, 0, 2100, 700),
+ // After the display is resized to (1400, 700).
+ /* sizeCompatScaled */ new Rect(0, 0, 700, 350));
+ }
+
+ @Test
+ public void testUpdateResolvedBoundsVerticalPosition_center() {
+ // Display configured as (1400, 2800).
+ assertVerticalPositionForDifferentDisplayConfigsForLandscapeActivity(
+ /* letterboxVerticalPositionMultiplier */ 0.5f,
+ // At launch.
+ /* fixedOrientationLetterbox */ new Rect(0, 1050, 1400, 1750),
+ // After 90 degree rotation.
+ /* sizeCompatUnscaled */ new Rect(700, 350, 2100, 1050),
+ // After the display is resized to (1400, 700).
+ /* sizeCompatScaled */ new Rect(0, 525, 700, 875));
+ }
+
+ @Test
+ public void testUpdateResolvedBoundsVerticalPosition_invalidMultiplier_defaultToCenter() {
+ // Display configured as (1400, 2800).
+
+ // Below 0.0.
+ assertVerticalPositionForDifferentDisplayConfigsForLandscapeActivity(
+ /* letterboxVerticalPositionMultiplier */ -1.0f,
+ // At launch.
+ /* fixedOrientationLetterbox */ new Rect(0, 1050, 1400, 1750),
+ // After 90 degree rotation.
+ /* sizeCompatUnscaled */ new Rect(700, 350, 2100, 1050),
+ // After the display is resized to (1400, 700).
+ /* sizeCompatScaled */ new Rect(0, 525, 700, 875));
+
+ // Above 1.0
+ assertVerticalPositionForDifferentDisplayConfigsForLandscapeActivity(
+ /* letterboxVerticalPositionMultiplier */ 2.0f,
+ // At launch.
+ /* fixedOrientationLetterbox */ new Rect(0, 1050, 1400, 1750),
+ // After 90 degree rotation.
+ /* sizeCompatUnscaled */ new Rect(700, 350, 2100, 1050),
+ // After the display is resized to (1400, 700).
+ /* sizeCompatScaled */ new Rect(0, 525, 700, 875));
+ }
+
+ @Test
+ public void testUpdateResolvedBoundsVerticalPosition_bottom() {
+ // Display configured as (1400, 2800).
+ assertVerticalPositionForDifferentDisplayConfigsForLandscapeActivity(
+ /* letterboxVerticalPositionMultiplier */ 1.0f,
+ // At launch.
+ /* fixedOrientationLetterbox */ new Rect(0, 2100, 1400, 2800),
+ // After 90 degree rotation.
+ /* sizeCompatUnscaled */ new Rect(700, 700, 2100, 1400),
+ // After the display is resized to (1400, 700).
+ /* sizeCompatScaled */ new Rect(0, 1050, 700, 1400));
+ }
+
+ private void assertVerticalPositionForDifferentDisplayConfigsForLandscapeActivity(
+ float letterboxVerticalPositionMultiplier, Rect fixedOrientationLetterbox,
+ Rect sizeCompatUnscaled, Rect sizeCompatScaled) {
+ // Set up a display in portrait and ignoring orientation request.
+ setUpDisplaySizeWithApp(1400, 2800);
+ mActivity.mDisplayContent.setIgnoreOrientationRequest(true /* ignoreOrientationRequest */);
+
+ mActivity.mWmService.mLetterboxConfiguration.setLetterboxVerticalPositionMultiplier(
+ letterboxVerticalPositionMultiplier);
+ prepareUnresizable(mActivity, SCREEN_ORIENTATION_LANDSCAPE);
+
+ assertEquals(fixedOrientationLetterbox, mActivity.getBounds());
+
+ // Rotate to put activity in size compat mode.
+ rotateDisplay(mActivity.mDisplayContent, ROTATION_90);
+
+ assertTrue(mActivity.inSizeCompatMode());
+ // Activity is in size compat mode but not scaled.
+ assertEquals(sizeCompatUnscaled, mActivity.getBounds());
+
+ // Force activity to scaled down for size compat mode.
+ resizeDisplay(mTask.mDisplayContent, 1400, 700);
+
+ assertTrue(mActivity.inSizeCompatMode());
+ assertScaled();
+ assertEquals(sizeCompatScaled, mActivity.getBounds());
+ }
+
+ @Test
+ public void testUpdateResolvedBoundsVerticalPosition_activityFillParentHeight() {
+ // When activity height equals parent height, multiplier shouldn't have any effect.
+ assertVerticalPositionForDifferentDisplayConfigsForPortraitActivity(
+ /* letterboxVerticalPositionMultiplier */ 0.0f);
+ assertVerticalPositionForDifferentDisplayConfigsForPortraitActivity(
+ /* letterboxVerticalPositionMultiplier */ 0.5f);
+ assertVerticalPositionForDifferentDisplayConfigsForPortraitActivity(
+ /* letterboxVerticalPositionMultiplier */ 1.0f);
+ }
+
@Test
public void testAreBoundsLetterboxed_letterboxedForAspectRatio_returnsTrue() {
setUpDisplaySizeWithApp(1000, 2500);
@@ -2367,6 +2465,23 @@ public class SizeCompatTests extends WindowTestsBase {
mActivity.mWmService.mLetterboxConfiguration.setLetterboxHorizontalPositionMultiplier(
letterboxHorizontalPositionMultiplier);
prepareUnresizable(mActivity, SCREEN_ORIENTATION_LANDSCAPE);
+ assertFitted();
+ // Rotate to put activity in size compat mode.
+ rotateDisplay(mActivity.mDisplayContent, ROTATION_90);
+ assertTrue(mActivity.inSizeCompatMode());
+ // Activity is in size compat mode but not scaled.
+ assertEquals(new Rect(0, 1050, 1400, 1750), mActivity.getBounds());
+ }
+
+ private void assertVerticalPositionForDifferentDisplayConfigsForPortraitActivity(
+ float letterboxVerticalPositionMultiplier) {
+ // Set up a display in portrait and ignoring orientation request.
+ setUpDisplaySizeWithApp(1400, 2800);
+ mActivity.mDisplayContent.setIgnoreOrientationRequest(true /* ignoreOrientationRequest */);
+
+ mActivity.mWmService.mLetterboxConfiguration.setLetterboxVerticalPositionMultiplier(
+ letterboxVerticalPositionMultiplier);
+ prepareUnresizable(mActivity, SCREEN_ORIENTATION_PORTRAIT);
assertFitted();
@@ -2375,7 +2490,7 @@ public class SizeCompatTests extends WindowTestsBase {
assertTrue(mActivity.inSizeCompatMode());
// Activity is in size compat mode but not scaled.
- assertEquals(new Rect(0, 1050, 1400, 1750), mActivity.getBounds());
+ assertEquals(new Rect(1050, 0, 1750, 1400), mActivity.getBounds());
}
private static WindowState addWindowToActivity(ActivityRecord activity) {
diff --git a/services/tests/wmtests/src/com/android/server/wm/WindowTestsBase.java b/services/tests/wmtests/src/com/android/server/wm/WindowTestsBase.java
index 9957d05d0a529..e138d52b8ef61 100644
--- a/services/tests/wmtests/src/com/android/server/wm/WindowTestsBase.java
+++ b/services/tests/wmtests/src/com/android/server/wm/WindowTestsBase.java
@@ -229,14 +229,22 @@ class WindowTestsBase extends SystemServiceTestsBase {
// {@link com.android.internal.R.dimen.config_fixedOrientationLetterboxAspectRatio}, is set
// on some device form factors.
mAtm.mWindowManager.mLetterboxConfiguration.setFixedOrientationLetterboxAspectRatio(0);
- // Ensure letterbox position multiplier is not overridden on any device target.
+ // Ensure letterbox horizontal position multiplier is not overridden on any device target.
// {@link com.android.internal.R.dimen.config_letterboxHorizontalPositionMultiplier},
// may be set on some device form factors.
mAtm.mWindowManager.mLetterboxConfiguration.setLetterboxHorizontalPositionMultiplier(0.5f);
- // Ensure letterbox reachability treatment isn't overridden on any device target.
- // {@link com.android.internal.R.bool.config_letterboxIsReachabilityEnabled},
+ // Ensure letterbox vertical position multiplier is not overridden on any device target.
+ // {@link com.android.internal.R.dimen.config_letterboxHorizontalPositionMultiplier},
// may be set on some device form factors.
- mAtm.mWindowManager.mLetterboxConfiguration.setIsReachabilityEnabled(false);
+ mAtm.mWindowManager.mLetterboxConfiguration.setLetterboxVerticalPositionMultiplier(0.5f);
+ // Ensure letterbox horizontal reachability treatment isn't overridden on any device target.
+ // {@link com.android.internal.R.bool.config_letterboxIsHorizontalReachabilityEnabled},
+ // may be set on some device form factors.
+ mAtm.mWindowManager.mLetterboxConfiguration.setIsHorizontalReachabilityEnabled(false);
+ // Ensure letterbox vertical reachability treatment isn't overridden on any device target.
+ // {@link com.android.internal.R.bool.config_letterboxIsVerticalReachabilityEnabled},
+ // may be set on some device form factors.
+ mAtm.mWindowManager.mLetterboxConfiguration.setIsVerticalReachabilityEnabled(false);
checkDeviceSpecificOverridesNotApplied();
}
@@ -246,7 +254,8 @@ class WindowTestsBase extends SystemServiceTestsBase {
// Revert back to device overrides.
mAtm.mWindowManager.mLetterboxConfiguration.resetFixedOrientationLetterboxAspectRatio();
mAtm.mWindowManager.mLetterboxConfiguration.resetLetterboxHorizontalPositionMultiplier();
- mAtm.mWindowManager.mLetterboxConfiguration.resetIsReachabilityEnabled();
+ mAtm.mWindowManager.mLetterboxConfiguration.resetIsHorizontalReachabilityEnabled();
+ mAtm.mWindowManager.mLetterboxConfiguration.resetIsVerticalReachabilityEnabled();
}
/**