Merge "Fix Letterboxing for Transparent Activities" into tm-qpr-dev
This commit is contained in:
committed by
Android (Google) Code Review
commit
86c6d900c6
@@ -5300,6 +5300,10 @@
|
|||||||
<!-- Whether using split screen aspect ratio as a default aspect ratio for unresizable apps. -->
|
<!-- Whether using split screen aspect ratio as a default aspect ratio for unresizable apps. -->
|
||||||
<bool name="config_letterboxIsSplitScreenAspectRatioForUnresizableAppsEnabled">false</bool>
|
<bool name="config_letterboxIsSplitScreenAspectRatioForUnresizableAppsEnabled">false</bool>
|
||||||
|
|
||||||
|
<!-- Whether the specific behaviour for translucent activities letterboxing is enabled.
|
||||||
|
TODO(b/255532890) Enable when ignoreOrientationRequest is set -->
|
||||||
|
<bool name="config_letterboxIsEnabledForTranslucentActivities">false</bool>
|
||||||
|
|
||||||
<!-- Whether a camera compat controller is enabled to allow the user to apply or revert
|
<!-- Whether a camera compat controller is enabled to allow the user to apply or revert
|
||||||
treatment for stretched issues in camera viewfinder. -->
|
treatment for stretched issues in camera viewfinder. -->
|
||||||
<bool name="config_isCameraCompatControlForStretchedIssuesEnabled">false</bool>
|
<bool name="config_isCameraCompatControlForStretchedIssuesEnabled">false</bool>
|
||||||
|
|||||||
@@ -4401,6 +4401,9 @@
|
|||||||
<!-- Set to true to make assistant show in front of the dream/screensaver. -->
|
<!-- Set to true to make assistant show in front of the dream/screensaver. -->
|
||||||
<java-symbol type="bool" name="config_assistantOnTopOfDream"/>
|
<java-symbol type="bool" name="config_assistantOnTopOfDream"/>
|
||||||
|
|
||||||
|
<!-- Set to true to enable letterboxing on translucent activities. -->
|
||||||
|
<java-symbol type="bool" name="config_letterboxIsEnabledForTranslucentActivities" />
|
||||||
|
|
||||||
<java-symbol type="string" name="config_overrideComponentUiPackage" />
|
<java-symbol type="string" name="config_overrideComponentUiPackage" />
|
||||||
|
|
||||||
<java-symbol type="string" name="notification_channel_network_status" />
|
<java-symbol type="string" name="notification_channel_network_status" />
|
||||||
|
|||||||
@@ -1239,8 +1239,8 @@ final class ActivityRecord extends WindowToken implements WindowManagerService.A
|
|||||||
pw.println(prefix + "supportsEnterPipOnTaskSwitch: "
|
pw.println(prefix + "supportsEnterPipOnTaskSwitch: "
|
||||||
+ supportsEnterPipOnTaskSwitch);
|
+ supportsEnterPipOnTaskSwitch);
|
||||||
}
|
}
|
||||||
if (info.getMaxAspectRatio() != 0) {
|
if (getMaxAspectRatio() != 0) {
|
||||||
pw.println(prefix + "maxAspectRatio=" + info.getMaxAspectRatio());
|
pw.println(prefix + "maxAspectRatio=" + getMaxAspectRatio());
|
||||||
}
|
}
|
||||||
final float minAspectRatio = getMinAspectRatio();
|
final float minAspectRatio = getMinAspectRatio();
|
||||||
if (minAspectRatio != 0) {
|
if (minAspectRatio != 0) {
|
||||||
@@ -1590,6 +1590,7 @@ final class ActivityRecord extends WindowToken implements WindowManagerService.A
|
|||||||
newParent.setResumedActivity(this, "onParentChanged");
|
newParent.setResumedActivity(this, "onParentChanged");
|
||||||
mImeInsetsFrozenUntilStartInput = false;
|
mImeInsetsFrozenUntilStartInput = false;
|
||||||
}
|
}
|
||||||
|
mLetterboxUiController.onActivityParentChanged(newParent);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (rootTask != null && rootTask.topRunningActivity() == this) {
|
if (rootTask != null && rootTask.topRunningActivity() == this) {
|
||||||
@@ -7682,6 +7683,15 @@ final class ActivityRecord extends WindowToken implements WindowManagerService.A
|
|||||||
@Configuration.Orientation
|
@Configuration.Orientation
|
||||||
@Override
|
@Override
|
||||||
int getRequestedConfigurationOrientation(boolean forDisplay) {
|
int getRequestedConfigurationOrientation(boolean forDisplay) {
|
||||||
|
if (mLetterboxUiController.hasInheritedOrientation()) {
|
||||||
|
final RootDisplayArea root = getRootDisplayArea();
|
||||||
|
if (forDisplay && root != null && root.isOrientationDifferentFromDisplay()) {
|
||||||
|
return ActivityInfo.reverseOrientation(
|
||||||
|
mLetterboxUiController.getInheritedOrientation());
|
||||||
|
} else {
|
||||||
|
return mLetterboxUiController.getInheritedOrientation();
|
||||||
|
}
|
||||||
|
}
|
||||||
if (mOrientation == SCREEN_ORIENTATION_BEHIND && task != null) {
|
if (mOrientation == SCREEN_ORIENTATION_BEHIND && task != null) {
|
||||||
// We use Task here because we want to be consistent with what happens in
|
// We use Task here because we want to be consistent with what happens in
|
||||||
// multi-window mode where other tasks orientations are ignored.
|
// multi-window mode where other tasks orientations are ignored.
|
||||||
@@ -7809,6 +7819,9 @@ final class ActivityRecord extends WindowToken implements WindowManagerService.A
|
|||||||
|
|
||||||
@Nullable
|
@Nullable
|
||||||
CompatDisplayInsets getCompatDisplayInsets() {
|
CompatDisplayInsets getCompatDisplayInsets() {
|
||||||
|
if (mLetterboxUiController.hasInheritedLetterboxBehavior()) {
|
||||||
|
return mLetterboxUiController.getInheritedCompatDisplayInsets();
|
||||||
|
}
|
||||||
return mCompatDisplayInsets;
|
return mCompatDisplayInsets;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -7891,6 +7904,10 @@ final class ActivityRecord extends WindowToken implements WindowManagerService.A
|
|||||||
|
|
||||||
// TODO(b/36505427): Consider moving this method and similar ones to ConfigurationContainer.
|
// TODO(b/36505427): Consider moving this method and similar ones to ConfigurationContainer.
|
||||||
private void updateCompatDisplayInsets() {
|
private void updateCompatDisplayInsets() {
|
||||||
|
if (mLetterboxUiController.hasInheritedLetterboxBehavior()) {
|
||||||
|
mCompatDisplayInsets = mLetterboxUiController.getInheritedCompatDisplayInsets();
|
||||||
|
return;
|
||||||
|
}
|
||||||
if (mCompatDisplayInsets != null || !shouldCreateCompatDisplayInsets()) {
|
if (mCompatDisplayInsets != null || !shouldCreateCompatDisplayInsets()) {
|
||||||
// The override configuration is set only once in size compatibility mode.
|
// The override configuration is set only once in size compatibility mode.
|
||||||
return;
|
return;
|
||||||
@@ -7952,6 +7969,9 @@ final class ActivityRecord extends WindowToken implements WindowManagerService.A
|
|||||||
|
|
||||||
@Override
|
@Override
|
||||||
float getCompatScale() {
|
float getCompatScale() {
|
||||||
|
if (mLetterboxUiController.hasInheritedLetterboxBehavior()) {
|
||||||
|
return mLetterboxUiController.getInheritedSizeCompatScale();
|
||||||
|
}
|
||||||
return hasSizeCompatBounds() ? mSizeCompatScale : super.getCompatScale();
|
return hasSizeCompatBounds() ? mSizeCompatScale : super.getCompatScale();
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -8060,6 +8080,16 @@ final class ActivityRecord extends WindowToken implements WindowManagerService.A
|
|||||||
logAppCompatState();
|
logAppCompatState();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @return The orientation to use to understand if reachability is enabled.
|
||||||
|
*/
|
||||||
|
@ActivityInfo.ScreenOrientation
|
||||||
|
int getOrientationForReachability() {
|
||||||
|
return mLetterboxUiController.hasInheritedLetterboxBehavior()
|
||||||
|
? mLetterboxUiController.getInheritedOrientation()
|
||||||
|
: getRequestedConfigurationOrientation();
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Returns whether activity bounds are letterboxed.
|
* Returns whether activity bounds are letterboxed.
|
||||||
*
|
*
|
||||||
@@ -8100,6 +8130,10 @@ final class ActivityRecord extends WindowToken implements WindowManagerService.A
|
|||||||
if (!ignoreVisibility && !mVisibleRequested) {
|
if (!ignoreVisibility && !mVisibleRequested) {
|
||||||
return APP_COMPAT_STATE_CHANGED__STATE__NOT_VISIBLE;
|
return APP_COMPAT_STATE_CHANGED__STATE__NOT_VISIBLE;
|
||||||
}
|
}
|
||||||
|
// TODO(b/256564921): Investigate if we need new metrics for translucent activities
|
||||||
|
if (mLetterboxUiController.hasInheritedLetterboxBehavior()) {
|
||||||
|
return mLetterboxUiController.getInheritedAppCompatState();
|
||||||
|
}
|
||||||
if (mInSizeCompatModeForBounds) {
|
if (mInSizeCompatModeForBounds) {
|
||||||
return APP_COMPAT_STATE_CHANGED__STATE__LETTERBOXED_FOR_SIZE_COMPAT_MODE;
|
return APP_COMPAT_STATE_CHANGED__STATE__LETTERBOXED_FOR_SIZE_COMPAT_MODE;
|
||||||
}
|
}
|
||||||
@@ -8570,6 +8604,11 @@ final class ActivityRecord extends WindowToken implements WindowManagerService.A
|
|||||||
}
|
}
|
||||||
|
|
||||||
private boolean isInSizeCompatModeForBounds(final Rect appBounds, final Rect containerBounds) {
|
private boolean isInSizeCompatModeForBounds(final Rect appBounds, final Rect containerBounds) {
|
||||||
|
if (mLetterboxUiController.hasInheritedLetterboxBehavior()) {
|
||||||
|
// To avoid wrong app behaviour, we decided to disable SCM when a translucent activity
|
||||||
|
// is letterboxed.
|
||||||
|
return false;
|
||||||
|
}
|
||||||
final int appWidth = appBounds.width();
|
final int appWidth = appBounds.width();
|
||||||
final int appHeight = appBounds.height();
|
final int appHeight = appBounds.height();
|
||||||
final int containerAppWidth = containerBounds.width();
|
final int containerAppWidth = containerBounds.width();
|
||||||
@@ -8590,10 +8629,11 @@ final class ActivityRecord extends WindowToken implements WindowManagerService.A
|
|||||||
|
|
||||||
// The rest of the condition is that only one side is smaller than the container, but it
|
// The rest of the condition is that only one side is smaller than the container, but it
|
||||||
// still needs to exclude the cases where the size is limited by the fixed aspect ratio.
|
// still needs to exclude the cases where the size is limited by the fixed aspect ratio.
|
||||||
if (info.getMaxAspectRatio() > 0) {
|
final float maxAspectRatio = getMaxAspectRatio();
|
||||||
|
if (maxAspectRatio > 0) {
|
||||||
final float aspectRatio = (0.5f + Math.max(appWidth, appHeight))
|
final float aspectRatio = (0.5f + Math.max(appWidth, appHeight))
|
||||||
/ Math.min(appWidth, appHeight);
|
/ Math.min(appWidth, appHeight);
|
||||||
if (aspectRatio >= info.getMaxAspectRatio()) {
|
if (aspectRatio >= maxAspectRatio) {
|
||||||
// The current size has reached the max aspect ratio.
|
// The current size has reached the max aspect ratio.
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
@@ -8815,7 +8855,7 @@ final class ActivityRecord extends WindowToken implements WindowManagerService.A
|
|||||||
// TODO(b/36505427): Consider moving this method and similar ones to ConfigurationContainer.
|
// TODO(b/36505427): Consider moving this method and similar ones to ConfigurationContainer.
|
||||||
private boolean applyAspectRatio(Rect outBounds, Rect containingAppBounds,
|
private boolean applyAspectRatio(Rect outBounds, Rect containingAppBounds,
|
||||||
Rect containingBounds, float desiredAspectRatio) {
|
Rect containingBounds, float desiredAspectRatio) {
|
||||||
final float maxAspectRatio = info.getMaxAspectRatio();
|
final float maxAspectRatio = getMaxAspectRatio();
|
||||||
final Task rootTask = getRootTask();
|
final Task rootTask = getRootTask();
|
||||||
final float minAspectRatio = getMinAspectRatio();
|
final float minAspectRatio = getMinAspectRatio();
|
||||||
final TaskFragment organizedTf = getOrganizedTaskFragment();
|
final TaskFragment organizedTf = getOrganizedTaskFragment();
|
||||||
@@ -8922,6 +8962,9 @@ final class ActivityRecord extends WindowToken implements WindowManagerService.A
|
|||||||
* Returns the min aspect ratio of this activity.
|
* Returns the min aspect ratio of this activity.
|
||||||
*/
|
*/
|
||||||
float getMinAspectRatio() {
|
float getMinAspectRatio() {
|
||||||
|
if (mLetterboxUiController.hasInheritedLetterboxBehavior()) {
|
||||||
|
return mLetterboxUiController.getInheritedMinAspectRatio();
|
||||||
|
}
|
||||||
if (info.applicationInfo == null) {
|
if (info.applicationInfo == null) {
|
||||||
return info.getMinAspectRatio();
|
return info.getMinAspectRatio();
|
||||||
}
|
}
|
||||||
@@ -8966,11 +9009,18 @@ final class ActivityRecord extends WindowToken implements WindowManagerService.A
|
|||||||
&& parent.getWindowConfiguration().getWindowingMode() == WINDOWING_MODE_FULLSCREEN;
|
&& parent.getWindowConfiguration().getWindowingMode() == WINDOWING_MODE_FULLSCREEN;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
float getMaxAspectRatio() {
|
||||||
|
if (mLetterboxUiController.hasInheritedLetterboxBehavior()) {
|
||||||
|
return mLetterboxUiController.getInheritedMaxAspectRatio();
|
||||||
|
}
|
||||||
|
return info.getMaxAspectRatio();
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Returns true if the activity has maximum or minimum aspect ratio.
|
* Returns true if the activity has maximum or minimum aspect ratio.
|
||||||
*/
|
*/
|
||||||
private boolean hasFixedAspectRatio() {
|
private boolean hasFixedAspectRatio() {
|
||||||
return info.getMaxAspectRatio() != 0 || getMinAspectRatio() != 0;
|
return getMaxAspectRatio() != 0 || getMinAspectRatio() != 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|||||||
@@ -21,6 +21,7 @@ import android.annotation.NonNull;
|
|||||||
import android.annotation.Nullable;
|
import android.annotation.Nullable;
|
||||||
import android.content.Context;
|
import android.content.Context;
|
||||||
import android.graphics.Color;
|
import android.graphics.Color;
|
||||||
|
import android.provider.DeviceConfig;
|
||||||
|
|
||||||
import com.android.internal.R;
|
import com.android.internal.R;
|
||||||
import com.android.internal.annotations.VisibleForTesting;
|
import com.android.internal.annotations.VisibleForTesting;
|
||||||
@@ -103,6 +104,10 @@ final class LetterboxConfiguration {
|
|||||||
|
|
||||||
final Context mContext;
|
final Context mContext;
|
||||||
|
|
||||||
|
// Responsible for the persistence of letterbox[Horizontal|Vertical]PositionMultiplier
|
||||||
|
@NonNull
|
||||||
|
private final LetterboxConfigurationPersister mLetterboxConfigurationPersister;
|
||||||
|
|
||||||
// Aspect ratio of letterbox for fixed orientation, values <=
|
// Aspect ratio of letterbox for fixed orientation, values <=
|
||||||
// MIN_FIXED_ORIENTATION_LETTERBOX_ASPECT_RATIO will be ignored.
|
// MIN_FIXED_ORIENTATION_LETTERBOX_ASPECT_RATIO will be ignored.
|
||||||
private float mFixedOrientationLetterboxAspectRatio;
|
private float mFixedOrientationLetterboxAspectRatio;
|
||||||
@@ -165,9 +170,12 @@ final class LetterboxConfiguration {
|
|||||||
// Whether using split screen aspect ratio as a default aspect ratio for unresizable apps.
|
// Whether using split screen aspect ratio as a default aspect ratio for unresizable apps.
|
||||||
private boolean mIsSplitScreenAspectRatioForUnresizableAppsEnabled;
|
private boolean mIsSplitScreenAspectRatioForUnresizableAppsEnabled;
|
||||||
|
|
||||||
// Responsible for the persistence of letterbox[Horizontal|Vertical]PositionMultiplier
|
// Whether letterboxing strategy is enabled for translucent activities. If {@value false}
|
||||||
@NonNull
|
// all the feature is disabled
|
||||||
private final LetterboxConfigurationPersister mLetterboxConfigurationPersister;
|
private boolean mTranslucentLetterboxingEnabled;
|
||||||
|
|
||||||
|
// Allows to enable letterboxing strategy for translucent activities ignoring flags.
|
||||||
|
private boolean mTranslucentLetterboxingOverrideEnabled;
|
||||||
|
|
||||||
LetterboxConfiguration(Context systemUiContext) {
|
LetterboxConfiguration(Context systemUiContext) {
|
||||||
this(systemUiContext, new LetterboxConfigurationPersister(systemUiContext,
|
this(systemUiContext, new LetterboxConfigurationPersister(systemUiContext,
|
||||||
@@ -206,6 +214,8 @@ final class LetterboxConfiguration {
|
|||||||
R.dimen.config_letterboxDefaultMinAspectRatioForUnresizableApps));
|
R.dimen.config_letterboxDefaultMinAspectRatioForUnresizableApps));
|
||||||
mIsSplitScreenAspectRatioForUnresizableAppsEnabled = mContext.getResources().getBoolean(
|
mIsSplitScreenAspectRatioForUnresizableAppsEnabled = mContext.getResources().getBoolean(
|
||||||
R.bool.config_letterboxIsSplitScreenAspectRatioForUnresizableAppsEnabled);
|
R.bool.config_letterboxIsSplitScreenAspectRatioForUnresizableAppsEnabled);
|
||||||
|
mTranslucentLetterboxingEnabled = mContext.getResources().getBoolean(
|
||||||
|
R.bool.config_letterboxIsEnabledForTranslucentActivities);
|
||||||
mLetterboxConfigurationPersister = letterboxConfigurationPersister;
|
mLetterboxConfigurationPersister = letterboxConfigurationPersister;
|
||||||
mLetterboxConfigurationPersister.start();
|
mLetterboxConfigurationPersister.start();
|
||||||
}
|
}
|
||||||
@@ -817,6 +827,32 @@ final class LetterboxConfiguration {
|
|||||||
R.bool.config_letterboxIsSplitScreenAspectRatioForUnresizableAppsEnabled);
|
R.bool.config_letterboxIsSplitScreenAspectRatioForUnresizableAppsEnabled);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
boolean isTranslucentLetterboxingEnabled() {
|
||||||
|
return mTranslucentLetterboxingOverrideEnabled || (mTranslucentLetterboxingEnabled
|
||||||
|
&& isTranslucentLetterboxingAllowed());
|
||||||
|
}
|
||||||
|
|
||||||
|
void setTranslucentLetterboxingEnabled(boolean translucentLetterboxingEnabled) {
|
||||||
|
mTranslucentLetterboxingEnabled = translucentLetterboxingEnabled;
|
||||||
|
}
|
||||||
|
|
||||||
|
void setTranslucentLetterboxingOverrideEnabled(
|
||||||
|
boolean translucentLetterboxingOverrideEnabled) {
|
||||||
|
mTranslucentLetterboxingOverrideEnabled = translucentLetterboxingOverrideEnabled;
|
||||||
|
setTranslucentLetterboxingEnabled(translucentLetterboxingOverrideEnabled);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Resets whether we use the constraints override strategy for letterboxing when dealing
|
||||||
|
* with translucent activities {@link R.bool.config_letterboxIsEnabledForTranslucentActivities}.
|
||||||
|
*/
|
||||||
|
void resetTranslucentLetterboxingEnabled() {
|
||||||
|
final boolean newValue = mContext.getResources().getBoolean(
|
||||||
|
R.bool.config_letterboxIsEnabledForTranslucentActivities);
|
||||||
|
setTranslucentLetterboxingEnabled(newValue);
|
||||||
|
setTranslucentLetterboxingOverrideEnabled(false);
|
||||||
|
}
|
||||||
|
|
||||||
/** Calculates a new letterboxPositionForHorizontalReachability value and updates the store */
|
/** Calculates a new letterboxPositionForHorizontalReachability value and updates the store */
|
||||||
private void updatePositionForHorizontalReachability(
|
private void updatePositionForHorizontalReachability(
|
||||||
Function<Integer, Integer> newHorizonalPositionFun) {
|
Function<Integer, Integer> newHorizonalPositionFun) {
|
||||||
@@ -839,4 +875,9 @@ final class LetterboxConfiguration {
|
|||||||
nextVerticalPosition);
|
nextVerticalPosition);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// TODO(b/262378106): Cache runtime flag and implement DeviceConfig.OnPropertiesChangedListener
|
||||||
|
static boolean isTranslucentLetterboxingAllowed() {
|
||||||
|
return DeviceConfig.getBoolean(DeviceConfig.NAMESPACE_WINDOW_MANAGER,
|
||||||
|
"enable_translucent_activity_letterbox", false);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -17,6 +17,7 @@
|
|||||||
package com.android.server.wm;
|
package com.android.server.wm;
|
||||||
|
|
||||||
import static android.app.WindowConfiguration.WINDOWING_MODE_FULLSCREEN;
|
import static android.app.WindowConfiguration.WINDOWING_MODE_FULLSCREEN;
|
||||||
|
import static android.content.pm.ActivityInfo.SCREEN_ORIENTATION_UNSPECIFIED;
|
||||||
import static android.content.res.Configuration.ORIENTATION_LANDSCAPE;
|
import static android.content.res.Configuration.ORIENTATION_LANDSCAPE;
|
||||||
import static android.content.res.Configuration.ORIENTATION_PORTRAIT;
|
import static android.content.res.Configuration.ORIENTATION_PORTRAIT;
|
||||||
import static android.view.WindowManager.LayoutParams.FLAG_SHOW_WALLPAPER;
|
import static android.view.WindowManager.LayoutParams.FLAG_SHOW_WALLPAPER;
|
||||||
@@ -27,6 +28,7 @@ import static com.android.internal.util.FrameworkStatsLog.APP_COMPAT_STATE_CHANG
|
|||||||
import static com.android.internal.util.FrameworkStatsLog.APP_COMPAT_STATE_CHANGED__LETTERBOX_POSITION__RIGHT;
|
import static com.android.internal.util.FrameworkStatsLog.APP_COMPAT_STATE_CHANGED__LETTERBOX_POSITION__RIGHT;
|
||||||
import static com.android.internal.util.FrameworkStatsLog.APP_COMPAT_STATE_CHANGED__LETTERBOX_POSITION__TOP;
|
import static com.android.internal.util.FrameworkStatsLog.APP_COMPAT_STATE_CHANGED__LETTERBOX_POSITION__TOP;
|
||||||
import static com.android.internal.util.FrameworkStatsLog.APP_COMPAT_STATE_CHANGED__LETTERBOX_POSITION__UNKNOWN_POSITION;
|
import static com.android.internal.util.FrameworkStatsLog.APP_COMPAT_STATE_CHANGED__LETTERBOX_POSITION__UNKNOWN_POSITION;
|
||||||
|
import static com.android.internal.util.FrameworkStatsLog.APP_COMPAT_STATE_CHANGED__STATE__UNKNOWN;
|
||||||
import static com.android.internal.util.FrameworkStatsLog.LETTERBOX_POSITION_CHANGED__POSITION_CHANGE__BOTTOM_TO_CENTER;
|
import static com.android.internal.util.FrameworkStatsLog.LETTERBOX_POSITION_CHANGED__POSITION_CHANGE__BOTTOM_TO_CENTER;
|
||||||
import static com.android.internal.util.FrameworkStatsLog.LETTERBOX_POSITION_CHANGED__POSITION_CHANGE__CENTER_TO_BOTTOM;
|
import static com.android.internal.util.FrameworkStatsLog.LETTERBOX_POSITION_CHANGED__POSITION_CHANGE__CENTER_TO_BOTTOM;
|
||||||
import static com.android.internal.util.FrameworkStatsLog.LETTERBOX_POSITION_CHANGED__POSITION_CHANGE__CENTER_TO_LEFT;
|
import static com.android.internal.util.FrameworkStatsLog.LETTERBOX_POSITION_CHANGED__POSITION_CHANGE__CENTER_TO_LEFT;
|
||||||
@@ -82,13 +84,44 @@ final class LetterboxUiController {
|
|||||||
|
|
||||||
private static final String TAG = TAG_WITH_CLASS_NAME ? "LetterboxUiController" : TAG_ATM;
|
private static final String TAG = TAG_WITH_CLASS_NAME ? "LetterboxUiController" : TAG_ATM;
|
||||||
|
|
||||||
|
private static final float UNDEFINED_ASPECT_RATIO = 0f;
|
||||||
|
|
||||||
private final Point mTmpPoint = new Point();
|
private final Point mTmpPoint = new Point();
|
||||||
|
|
||||||
private final LetterboxConfiguration mLetterboxConfiguration;
|
private final LetterboxConfiguration mLetterboxConfiguration;
|
||||||
|
|
||||||
private final ActivityRecord mActivityRecord;
|
private final ActivityRecord mActivityRecord;
|
||||||
|
|
||||||
|
/*
|
||||||
|
* WindowContainerListener responsible to make translucent activities inherit
|
||||||
|
* constraints from the first opaque activity beneath them. It's null for not
|
||||||
|
* translucent activities.
|
||||||
|
*/
|
||||||
|
@Nullable
|
||||||
|
private WindowContainerListener mLetterboxConfigListener;
|
||||||
|
|
||||||
private boolean mShowWallpaperForLetterboxBackground;
|
private boolean mShowWallpaperForLetterboxBackground;
|
||||||
|
|
||||||
|
// In case of transparent activities we might need to access the aspectRatio of the
|
||||||
|
// first opaque activity beneath.
|
||||||
|
private float mInheritedMinAspectRatio = UNDEFINED_ASPECT_RATIO;
|
||||||
|
private float mInheritedMaxAspectRatio = UNDEFINED_ASPECT_RATIO;
|
||||||
|
|
||||||
|
@Configuration.Orientation
|
||||||
|
private int mInheritedOrientation = Configuration.ORIENTATION_UNDEFINED;
|
||||||
|
|
||||||
|
// The app compat state for the opaque activity if any
|
||||||
|
private int mInheritedAppCompatState = APP_COMPAT_STATE_CHANGED__STATE__UNKNOWN;
|
||||||
|
|
||||||
|
// If true it means that the opaque activity beneath a translucent one is in SizeCompatMode.
|
||||||
|
private boolean mIsInheritedInSizeCompatMode;
|
||||||
|
|
||||||
|
// This is the SizeCompatScale of the opaque activity beneath a translucent one
|
||||||
|
private float mInheritedSizeCompatScale;
|
||||||
|
|
||||||
|
// The CompatDisplayInsets of the opaque activity beneath the translucent one.
|
||||||
|
private ActivityRecord.CompatDisplayInsets mInheritedCompatDisplayInsets;
|
||||||
|
|
||||||
@Nullable
|
@Nullable
|
||||||
private Letterbox mLetterbox;
|
private Letterbox mLetterbox;
|
||||||
|
|
||||||
@@ -220,7 +253,9 @@ final class LetterboxUiController {
|
|||||||
: mActivityRecord.inMultiWindowMode()
|
: mActivityRecord.inMultiWindowMode()
|
||||||
? mActivityRecord.getTask().getBounds()
|
? mActivityRecord.getTask().getBounds()
|
||||||
: mActivityRecord.getRootTask().getParent().getBounds();
|
: mActivityRecord.getRootTask().getParent().getBounds();
|
||||||
mLetterbox.layout(spaceToFill, w.getFrame(), mTmpPoint);
|
final Rect innerFrame = hasInheritedLetterboxBehavior()
|
||||||
|
? mActivityRecord.getWindowConfiguration().getBounds() : w.getFrame();
|
||||||
|
mLetterbox.layout(spaceToFill, innerFrame, mTmpPoint);
|
||||||
} else if (mLetterbox != null) {
|
} else if (mLetterbox != null) {
|
||||||
mLetterbox.hide();
|
mLetterbox.hide();
|
||||||
}
|
}
|
||||||
@@ -305,7 +340,9 @@ final class LetterboxUiController {
|
|||||||
}
|
}
|
||||||
|
|
||||||
private void handleHorizontalDoubleTap(int x) {
|
private void handleHorizontalDoubleTap(int x) {
|
||||||
if (!isHorizontalReachabilityEnabled() || mActivityRecord.isInTransition()) {
|
// TODO(b/260857308): Investigate if enabling reachability for translucent activity
|
||||||
|
if (hasInheritedLetterboxBehavior() || !isHorizontalReachabilityEnabled()
|
||||||
|
|| mActivityRecord.isInTransition()) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -341,7 +378,9 @@ final class LetterboxUiController {
|
|||||||
}
|
}
|
||||||
|
|
||||||
private void handleVerticalDoubleTap(int y) {
|
private void handleVerticalDoubleTap(int y) {
|
||||||
if (!isVerticalReachabilityEnabled() || mActivityRecord.isInTransition()) {
|
// TODO(b/260857308): Investigate if enabling reachability for translucent activity
|
||||||
|
if (hasInheritedLetterboxBehavior() || !isVerticalReachabilityEnabled()
|
||||||
|
|| mActivityRecord.isInTransition()) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -390,7 +429,7 @@ final class LetterboxUiController {
|
|||||||
&& parentConfiguration.windowConfiguration.getWindowingMode()
|
&& parentConfiguration.windowConfiguration.getWindowingMode()
|
||||||
== WINDOWING_MODE_FULLSCREEN
|
== WINDOWING_MODE_FULLSCREEN
|
||||||
&& (parentConfiguration.orientation == ORIENTATION_LANDSCAPE
|
&& (parentConfiguration.orientation == ORIENTATION_LANDSCAPE
|
||||||
&& mActivityRecord.getRequestedConfigurationOrientation() == ORIENTATION_PORTRAIT);
|
&& mActivityRecord.getOrientationForReachability() == ORIENTATION_PORTRAIT);
|
||||||
}
|
}
|
||||||
|
|
||||||
private boolean isHorizontalReachabilityEnabled() {
|
private boolean isHorizontalReachabilityEnabled() {
|
||||||
@@ -412,7 +451,7 @@ final class LetterboxUiController {
|
|||||||
&& parentConfiguration.windowConfiguration.getWindowingMode()
|
&& parentConfiguration.windowConfiguration.getWindowingMode()
|
||||||
== WINDOWING_MODE_FULLSCREEN
|
== WINDOWING_MODE_FULLSCREEN
|
||||||
&& (parentConfiguration.orientation == ORIENTATION_PORTRAIT
|
&& (parentConfiguration.orientation == ORIENTATION_PORTRAIT
|
||||||
&& mActivityRecord.getRequestedConfigurationOrientation() == ORIENTATION_LANDSCAPE);
|
&& mActivityRecord.getOrientationForReachability() == ORIENTATION_LANDSCAPE);
|
||||||
}
|
}
|
||||||
|
|
||||||
private boolean isVerticalReachabilityEnabled() {
|
private boolean isVerticalReachabilityEnabled() {
|
||||||
@@ -576,9 +615,7 @@ final class LetterboxUiController {
|
|||||||
// Rounded corners should be displayed above the taskbar.
|
// Rounded corners should be displayed above the taskbar.
|
||||||
bounds.bottom =
|
bounds.bottom =
|
||||||
Math.min(bounds.bottom, getTaskbarInsetsSource(mainWindow).getFrame().top);
|
Math.min(bounds.bottom, getTaskbarInsetsSource(mainWindow).getFrame().top);
|
||||||
if (mActivityRecord.inSizeCompatMode() && mActivityRecord.getCompatScale() < 1.0f) {
|
scaleIfNeeded(bounds);
|
||||||
bounds.scale(1.0f / mActivityRecord.getCompatScale());
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private int getInsetsStateCornerRadius(
|
private int getInsetsStateCornerRadius(
|
||||||
@@ -788,4 +825,144 @@ final class LetterboxUiController {
|
|||||||
w.mAttrs.insetsFlags.appearance
|
w.mAttrs.insetsFlags.appearance
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Handles translucent activities letterboxing inheriting constraints from the
|
||||||
|
* first opaque activity beneath.
|
||||||
|
* @param parent The parent container.
|
||||||
|
*/
|
||||||
|
void onActivityParentChanged(WindowContainer<?> parent) {
|
||||||
|
if (!mLetterboxConfiguration.isTranslucentLetterboxingEnabled()) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
if (mLetterboxConfigListener != null) {
|
||||||
|
mLetterboxConfigListener.onRemoved();
|
||||||
|
clearInheritedConfig();
|
||||||
|
}
|
||||||
|
// In case mActivityRecord.getCompatDisplayInsets() is not null we don't apply the
|
||||||
|
// opaque activity constraints because we're expecting the activity is already letterboxed.
|
||||||
|
if (mActivityRecord.getTask() == null || mActivityRecord.getCompatDisplayInsets() != null
|
||||||
|
|| mActivityRecord.fillsParent()) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
final ActivityRecord firstOpaqueActivityBeneath = mActivityRecord.getTask().getActivity(
|
||||||
|
ActivityRecord::fillsParent, mActivityRecord, false /* includeBoundary */,
|
||||||
|
true /* traverseTopToBottom */);
|
||||||
|
if (firstOpaqueActivityBeneath == null
|
||||||
|
|| mActivityRecord.launchedFromUid != firstOpaqueActivityBeneath.getUid()) {
|
||||||
|
// We skip letterboxing if the translucent activity doesn't have any opaque
|
||||||
|
// activities beneath of if it's launched from a different user (e.g. notification)
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
inheritConfiguration(firstOpaqueActivityBeneath);
|
||||||
|
mLetterboxConfigListener = WindowContainer.overrideConfigurationPropagation(
|
||||||
|
mActivityRecord, firstOpaqueActivityBeneath,
|
||||||
|
(opaqueConfig, transparentConfig) -> {
|
||||||
|
final Configuration mutatedConfiguration = new Configuration();
|
||||||
|
final Rect parentBounds = parent.getWindowConfiguration().getBounds();
|
||||||
|
final Rect bounds = mutatedConfiguration.windowConfiguration.getBounds();
|
||||||
|
final Rect letterboxBounds = opaqueConfig.windowConfiguration.getBounds();
|
||||||
|
// We cannot use letterboxBounds directly here because the position relies on
|
||||||
|
// letterboxing. Using letterboxBounds directly, would produce a double offset.
|
||||||
|
bounds.set(parentBounds.left, parentBounds.top,
|
||||||
|
parentBounds.left + letterboxBounds.width(),
|
||||||
|
parentBounds.top + letterboxBounds.height());
|
||||||
|
// We need to initialize appBounds to avoid NPE. The actual value will
|
||||||
|
// be set ahead when resolving the Configuration for the activity.
|
||||||
|
mutatedConfiguration.windowConfiguration.setAppBounds(new Rect());
|
||||||
|
return mutatedConfiguration;
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @return {@code true} if the current activity is translucent with an opaque activity
|
||||||
|
* beneath. In this case it will inherit bounds, orientation and aspect ratios from
|
||||||
|
* the first opaque activity beneath.
|
||||||
|
*/
|
||||||
|
boolean hasInheritedLetterboxBehavior() {
|
||||||
|
return mLetterboxConfigListener != null && !mActivityRecord.matchParentBounds();
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @return {@code true} if the current activity is translucent with an opaque activity
|
||||||
|
* beneath and needs to inherit its orientation.
|
||||||
|
*/
|
||||||
|
boolean hasInheritedOrientation() {
|
||||||
|
// To force a different orientation, the transparent one needs to have an explicit one
|
||||||
|
// otherwise the existing one is fine and the actual orientation will depend on the
|
||||||
|
// bounds.
|
||||||
|
// To avoid wrong behaviour, we're not forcing orientation for activities with not
|
||||||
|
// fixed orientation (e.g. permission dialogs).
|
||||||
|
return hasInheritedLetterboxBehavior()
|
||||||
|
&& mActivityRecord.mOrientation != SCREEN_ORIENTATION_UNSPECIFIED;
|
||||||
|
}
|
||||||
|
|
||||||
|
float getInheritedMinAspectRatio() {
|
||||||
|
return mInheritedMinAspectRatio;
|
||||||
|
}
|
||||||
|
|
||||||
|
float getInheritedMaxAspectRatio() {
|
||||||
|
return mInheritedMaxAspectRatio;
|
||||||
|
}
|
||||||
|
|
||||||
|
int getInheritedAppCompatState() {
|
||||||
|
return mInheritedAppCompatState;
|
||||||
|
}
|
||||||
|
|
||||||
|
float getInheritedSizeCompatScale() {
|
||||||
|
return mInheritedSizeCompatScale;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Configuration.Orientation
|
||||||
|
int getInheritedOrientation() {
|
||||||
|
return mInheritedOrientation;
|
||||||
|
}
|
||||||
|
|
||||||
|
public ActivityRecord.CompatDisplayInsets getInheritedCompatDisplayInsets() {
|
||||||
|
return mInheritedCompatDisplayInsets;
|
||||||
|
}
|
||||||
|
|
||||||
|
private void inheritConfiguration(ActivityRecord firstOpaque) {
|
||||||
|
// To avoid wrong behaviour, we're not forcing a specific aspet ratio to activities
|
||||||
|
// which are not already providing one (e.g. permission dialogs) and presumably also
|
||||||
|
// not resizable.
|
||||||
|
if (mActivityRecord.getMinAspectRatio() != UNDEFINED_ASPECT_RATIO) {
|
||||||
|
mInheritedMinAspectRatio = firstOpaque.getMinAspectRatio();
|
||||||
|
}
|
||||||
|
if (mActivityRecord.getMaxAspectRatio() != UNDEFINED_ASPECT_RATIO) {
|
||||||
|
mInheritedMaxAspectRatio = firstOpaque.getMaxAspectRatio();
|
||||||
|
}
|
||||||
|
mInheritedOrientation = firstOpaque.getRequestedConfigurationOrientation();
|
||||||
|
mInheritedAppCompatState = firstOpaque.getAppCompatState();
|
||||||
|
mIsInheritedInSizeCompatMode = firstOpaque.inSizeCompatMode();
|
||||||
|
mInheritedSizeCompatScale = firstOpaque.getCompatScale();
|
||||||
|
mInheritedCompatDisplayInsets = firstOpaque.getCompatDisplayInsets();
|
||||||
|
}
|
||||||
|
|
||||||
|
private void clearInheritedConfig() {
|
||||||
|
mLetterboxConfigListener = null;
|
||||||
|
mInheritedMinAspectRatio = UNDEFINED_ASPECT_RATIO;
|
||||||
|
mInheritedMaxAspectRatio = UNDEFINED_ASPECT_RATIO;
|
||||||
|
mInheritedOrientation = Configuration.ORIENTATION_UNDEFINED;
|
||||||
|
mInheritedAppCompatState = APP_COMPAT_STATE_CHANGED__STATE__UNKNOWN;
|
||||||
|
mIsInheritedInSizeCompatMode = false;
|
||||||
|
mInheritedSizeCompatScale = 1f;
|
||||||
|
mInheritedCompatDisplayInsets = null;
|
||||||
|
}
|
||||||
|
|
||||||
|
private void scaleIfNeeded(Rect bounds) {
|
||||||
|
if (boundsNeedToScale()) {
|
||||||
|
bounds.scale(1.0f / mActivityRecord.getCompatScale());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private boolean boundsNeedToScale() {
|
||||||
|
if (hasInheritedLetterboxBehavior()) {
|
||||||
|
return mIsInheritedInSizeCompatMode
|
||||||
|
&& mInheritedSizeCompatScale < 1.0f;
|
||||||
|
} else {
|
||||||
|
return mActivityRecord.inSizeCompatMode()
|
||||||
|
&& mActivityRecord.getCompatScale() < 1.0f;
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -3938,27 +3938,54 @@ class WindowContainer<E extends WindowContainer> extends ConfigurationContainer<
|
|||||||
unregisterConfigurationChangeListener(listener);
|
unregisterConfigurationChangeListener(listener);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static void overrideConfigurationPropagation(WindowContainer<?> receiver,
|
||||||
|
WindowContainer<?> supplier) {
|
||||||
|
overrideConfigurationPropagation(receiver, supplier, null /* configurationMerger */);
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Forces the receiver container to always use the configuration of the supplier container as
|
* Forces the receiver container to always use the configuration of the supplier container as
|
||||||
* its requested override configuration. It allows to propagate configuration without changing
|
* its requested override configuration. It allows to propagate configuration without changing
|
||||||
* the relationship between child and parent.
|
* the relationship between child and parent.
|
||||||
|
*
|
||||||
|
* @param receiver The {@link WindowContainer<?>} which will receive the {@link
|
||||||
|
* Configuration} result of the merging operation.
|
||||||
|
* @param supplier The {@link WindowContainer<?>} which provides the initial {@link
|
||||||
|
* Configuration}.
|
||||||
|
* @param configurationMerger A {@link ConfigurationMerger} which combines the {@link
|
||||||
|
* Configuration} of the receiver and the supplier.
|
||||||
*/
|
*/
|
||||||
static void overrideConfigurationPropagation(WindowContainer<?> receiver,
|
static WindowContainerListener overrideConfigurationPropagation(WindowContainer<?> receiver,
|
||||||
WindowContainer<?> supplier) {
|
WindowContainer<?> supplier, @Nullable ConfigurationMerger configurationMerger) {
|
||||||
final ConfigurationContainerListener listener = new ConfigurationContainerListener() {
|
final ConfigurationContainerListener listener = new ConfigurationContainerListener() {
|
||||||
@Override
|
@Override
|
||||||
public void onMergedOverrideConfigurationChanged(Configuration mergedOverrideConfig) {
|
public void onMergedOverrideConfigurationChanged(Configuration mergedOverrideConfig) {
|
||||||
receiver.onRequestedOverrideConfigurationChanged(supplier.getConfiguration());
|
final Configuration mergedConfiguration =
|
||||||
|
configurationMerger != null
|
||||||
|
? configurationMerger.merge(mergedOverrideConfig,
|
||||||
|
receiver.getConfiguration())
|
||||||
|
: supplier.getConfiguration();
|
||||||
|
receiver.onRequestedOverrideConfigurationChanged(mergedConfiguration);
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
supplier.registerConfigurationChangeListener(listener);
|
supplier.registerConfigurationChangeListener(listener);
|
||||||
receiver.registerWindowContainerListener(new WindowContainerListener() {
|
final WindowContainerListener wcListener = new WindowContainerListener() {
|
||||||
@Override
|
@Override
|
||||||
public void onRemoved() {
|
public void onRemoved() {
|
||||||
receiver.unregisterWindowContainerListener(this);
|
receiver.unregisterWindowContainerListener(this);
|
||||||
supplier.unregisterConfigurationChangeListener(listener);
|
supplier.unregisterConfigurationChangeListener(listener);
|
||||||
}
|
}
|
||||||
});
|
};
|
||||||
|
receiver.registerWindowContainerListener(wcListener);
|
||||||
|
return wcListener;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Abstraction for functions merging two {@link Configuration} objects into one.
|
||||||
|
*/
|
||||||
|
@FunctionalInterface
|
||||||
|
interface ConfigurationMerger {
|
||||||
|
Configuration merge(Configuration first, Configuration second);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|||||||
@@ -963,6 +963,29 @@ public class WindowManagerShellCommand extends ShellCommand {
|
|||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private int runSetTranslucentLetterboxingEnabled(PrintWriter pw) {
|
||||||
|
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.setTranslucentLetterboxingOverrideEnabled(enabled);
|
||||||
|
}
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
private int runSetLetterboxStyle(PrintWriter pw) throws RemoteException {
|
private int runSetLetterboxStyle(PrintWriter pw) throws RemoteException {
|
||||||
if (peekNextArg() == null) {
|
if (peekNextArg() == null) {
|
||||||
getErrPrintWriter().println("Error: No arguments provided.");
|
getErrPrintWriter().println("Error: No arguments provided.");
|
||||||
@@ -1018,6 +1041,9 @@ public class WindowManagerShellCommand extends ShellCommand {
|
|||||||
case "--isSplitScreenAspectRatioForUnresizableAppsEnabled":
|
case "--isSplitScreenAspectRatioForUnresizableAppsEnabled":
|
||||||
runSetLetterboxIsSplitScreenAspectRatioForUnresizableAppsEnabled(pw);
|
runSetLetterboxIsSplitScreenAspectRatioForUnresizableAppsEnabled(pw);
|
||||||
break;
|
break;
|
||||||
|
case "--isTranslucentLetterboxingEnabled":
|
||||||
|
runSetTranslucentLetterboxingEnabled(pw);
|
||||||
|
break;
|
||||||
default:
|
default:
|
||||||
getErrPrintWriter().println(
|
getErrPrintWriter().println(
|
||||||
"Error: Unrecognized letterbox style option: " + arg);
|
"Error: Unrecognized letterbox style option: " + arg);
|
||||||
@@ -1081,6 +1107,9 @@ public class WindowManagerShellCommand extends ShellCommand {
|
|||||||
mLetterboxConfiguration
|
mLetterboxConfiguration
|
||||||
.getIsSplitScreenAspectRatioForUnresizableAppsEnabled();
|
.getIsSplitScreenAspectRatioForUnresizableAppsEnabled();
|
||||||
break;
|
break;
|
||||||
|
case "isTranslucentLetterboxingEnabled":
|
||||||
|
mLetterboxConfiguration.resetTranslucentLetterboxingEnabled();
|
||||||
|
break;
|
||||||
default:
|
default:
|
||||||
getErrPrintWriter().println(
|
getErrPrintWriter().println(
|
||||||
"Error: Unrecognized letterbox style option: " + arg);
|
"Error: Unrecognized letterbox style option: " + arg);
|
||||||
@@ -1181,6 +1210,7 @@ public class WindowManagerShellCommand extends ShellCommand {
|
|||||||
mLetterboxConfiguration.resetDefaultPositionForVerticalReachability();
|
mLetterboxConfiguration.resetDefaultPositionForVerticalReachability();
|
||||||
mLetterboxConfiguration.resetIsEducationEnabled();
|
mLetterboxConfiguration.resetIsEducationEnabled();
|
||||||
mLetterboxConfiguration.resetIsSplitScreenAspectRatioForUnresizableAppsEnabled();
|
mLetterboxConfiguration.resetIsSplitScreenAspectRatioForUnresizableAppsEnabled();
|
||||||
|
mLetterboxConfiguration.resetTranslucentLetterboxingEnabled();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -1217,7 +1247,6 @@ public class WindowManagerShellCommand extends ShellCommand {
|
|||||||
pw.println("Is using split screen aspect ratio as aspect ratio for unresizable apps: "
|
pw.println("Is using split screen aspect ratio as aspect ratio for unresizable apps: "
|
||||||
+ mLetterboxConfiguration
|
+ mLetterboxConfiguration
|
||||||
.getIsSplitScreenAspectRatioForUnresizableAppsEnabled());
|
.getIsSplitScreenAspectRatioForUnresizableAppsEnabled());
|
||||||
|
|
||||||
pw.println("Background type: "
|
pw.println("Background type: "
|
||||||
+ LetterboxConfiguration.letterboxBackgroundTypeToString(
|
+ LetterboxConfiguration.letterboxBackgroundTypeToString(
|
||||||
mLetterboxConfiguration.getLetterboxBackgroundType()));
|
mLetterboxConfiguration.getLetterboxBackgroundType()));
|
||||||
@@ -1227,6 +1256,12 @@ public class WindowManagerShellCommand extends ShellCommand {
|
|||||||
+ mLetterboxConfiguration.getLetterboxBackgroundWallpaperBlurRadius());
|
+ mLetterboxConfiguration.getLetterboxBackgroundWallpaperBlurRadius());
|
||||||
pw.println(" Wallpaper dark scrim alpha: "
|
pw.println(" Wallpaper dark scrim alpha: "
|
||||||
+ mLetterboxConfiguration.getLetterboxBackgroundWallpaperDarkScrimAlpha());
|
+ mLetterboxConfiguration.getLetterboxBackgroundWallpaperDarkScrimAlpha());
|
||||||
|
|
||||||
|
if (mLetterboxConfiguration.isTranslucentLetterboxingEnabled()) {
|
||||||
|
pw.println("Letterboxing for translucent activities: enabled");
|
||||||
|
} else {
|
||||||
|
pw.println("Letterboxing for translucent activities: disabled");
|
||||||
|
}
|
||||||
}
|
}
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
@@ -1419,12 +1454,16 @@ public class WindowManagerShellCommand extends ShellCommand {
|
|||||||
pw.println(" --isSplitScreenAspectRatioForUnresizableAppsEnabled [true|1|false|0]");
|
pw.println(" --isSplitScreenAspectRatioForUnresizableAppsEnabled [true|1|false|0]");
|
||||||
pw.println(" Whether using split screen aspect ratio as a default aspect ratio for");
|
pw.println(" Whether using split screen aspect ratio as a default aspect ratio for");
|
||||||
pw.println(" unresizable apps.");
|
pw.println(" unresizable apps.");
|
||||||
|
pw.println(" --isTranslucentLetterboxingEnabled [true|1|false|0]");
|
||||||
|
pw.println(" Whether letterboxing for translucent activities is enabled.");
|
||||||
|
|
||||||
pw.println(" reset-letterbox-style [aspectRatio|cornerRadius|backgroundType");
|
pw.println(" reset-letterbox-style [aspectRatio|cornerRadius|backgroundType");
|
||||||
pw.println(" |backgroundColor|wallpaperBlurRadius|wallpaperDarkScrimAlpha");
|
pw.println(" |backgroundColor|wallpaperBlurRadius|wallpaperDarkScrimAlpha");
|
||||||
pw.println(" |horizontalPositionMultiplier|verticalPositionMultiplier");
|
pw.println(" |horizontalPositionMultiplier|verticalPositionMultiplier");
|
||||||
pw.println(" |isHorizontalReachabilityEnabled|isVerticalReachabilityEnabled");
|
pw.println(" |isHorizontalReachabilityEnabled|isVerticalReachabilityEnabled");
|
||||||
pw.println(" isEducationEnabled||defaultPositionMultiplierForHorizontalReachability");
|
pw.println(" |isEducationEnabled||defaultPositionMultiplierForHorizontalReachability");
|
||||||
pw.println(" ||defaultPositionMultiplierForVerticalReachability]");
|
pw.println(" |isTranslucentLetterboxingEnabled");
|
||||||
|
pw.println(" |defaultPositionMultiplierForVerticalReachability]");
|
||||||
pw.println(" Resets overrides to default values for specified properties separated");
|
pw.println(" Resets overrides to default values for specified properties separated");
|
||||||
pw.println(" by space, e.g. 'reset-letterbox-style aspectRatio cornerRadius'.");
|
pw.println(" by space, e.g. 'reset-letterbox-style aspectRatio cornerRadius'.");
|
||||||
pw.println(" If no arguments provided, all values will be reset.");
|
pw.println(" If no arguments provided, all values will be reset.");
|
||||||
|
|||||||
@@ -163,6 +163,114 @@ public class SizeCompatTests extends WindowTestsBase {
|
|||||||
setUpApp(builder.build());
|
setUpApp(builder.build());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void testApplyStrategyToTranslucentActivities() {
|
||||||
|
mWm.mLetterboxConfiguration.setTranslucentLetterboxingOverrideEnabled(true);
|
||||||
|
setUpDisplaySizeWithApp(2000, 1000);
|
||||||
|
prepareUnresizable(mActivity, 1.5f /* maxAspect */, SCREEN_ORIENTATION_PORTRAIT);
|
||||||
|
mActivity.info.setMinAspectRatio(1.2f);
|
||||||
|
mActivity.mDisplayContent.setIgnoreOrientationRequest(true /* ignoreOrientationRequest */);
|
||||||
|
// Translucent Activity
|
||||||
|
final ActivityRecord translucentActivity = new ActivityBuilder(mAtm)
|
||||||
|
.setLaunchedFromUid(mActivity.getUid())
|
||||||
|
.setScreenOrientation(SCREEN_ORIENTATION_LANDSCAPE)
|
||||||
|
.setMinAspectRatio(1.1f)
|
||||||
|
.setMaxAspectRatio(3f)
|
||||||
|
.build();
|
||||||
|
doReturn(false).when(translucentActivity).fillsParent();
|
||||||
|
mTask.addChild(translucentActivity);
|
||||||
|
// We check bounds
|
||||||
|
final Rect opaqueBounds = mActivity.getConfiguration().windowConfiguration.getBounds();
|
||||||
|
final Rect translucentRequestedBounds = translucentActivity.getRequestedOverrideBounds();
|
||||||
|
assertEquals(opaqueBounds, translucentRequestedBounds);
|
||||||
|
// We check orientation
|
||||||
|
final int translucentOrientation =
|
||||||
|
translucentActivity.getRequestedConfigurationOrientation();
|
||||||
|
assertEquals(ORIENTATION_PORTRAIT, translucentOrientation);
|
||||||
|
// We check aspect ratios
|
||||||
|
assertEquals(1.2f, translucentActivity.getMinAspectRatio(), 0.00001f);
|
||||||
|
assertEquals(1.5f, translucentActivity.getMaxAspectRatio(), 0.00001f);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void testNotApplyStrategyToTranslucentActivitiesWithDifferentUid() {
|
||||||
|
mWm.mLetterboxConfiguration.setTranslucentLetterboxingOverrideEnabled(true);
|
||||||
|
setUpDisplaySizeWithApp(2000, 1000);
|
||||||
|
prepareUnresizable(mActivity, 1.5f /* maxAspect */, SCREEN_ORIENTATION_PORTRAIT);
|
||||||
|
mActivity.info.setMinAspectRatio(1.2f);
|
||||||
|
mActivity.mDisplayContent.setIgnoreOrientationRequest(true /* ignoreOrientationRequest */);
|
||||||
|
// Translucent Activity
|
||||||
|
final ActivityRecord translucentActivity = new ActivityBuilder(mAtm)
|
||||||
|
.setScreenOrientation(SCREEN_ORIENTATION_LANDSCAPE)
|
||||||
|
.setMinAspectRatio(1.1f)
|
||||||
|
.setMaxAspectRatio(3f)
|
||||||
|
.build();
|
||||||
|
doReturn(false).when(translucentActivity).fillsParent();
|
||||||
|
mTask.addChild(translucentActivity);
|
||||||
|
// We check bounds
|
||||||
|
final Rect opaqueBounds = mActivity.getConfiguration().windowConfiguration.getBounds();
|
||||||
|
final Rect translucentRequestedBounds = translucentActivity.getRequestedOverrideBounds();
|
||||||
|
assertNotEquals(opaqueBounds, translucentRequestedBounds);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void testApplyStrategyToMultipleTranslucentActivities() {
|
||||||
|
mWm.mLetterboxConfiguration.setTranslucentLetterboxingOverrideEnabled(true);
|
||||||
|
setUpDisplaySizeWithApp(2000, 1000);
|
||||||
|
prepareUnresizable(mActivity, 1.5f /* maxAspect */, SCREEN_ORIENTATION_PORTRAIT);
|
||||||
|
mActivity.info.setMinAspectRatio(1.2f);
|
||||||
|
mActivity.mDisplayContent.setIgnoreOrientationRequest(true /* ignoreOrientationRequest */);
|
||||||
|
// Translucent Activity
|
||||||
|
final ActivityRecord translucentActivity = new ActivityBuilder(mAtm)
|
||||||
|
.setLaunchedFromUid(mActivity.getUid())
|
||||||
|
.setScreenOrientation(SCREEN_ORIENTATION_LANDSCAPE)
|
||||||
|
.setMinAspectRatio(1.1f)
|
||||||
|
.setMaxAspectRatio(3f)
|
||||||
|
.build();
|
||||||
|
doReturn(false).when(translucentActivity).fillsParent();
|
||||||
|
mTask.addChild(translucentActivity);
|
||||||
|
// We check bounds
|
||||||
|
final Rect opaqueBounds = mActivity.getConfiguration().windowConfiguration.getBounds();
|
||||||
|
final Rect translucentRequestedBounds = translucentActivity.getRequestedOverrideBounds();
|
||||||
|
assertEquals(opaqueBounds, translucentRequestedBounds);
|
||||||
|
// Launch another translucent activity
|
||||||
|
final ActivityRecord translucentActivity2 = new ActivityBuilder(mAtm)
|
||||||
|
.setLaunchedFromUid(mActivity.getUid())
|
||||||
|
.setScreenOrientation(SCREEN_ORIENTATION_LANDSCAPE)
|
||||||
|
.build();
|
||||||
|
doReturn(false).when(translucentActivity2).fillsParent();
|
||||||
|
mTask.addChild(translucentActivity2);
|
||||||
|
// We check bounds
|
||||||
|
final Rect translucent2RequestedBounds = translucentActivity2.getRequestedOverrideBounds();
|
||||||
|
assertEquals(opaqueBounds, translucent2RequestedBounds);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void testTranslucentActivitiesDontGoInSizeCompactMode() {
|
||||||
|
mWm.mLetterboxConfiguration.setTranslucentLetterboxingOverrideEnabled(true);
|
||||||
|
setUpDisplaySizeWithApp(2800, 1400);
|
||||||
|
mActivity.mDisplayContent.setIgnoreOrientationRequest(true /* ignoreOrientationRequest */);
|
||||||
|
prepareUnresizable(mActivity, -1f /* maxAspect */, SCREEN_ORIENTATION_PORTRAIT);
|
||||||
|
// Rotate to put activity in size compat mode.
|
||||||
|
rotateDisplay(mActivity.mDisplayContent, ROTATION_90);
|
||||||
|
assertTrue(mActivity.inSizeCompatMode());
|
||||||
|
// Rotate back
|
||||||
|
rotateDisplay(mActivity.mDisplayContent, ROTATION_0);
|
||||||
|
assertFalse(mActivity.inSizeCompatMode());
|
||||||
|
// We launch a transparent activity
|
||||||
|
final ActivityRecord translucentActivity = new ActivityBuilder(mAtm)
|
||||||
|
.setLaunchedFromUid(mActivity.getUid())
|
||||||
|
.setScreenOrientation(SCREEN_ORIENTATION_PORTRAIT)
|
||||||
|
.build();
|
||||||
|
doReturn(true).when(translucentActivity).fillsParent();
|
||||||
|
mTask.addChild(translucentActivity);
|
||||||
|
// It should not be in SCM
|
||||||
|
assertFalse(translucentActivity.inSizeCompatMode());
|
||||||
|
// We rotate again
|
||||||
|
rotateDisplay(translucentActivity.mDisplayContent, ROTATION_90);
|
||||||
|
assertFalse(translucentActivity.inSizeCompatMode());
|
||||||
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void testRestartProcessIfVisible() {
|
public void testRestartProcessIfVisible() {
|
||||||
setUpDisplaySizeWithApp(1000, 2500);
|
setUpDisplaySizeWithApp(1000, 2500);
|
||||||
|
|||||||
Reference in New Issue
Block a user