diff options
| author | 2024-12-16 16:24:57 +0000 | |
|---|---|---|
| committer | 2025-01-10 15:35:48 +0000 | |
| commit | b805c44f76dd23ec823afa680b485c0e836de63c (patch) | |
| tree | 924dff95af1d2e181f6828fdf0cedfe89a23e325 | |
| parent | 7d5db209ccd22761047bf52933fd366954cbac9b (diff) | |
[42/n] Move some SizeCompatMode logic to Policy
Flag: EXEMPT Refactoring
Bug: 360865550
Test: atest WmTests:ActivityRecordTests
Change-Id: Icb32bb8f113c697f0cb928b114a9dd7b6652689c
3 files changed, 126 insertions, 95 deletions
diff --git a/services/core/java/com/android/server/wm/ActivityRecord.java b/services/core/java/com/android/server/wm/ActivityRecord.java index d31aed2aee37..0fbbbbf79137 100644 --- a/services/core/java/com/android/server/wm/ActivityRecord.java +++ b/services/core/java/com/android/server/wm/ActivityRecord.java @@ -90,10 +90,6 @@ import static android.content.pm.ActivityInfo.RESIZE_MODE_RESIZEABLE_VIA_SDK_VER import static android.content.pm.ActivityInfo.RESIZE_MODE_UNRESIZEABLE; import static android.content.pm.ActivityInfo.SCREEN_ORIENTATION_BEHIND; import static android.content.pm.ActivityInfo.SCREEN_ORIENTATION_UNSET; -import static android.content.pm.ActivityInfo.SIZE_CHANGES_SUPPORTED_METADATA; -import static android.content.pm.ActivityInfo.SIZE_CHANGES_SUPPORTED_OVERRIDE; -import static android.content.pm.ActivityInfo.SIZE_CHANGES_UNSUPPORTED_METADATA; -import static android.content.pm.ActivityInfo.SIZE_CHANGES_UNSUPPORTED_OVERRIDE; import static android.content.res.Configuration.ASSETS_SEQ_UNDEFINED; import static android.content.res.Configuration.EMPTY; import static android.content.res.Configuration.ORIENTATION_LANDSCAPE; @@ -1272,8 +1268,10 @@ final class ActivityRecord extends WindowToken implements WindowManagerService.A pw.println(prefix + "manifestMinAspectRatio=" + info.getManifestMinAspectRatio()); } - pw.println(prefix + "supportsSizeChanges=" - + ActivityInfo.sizeChangesSupportModeToString(supportsSizeChanges())); + pw.println( + prefix + "supportsSizeChanges=" + ActivityInfo.sizeChangesSupportModeToString( + mAppCompatController.getAppCompatSizeCompatModePolicy() + .supportsSizeChanges())); if (info.configChanges != 0) { pw.println(prefix + "configChanges=0x" + Integer.toHexString(info.configChanges)); } @@ -8374,31 +8372,7 @@ final class ActivityRecord extends WindowToken implements WindowManagerService.A * density than its parent or its bounds don't fit in parent naturally. */ boolean inSizeCompatMode() { - final AppCompatSizeCompatModePolicy scmPolicy = mAppCompatController - .getAppCompatSizeCompatModePolicy(); - if (scmPolicy.isInSizeCompatModeForBounds()) { - return true; - } - if (getAppCompatDisplayInsets() == null || !shouldCreateAppCompatDisplayInsets() - // The orientation is different from parent when transforming. - || isFixedRotationTransforming()) { - return false; - } - final Rect appBounds = getConfiguration().windowConfiguration.getAppBounds(); - if (appBounds == null) { - // The app bounds hasn't been computed yet. - return false; - } - final WindowContainer parent = getParent(); - if (parent == null) { - // The parent of detached Activity can be null. - return false; - } - final Configuration parentConfig = parent.getConfiguration(); - // Although colorMode, screenLayout, smallestScreenWidthDp are also fixed, generally these - // fields should be changed with density and bounds, so here only compares the most - // significant field. - return parentConfig.densityDpi != getConfiguration().densityDpi; + return mAppCompatController.getAppCompatSizeCompatModePolicy().inSizeCompatMode(); } /** @@ -8412,62 +8386,8 @@ final class ActivityRecord extends WindowToken implements WindowManagerService.A * aspect ratio. */ boolean shouldCreateAppCompatDisplayInsets() { - if (mAppCompatController.getAppCompatAspectRatioOverrides().hasFullscreenOverride()) { - // If the user has forced the applications aspect ratio to be fullscreen, don't use size - // compatibility mode in any situation. The user has been warned and therefore accepts - // the risk of the application misbehaving. - return false; - } - switch (supportsSizeChanges()) { - case SIZE_CHANGES_SUPPORTED_METADATA: - case SIZE_CHANGES_SUPPORTED_OVERRIDE: - return false; - case SIZE_CHANGES_UNSUPPORTED_OVERRIDE: - return true; - default: - // Fall through - } - // Use root activity's info for tasks in multi-window mode, or fullscreen tasks in freeform - // task display areas, to ensure visual consistency across activity launches and exits in - // the same task. - final TaskDisplayArea tda = getTaskDisplayArea(); - if (inMultiWindowMode() || (tda != null && tda.inFreeformWindowingMode())) { - final ActivityRecord root = task != null ? task.getRootActivity() : null; - if (root != null && root != this && !root.shouldCreateAppCompatDisplayInsets()) { - // If the root activity doesn't use size compatibility mode, the activities above - // are forced to be the same for consistent visual appearance. - return false; - } - } - return !isResizeable() && (info.isFixedOrientation() || hasFixedAspectRatio()) - // The configuration of non-standard type should be enforced by system. - // {@link WindowConfiguration#ACTIVITY_TYPE_STANDARD} is set when this activity is - // added to a task, but this function is called when resolving the launch params, at - // which point, the activity type is still undefined if it will be standard. - // For other non-standard types, the type is set in the constructor, so this should - // not be a problem. - && isActivityTypeStandardOrUndefined(); - } - - /** - * Returns whether the activity supports size changes. - */ - @ActivityInfo.SizeChangesSupportMode - private int supportsSizeChanges() { - final AppCompatResizeOverrides resizeOverrides = mAppCompatController.getResizeOverrides(); - if (resizeOverrides.shouldOverrideForceNonResizeApp()) { - return SIZE_CHANGES_UNSUPPORTED_OVERRIDE; - } - - if (info.supportsSizeChanges) { - return SIZE_CHANGES_SUPPORTED_METADATA; - } - - if (resizeOverrides.shouldOverrideForceResizeApp()) { - return SIZE_CHANGES_SUPPORTED_OVERRIDE; - } - - return SIZE_CHANGES_UNSUPPORTED_METADATA; + return mAppCompatController.getAppCompatSizeCompatModePolicy() + .shouldCreateAppCompatDisplayInsets(); } @Override @@ -9367,13 +9287,6 @@ final class ActivityRecord extends WindowToken implements WindowManagerService.A } /** - * Returns true if the activity has maximum or minimum aspect ratio. - */ - private boolean hasFixedAspectRatio() { - return getMaxAspectRatio() != 0 || getMinAspectRatio() != 0; - } - - /** * @return {@code true} if this activity was reparented to another display but * {@link #ensureActivityConfiguration} is not called. */ diff --git a/services/core/java/com/android/server/wm/AppCompatAspectRatioPolicy.java b/services/core/java/com/android/server/wm/AppCompatAspectRatioPolicy.java index 6a0de98c0ffa..3e232ea6b612 100644 --- a/services/core/java/com/android/server/wm/AppCompatAspectRatioPolicy.java +++ b/services/core/java/com/android/server/wm/AppCompatAspectRatioPolicy.java @@ -215,6 +215,13 @@ class AppCompatAspectRatioPolicy { mAppCompatAspectRatioState.mLetterboxBoundsForAspectRatio = bounds; } + /** + * Returns true if the activity has maximum or minimum aspect ratio. + */ + boolean hasFixedAspectRatio() { + return getMaxAspectRatio() != 0 || getMinAspectRatio() != 0; + } + private boolean isParentFullscreenPortrait() { final WindowContainer<?> parent = mActivityRecord.getParent(); return parent != null diff --git a/services/core/java/com/android/server/wm/AppCompatSizeCompatModePolicy.java b/services/core/java/com/android/server/wm/AppCompatSizeCompatModePolicy.java index d278dc3d1be7..515a7c415eeb 100644 --- a/services/core/java/com/android/server/wm/AppCompatSizeCompatModePolicy.java +++ b/services/core/java/com/android/server/wm/AppCompatSizeCompatModePolicy.java @@ -18,6 +18,10 @@ package com.android.server.wm; import static android.app.WindowConfiguration.ROTATION_UNDEFINED; import static android.app.WindowConfiguration.WINDOWING_MODE_FREEFORM; +import static android.content.pm.ActivityInfo.SIZE_CHANGES_SUPPORTED_METADATA; +import static android.content.pm.ActivityInfo.SIZE_CHANGES_SUPPORTED_OVERRIDE; +import static android.content.pm.ActivityInfo.SIZE_CHANGES_UNSUPPORTED_METADATA; +import static android.content.pm.ActivityInfo.SIZE_CHANGES_UNSUPPORTED_OVERRIDE; import static android.content.res.Configuration.ORIENTATION_UNDEFINED; import static com.android.server.wm.DesktopModeHelper.canEnterDesktopMode; @@ -82,7 +86,8 @@ class AppCompatSizeCompatModePolicy { } /** - * @return The {@code true} if the current instance has {@link #mAppCompatDisplayInsets} without + * @return The {@code true} if the current instance has + * {@link AppCompatSizeCompatModePolicy#mAppCompatDisplayInsets} without * considering the inheritance implemented in {@link #getAppCompatDisplayInsets()} */ boolean hasAppCompatDisplayInsetsWithoutInheritance() { @@ -368,6 +373,112 @@ class AppCompatSizeCompatModePolicy { .mUseOverrideInsetsForConfig); } + /** + * @return {@code true} if this activity is in size compatibility mode that uses the different + * density than its parent or its bounds don't fit in parent naturally. + */ + boolean inSizeCompatMode() { + if (isInSizeCompatModeForBounds()) { + return true; + } + if (getAppCompatDisplayInsets() == null || !shouldCreateAppCompatDisplayInsets() + // The orientation is different from parent when transforming. + || mActivityRecord.isFixedRotationTransforming()) { + return false; + } + final Rect appBounds = mActivityRecord.getConfiguration().windowConfiguration + .getAppBounds(); + if (appBounds == null) { + // The app bounds hasn't been computed yet. + return false; + } + final WindowContainer<?> parent = mActivityRecord.getParent(); + if (parent == null) { + // The parent of detached Activity can be null. + return false; + } + final Configuration parentConfig = parent.getConfiguration(); + // Although colorMode, screenLayout, smallestScreenWidthDp are also fixed, generally these + // fields should be changed with density and bounds, so here only compares the most + // significant field. + return parentConfig.densityDpi != mActivityRecord.getConfiguration().densityDpi; + } + + /** + * Indicates the activity will keep the bounds and screen configuration when it was first + * launched, no matter how its parent changes. + * + * <p>If {@true}, then {@link AppCompatDisplayInsets} will be created in {@link + * ActivityRecord#resolveOverrideConfiguration} to "freeze" activity bounds and insets. + * + * @return {@code true} if this activity is declared as non-resizable and fixed orientation or + * aspect ratio. + */ + boolean shouldCreateAppCompatDisplayInsets() { + if (mActivityRecord.mAppCompatController.getAppCompatAspectRatioOverrides() + .hasFullscreenOverride()) { + // If the user has forced the applications aspect ratio to be fullscreen, don't use size + // compatibility mode in any situation. The user has been warned and therefore accepts + // the risk of the application misbehaving. + return false; + } + switch (supportsSizeChanges()) { + case SIZE_CHANGES_SUPPORTED_METADATA: + case SIZE_CHANGES_SUPPORTED_OVERRIDE: + return false; + case SIZE_CHANGES_UNSUPPORTED_OVERRIDE: + return true; + default: + // Fall through + } + // Use root activity's info for tasks in multi-window mode, or fullscreen tasks in freeform + // task display areas, to ensure visual consistency across activity launches and exits in + // the same task. + final TaskDisplayArea tda = mActivityRecord.getTaskDisplayArea(); + if (mActivityRecord.inMultiWindowMode() || (tda != null && tda.inFreeformWindowingMode())) { + final Task task = mActivityRecord.getTask(); + final ActivityRecord root = task != null ? task.getRootActivity() : null; + if (root != null && root != mActivityRecord + && !root.shouldCreateAppCompatDisplayInsets()) { + // If the root activity doesn't use size compatibility mode, the activities above + // are forced to be the same for consistent visual appearance. + return false; + } + } + final AppCompatAspectRatioPolicy aspectRatioPolicy = mActivityRecord.mAppCompatController + .getAppCompatAspectRatioPolicy(); + return !mActivityRecord.isResizeable() && (mActivityRecord.info.isFixedOrientation() + || aspectRatioPolicy.hasFixedAspectRatio()) + // The configuration of non-standard type should be enforced by system. + // {@link WindowConfiguration#ACTIVITY_TYPE_STANDARD} is set when this activity is + // added to a task, but this function is called when resolving the launch params, at + // which point, the activity type is still undefined if it will be standard. + // For other non-standard types, the type is set in the constructor, so this should + // not be a problem. + && mActivityRecord.isActivityTypeStandardOrUndefined(); + } + + /** + * Returns whether the activity supports size changes. + */ + @ActivityInfo.SizeChangesSupportMode + int supportsSizeChanges() { + final AppCompatResizeOverrides resizeOverrides = mAppCompatOverrides.getResizeOverrides(); + if (resizeOverrides.shouldOverrideForceNonResizeApp()) { + return SIZE_CHANGES_UNSUPPORTED_OVERRIDE; + } + + if (mActivityRecord.info.supportsSizeChanges) { + return SIZE_CHANGES_SUPPORTED_METADATA; + } + + if (resizeOverrides.shouldOverrideForceResizeApp()) { + return SIZE_CHANGES_SUPPORTED_OVERRIDE; + } + + return SIZE_CHANGES_UNSUPPORTED_METADATA; + } + private boolean isInSizeCompatModeForBounds(final @NonNull Rect appBounds, final @NonNull Rect containerBounds) { |