diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/back/CrossActivityBackAnimation.kt b/libs/WindowManager/Shell/src/com/android/wm/shell/back/CrossActivityBackAnimation.kt index a3111b31a2f9912b7b116d84638e299161033e1f..c9d3dbdcae05afef2b781f05ff89a2d30ac46b2f 100644 --- a/libs/WindowManager/Shell/src/com/android/wm/shell/back/CrossActivityBackAnimation.kt +++ b/libs/WindowManager/Shell/src/com/android/wm/shell/back/CrossActivityBackAnimation.kt @@ -324,6 +324,7 @@ abstract class CrossActivityBackAnimation( enteringHasSameLetterbox = false lastPostCommitFlingScale = SPRING_SCALE gestureProgress = 0f + triggerBack = false } protected fun applyTransform( @@ -499,10 +500,12 @@ abstract class CrossActivityBackAnimation( } override fun onBackCancelled() { + triggerBack = false progressAnimator.onBackCancelled { finishAnimation() } } override fun onBackInvoked() { + triggerBack = true progressAnimator.reset() onGestureCommitted(progressAnimator.velocity) } diff --git a/services/core/java/com/android/server/wm/ActivityRecord.java b/services/core/java/com/android/server/wm/ActivityRecord.java index 8f0517435aed4408fa1579112285357904ed05a7..de16683f2d77c208fefe14fd5c7c7d2b51fc2ece 100644 --- a/services/core/java/com/android/server/wm/ActivityRecord.java +++ b/services/core/java/com/android/server/wm/ActivityRecord.java @@ -53,7 +53,6 @@ import static android.app.WindowConfiguration.WINDOWING_MODE_MULTI_WINDOW; import static android.app.WindowConfiguration.WINDOWING_MODE_PINNED; import static android.app.WindowConfiguration.WINDOWING_MODE_UNDEFINED; import static android.app.WindowConfiguration.activityTypeToString; -import static android.app.WindowConfiguration.isFloating; import static android.app.admin.DevicePolicyResources.Drawables.Source.PROFILE_SWITCH_ANIMATION; import static android.app.admin.DevicePolicyResources.Drawables.Style.OUTLINE; import static android.app.admin.DevicePolicyResources.Drawables.WORK_PROFILE_ICON; @@ -342,7 +341,6 @@ import android.service.contentcapture.ActivityEvent; import android.service.dreams.DreamActivity; import android.service.voice.IVoiceInteractionSession; import android.util.ArraySet; -import android.util.DisplayMetrics; import android.util.EventLog; import android.util.Log; import android.util.MergedConfiguration; @@ -8667,7 +8665,14 @@ final class ActivityRecord extends WindowToken implements WindowManagerService.A resolvedConfig.windowConfiguration.setMaxBounds(mTmpBounds); } - applySizeOverrideIfNeeded(newParentConfiguration, parentWindowingMode, resolvedConfig); + applySizeOverrideIfNeeded( + mDisplayContent, + info.applicationInfo, + newParentConfiguration, + resolvedConfig, + mOptOutEdgeToEdge, + hasFixedRotationTransform(), + getCompatDisplayInsets() != null); mResolveConfigHint.resetTmpOverrides(); logAppCompatState(); @@ -8677,100 +8682,6 @@ final class ActivityRecord extends WindowToken implements WindowManagerService.A return Rect.copyOrNull(mResolveConfigHint.mParentAppBoundsOverride); } - /** - * If necessary, override configuration fields related to app bounds. - * This will happen when the app is targeting SDK earlier than 35. - * The insets and configuration has decoupled since SDK level 35, to make the system - * compatible to existing apps, override the configuration with legacy metrics. In legacy - * metrics, fields such as appBounds will exclude some of the system bar areas. - * The override contains all potentially affected fields in Configuration, including - * screenWidthDp, screenHeightDp, smallestScreenWidthDp, and orientation. - * All overrides to those fields should be in this method. - * - * TODO: Consider integrate this with computeConfigByResolveHint() - */ - private void applySizeOverrideIfNeeded(Configuration newParentConfiguration, - int parentWindowingMode, Configuration inOutConfig) { - if (mDisplayContent == null) { - return; - } - final Rect parentBounds = newParentConfiguration.windowConfiguration.getBounds(); - int rotation = newParentConfiguration.windowConfiguration.getRotation(); - if (rotation == ROTATION_UNDEFINED && !isFixedRotationTransforming()) { - rotation = mDisplayContent.getRotation(); - } - if (!mOptOutEdgeToEdge && (!mResolveConfigHint.mUseOverrideInsetsForConfig - || getCompatDisplayInsets() != null - || (isFloating(parentWindowingMode) - // Check the requested windowing mode of activity as well in case it is - // switching between PiP and fullscreen. - && (inOutConfig.windowConfiguration.getWindowingMode() - == WINDOWING_MODE_UNDEFINED - || isFloating(inOutConfig.windowConfiguration.getWindowingMode()))) - || rotation == ROTATION_UNDEFINED)) { - // If the insets configuration decoupled logic is not enabled for the app, or the app - // already has a compat override, or the context doesn't contain enough info to - // calculate the override, skip the override. - return; - } - // Make sure the orientation related fields will be updated by the override insets, because - // fixed rotation has assigned the fields from display's configuration. - if (hasFixedRotationTransform()) { - inOutConfig.windowConfiguration.setAppBounds(null); - inOutConfig.screenWidthDp = Configuration.SCREEN_WIDTH_DP_UNDEFINED; - inOutConfig.screenHeightDp = Configuration.SCREEN_HEIGHT_DP_UNDEFINED; - inOutConfig.smallestScreenWidthDp = Configuration.SMALLEST_SCREEN_WIDTH_DP_UNDEFINED; - inOutConfig.orientation = ORIENTATION_UNDEFINED; - } - - // Override starts here. - final boolean rotated = (rotation == ROTATION_90 || rotation == ROTATION_270); - final int dw = rotated ? mDisplayContent.mBaseDisplayHeight - : mDisplayContent.mBaseDisplayWidth; - final int dh = rotated ? mDisplayContent.mBaseDisplayWidth - : mDisplayContent.mBaseDisplayHeight; - final Rect nonDecorInsets = mDisplayContent.getDisplayPolicy() - .getDecorInsetsInfo(rotation, dw, dh).mOverrideNonDecorInsets; - // This should be the only place override the configuration for ActivityRecord. Override - // the value if not calculated yet. - Rect outAppBounds = inOutConfig.windowConfiguration.getAppBounds(); - if (outAppBounds == null || outAppBounds.isEmpty()) { - inOutConfig.windowConfiguration.setAppBounds(parentBounds); - outAppBounds = inOutConfig.windowConfiguration.getAppBounds(); - outAppBounds.inset(nonDecorInsets); - } - float density = inOutConfig.densityDpi; - if (density == Configuration.DENSITY_DPI_UNDEFINED) { - density = newParentConfiguration.densityDpi; - } - density *= DisplayMetrics.DENSITY_DEFAULT_SCALE; - if (inOutConfig.screenWidthDp == Configuration.SCREEN_WIDTH_DP_UNDEFINED) { - inOutConfig.screenWidthDp = (int) (outAppBounds.width() / density + 0.5f); - } - if (inOutConfig.screenHeightDp == Configuration.SCREEN_HEIGHT_DP_UNDEFINED) { - inOutConfig.screenHeightDp = (int) (outAppBounds.height() / density + 0.5f); - } - if (inOutConfig.smallestScreenWidthDp - == Configuration.SMALLEST_SCREEN_WIDTH_DP_UNDEFINED - && parentWindowingMode == WINDOWING_MODE_FULLSCREEN) { - // For the case of PIP transition and multi-window environment, the - // smallestScreenWidthDp is handled already. Override only if the app is in - // fullscreen. - final DisplayInfo info = new DisplayInfo(mDisplayContent.getDisplayInfo()); - mDisplayContent.computeSizeRanges(info, rotated, dw, dh, - mDisplayContent.getDisplayMetrics().density, - inOutConfig, true /* overrideConfig */); - } - - // It's possible that screen size will be considered in different orientation with or - // without considering the system bar insets. Override orientation as well. - if (inOutConfig.orientation == ORIENTATION_UNDEFINED) { - inOutConfig.orientation = - (inOutConfig.screenWidthDp <= inOutConfig.screenHeightDp) - ? ORIENTATION_PORTRAIT : ORIENTATION_LANDSCAPE; - } - } - private void computeConfigByResolveHint(@NonNull Configuration resolvedConfig, @NonNull Configuration parentConfig) { task.computeConfigResourceOverrides(resolvedConfig, parentConfig, mResolveConfigHint); diff --git a/services/core/java/com/android/server/wm/ConfigurationContainer.java b/services/core/java/com/android/server/wm/ConfigurationContainer.java index efd52026cfecdb2905c48da0aed043aa4e286c02..a38ac9ba4b753f71241e6a313f097cb7456b7cab 100644 --- a/services/core/java/com/android/server/wm/ConfigurationContainer.java +++ b/services/core/java/com/android/server/wm/ConfigurationContainer.java @@ -22,14 +22,23 @@ import static android.app.WindowConfiguration.ACTIVITY_TYPE_HOME; import static android.app.WindowConfiguration.ACTIVITY_TYPE_RECENTS; import static android.app.WindowConfiguration.ACTIVITY_TYPE_STANDARD; import static android.app.WindowConfiguration.ACTIVITY_TYPE_UNDEFINED; +import static android.app.WindowConfiguration.ROTATION_UNDEFINED; import static android.app.WindowConfiguration.WINDOWING_MODE_FREEFORM; import static android.app.WindowConfiguration.WINDOWING_MODE_FULLSCREEN; import static android.app.WindowConfiguration.WINDOWING_MODE_PINNED; import static android.app.WindowConfiguration.WINDOWING_MODE_UNDEFINED; import static android.app.WindowConfiguration.activityTypeToString; +import static android.app.WindowConfiguration.isFloating; import static android.app.WindowConfiguration.windowingModeToString; import static android.app.WindowConfigurationProto.WINDOWING_MODE; import static android.content.ConfigurationProto.WINDOW_CONFIGURATION; +import static android.content.pm.ActivityInfo.INSETS_DECOUPLED_CONFIGURATION_ENFORCED; +import static android.content.pm.ActivityInfo.OVERRIDE_ENABLE_INSETS_DECOUPLED_CONFIGURATION; +import static android.content.res.Configuration.ORIENTATION_LANDSCAPE; +import static android.content.res.Configuration.ORIENTATION_PORTRAIT; +import static android.content.res.Configuration.ORIENTATION_UNDEFINED; +import static android.view.Surface.ROTATION_270; +import static android.view.Surface.ROTATION_90; import static com.android.server.wm.ConfigurationContainerProto.FULL_CONFIGURATION; import static com.android.server.wm.ConfigurationContainerProto.MERGED_OVERRIDE_CONFIGURATION; @@ -38,11 +47,14 @@ import static com.android.server.wm.ConfigurationContainerProto.OVERRIDE_CONFIGU import android.annotation.CallSuper; import android.annotation.NonNull; import android.app.WindowConfiguration; +import android.content.pm.ApplicationInfo; import android.content.res.Configuration; import android.graphics.Point; import android.graphics.Rect; import android.os.LocaleList; +import android.util.DisplayMetrics; import android.util.proto.ProtoOutputStream; +import android.view.DisplayInfo; import com.android.internal.annotations.VisibleForTesting; @@ -173,6 +185,111 @@ public abstract class ConfigurationContainer { mResolvedOverrideConfiguration.setTo(mRequestedOverrideConfiguration); } + /** + * If necessary, override configuration fields related to app bounds. + * This will happen when the app is targeting SDK earlier than 35. + * The insets and configuration has decoupled since SDK level 35, to make the system + * compatible to existing apps, override the configuration with legacy metrics. In legacy + * metrics, fields such as appBounds will exclude some of the system bar areas. + * The override contains all potentially affected fields in Configuration, including + * screenWidthDp, screenHeightDp, smallestScreenWidthDp, and orientation. + * All overrides to those fields should be in this method. + * + * TODO: Consider integrate this with computeConfigByResolveHint() + */ + static void applySizeOverrideIfNeeded(DisplayContent displayContent, ApplicationInfo appInfo, + Configuration newParentConfiguration, Configuration inOutConfig, + boolean optOutEdgeToEdge, boolean hasFixedRotationTransform, + boolean hasCompatDisplayInsets) { + if (displayContent == null) { + return; + } + final boolean useOverrideInsetsForConfig = + displayContent.mWmService.mFlags.mInsetsDecoupledConfiguration + ? !appInfo.isChangeEnabled(INSETS_DECOUPLED_CONFIGURATION_ENFORCED) + && !appInfo.isChangeEnabled( + OVERRIDE_ENABLE_INSETS_DECOUPLED_CONFIGURATION) + : appInfo.isChangeEnabled(OVERRIDE_ENABLE_INSETS_DECOUPLED_CONFIGURATION); + final int parentWindowingMode = + newParentConfiguration.windowConfiguration.getWindowingMode(); + final boolean isFloating = isFloating(parentWindowingMode) + // Check the requested windowing mode of activity as well in case it is + // switching between PiP and fullscreen. + && (inOutConfig.windowConfiguration.getWindowingMode() == WINDOWING_MODE_UNDEFINED + || isFloating(inOutConfig.windowConfiguration.getWindowingMode())); + final Rect parentBounds = newParentConfiguration.windowConfiguration.getBounds(); + int rotation = newParentConfiguration.windowConfiguration.getRotation(); + if (rotation == ROTATION_UNDEFINED && !hasFixedRotationTransform) { + rotation = displayContent.getRotation(); + } + if (!optOutEdgeToEdge && (!useOverrideInsetsForConfig + || hasCompatDisplayInsets + || isFloating + || rotation == ROTATION_UNDEFINED)) { + // If the insets configuration decoupled logic is not enabled for the app, or the app + // already has a compat override, or the context doesn't contain enough info to + // calculate the override, skip the override. + return; + } + // Make sure the orientation related fields will be updated by the override insets, because + // fixed rotation has assigned the fields from display's configuration. + if (hasFixedRotationTransform) { + inOutConfig.windowConfiguration.setAppBounds(null); + inOutConfig.screenWidthDp = Configuration.SCREEN_WIDTH_DP_UNDEFINED; + inOutConfig.screenHeightDp = Configuration.SCREEN_HEIGHT_DP_UNDEFINED; + inOutConfig.smallestScreenWidthDp = Configuration.SMALLEST_SCREEN_WIDTH_DP_UNDEFINED; + inOutConfig.orientation = ORIENTATION_UNDEFINED; + } + + // Override starts here. + final boolean rotated = (rotation == ROTATION_90 || rotation == ROTATION_270); + final int dw = rotated + ? displayContent.mBaseDisplayHeight + : displayContent.mBaseDisplayWidth; + final int dh = rotated + ? displayContent.mBaseDisplayWidth + : displayContent.mBaseDisplayHeight; + final Rect nonDecorFrame = displayContent.getDisplayPolicy() + .getDecorInsetsInfo(rotation, dw, dh).mOverrideNonDecorFrame; + // This should be the only place override the configuration for ActivityRecord. Override + // the value if not calculated yet. + Rect outAppBounds = inOutConfig.windowConfiguration.getAppBounds(); + if (outAppBounds == null || outAppBounds.isEmpty()) { + inOutConfig.windowConfiguration.setAppBounds(parentBounds); + outAppBounds = inOutConfig.windowConfiguration.getAppBounds(); + outAppBounds.intersect(nonDecorFrame); + } + float density = inOutConfig.densityDpi; + if (density == Configuration.DENSITY_DPI_UNDEFINED) { + density = newParentConfiguration.densityDpi; + } + density *= DisplayMetrics.DENSITY_DEFAULT_SCALE; + if (inOutConfig.screenWidthDp == Configuration.SCREEN_WIDTH_DP_UNDEFINED) { + inOutConfig.screenWidthDp = (int) (outAppBounds.width() / density + 0.5f); + } + if (inOutConfig.screenHeightDp == Configuration.SCREEN_HEIGHT_DP_UNDEFINED) { + inOutConfig.screenHeightDp = (int) (outAppBounds.height() / density + 0.5f); + } + if (inOutConfig.smallestScreenWidthDp == Configuration.SMALLEST_SCREEN_WIDTH_DP_UNDEFINED + && parentWindowingMode == WINDOWING_MODE_FULLSCREEN) { + // For the case of PIP transition and multi-window environment, the + // smallestScreenWidthDp is handled already. Override only if the app is in + // fullscreen. + final DisplayInfo info = new DisplayInfo(displayContent.getDisplayInfo()); + displayContent.computeSizeRanges(info, rotated, dw, dh, + displayContent.getDisplayMetrics().density, + inOutConfig, true /* overrideConfig */); + } + + // It's possible that screen size will be considered in different orientation with or + // without considering the system bar insets. Override orientation as well. + if (inOutConfig.orientation == ORIENTATION_UNDEFINED) { + inOutConfig.orientation = (inOutConfig.screenWidthDp <= inOutConfig.screenHeightDp) + ? ORIENTATION_PORTRAIT + : ORIENTATION_LANDSCAPE; + } + } + /** Returns {@code true} if requested override override configuration is not empty. */ boolean hasRequestedOverrideConfiguration() { return mHasOverrideConfiguration; diff --git a/services/core/java/com/android/server/wm/WindowProcessController.java b/services/core/java/com/android/server/wm/WindowProcessController.java index 1c00fbbf5c92a2c675c2622f72971fa4b853c84e..607347e46702fecf881a2b247d36b42a26717970 100644 --- a/services/core/java/com/android/server/wm/WindowProcessController.java +++ b/services/core/java/com/android/server/wm/WindowProcessController.java @@ -1660,6 +1660,22 @@ public class WindowProcessController extends ConfigurationContainer