diff options
4 files changed, 97 insertions, 150 deletions
diff --git a/services/core/java/com/android/server/wm/ActivityRecord.java b/services/core/java/com/android/server/wm/ActivityRecord.java index 516fc656ccb4..400919a88b1f 100644 --- a/services/core/java/com/android/server/wm/ActivityRecord.java +++ b/services/core/java/com/android/server/wm/ActivityRecord.java @@ -53,6 +53,7 @@ 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; @@ -335,6 +336,7 @@ 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; @@ -8646,14 +8648,7 @@ final class ActivityRecord extends WindowToken implements WindowManagerService.A resolvedConfig.windowConfiguration.setMaxBounds(mTmpBounds); } - applySizeOverrideIfNeeded( - mDisplayContent, - info.applicationInfo, - newParentConfiguration, - resolvedConfig, - mOptOutEdgeToEdge, - hasFixedRotationTransform(), - getCompatDisplayInsets() != null); + applySizeOverrideIfNeeded(newParentConfiguration, parentWindowingMode, resolvedConfig); mResolveConfigHint.resetTmpOverrides(); logAppCompatState(); @@ -8663,6 +8658,100 @@ 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 3ebaf03c4a31..efd52026cfec 100644 --- a/services/core/java/com/android/server/wm/ConfigurationContainer.java +++ b/services/core/java/com/android/server/wm/ConfigurationContainer.java @@ -22,23 +22,14 @@ 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; @@ -47,14 +38,11 @@ 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; @@ -185,110 +173,6 @@ public abstract class ConfigurationContainer<E extends 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 optsOutEdgeToEdge, 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())); - int rotation = newParentConfiguration.windowConfiguration.getRotation(); - if (rotation == ROTATION_UNDEFINED && !hasFixedRotationTransform) { - rotation = displayContent.getRotation(); - } - if (!optsOutEdgeToEdge && (!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; - // 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( - newParentConfiguration.windowConfiguration.getBounds()); - outAppBounds = inOutConfig.windowConfiguration.getAppBounds(); - outAppBounds.inset(displayContent.getDisplayPolicy() - .getDecorInsetsInfo(rotation, dw, dh).mOverrideNonDecorInsets); - } - 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 7b986902d16c..12c50739f66b 100644 --- a/services/core/java/com/android/server/wm/WindowProcessController.java +++ b/services/core/java/com/android/server/wm/WindowProcessController.java @@ -81,11 +81,9 @@ import android.util.Log; import android.util.Slog; import android.util.proto.ProtoOutputStream; -import com.android.internal.R; import com.android.internal.annotations.GuardedBy; import com.android.internal.annotations.VisibleForTesting; import com.android.internal.app.HeavyWeightSwitcherActivity; -import com.android.internal.policy.AttributeCache; import com.android.internal.protolog.ProtoLog; import com.android.internal.util.function.pooled.PooledLambda; import com.android.server.Watchdog; @@ -137,7 +135,6 @@ public class WindowProcessController extends ConfigurationContainer<Configuratio final ApplicationInfo mInfo; final String mName; final int mUid; - final boolean mOptsOutEdgeToEdge; // The process of this application; 0 if none private volatile int mPid; @@ -353,11 +350,6 @@ public class WindowProcessController extends ConfigurationContainer<Configuratio mBgLaunchController = new BackgroundLaunchProcessController( atm::hasActiveVisibleWindow, atm.getBackgroundActivityStartCallback()); - final AttributeCache.Entry ent = AttributeCache.instance().get(info.packageName, - info.theme, R.styleable.Window, mUserId); - mOptsOutEdgeToEdge = ent != null && ent.array.getBoolean( - R.styleable.Window_windowOptOutEdgeToEdgeEnforcement, false); - boolean isSysUiPackage = info.packageName.equals( mAtm.getSysUiServiceComponentLocked().getPackageName()); if (isSysUiPackage || UserHandle.getAppId(mUid) == Process.SYSTEM_UID) { @@ -1682,22 +1674,6 @@ public class WindowProcessController extends ConfigurationContainer<Configuratio // Otherwise if other places send wpc.getConfiguration() to client, the configuration may // be ignored due to the seq is older. resolvedConfig.seq = newParentConfig.seq; - - if (mConfigActivityRecord != null) { - // Let the activity decide whether to apply the size override. - return; - } - final DisplayContent displayContent = mAtm.mWindowManager != null - ? mAtm.mWindowManager.getDefaultDisplayContentLocked() - : null; - applySizeOverrideIfNeeded( - displayContent, - mInfo, - newParentConfig, - resolvedConfig, - mOptsOutEdgeToEdge, - false /* hasFixedRotationTransform */, - false /* hasCompatDisplayInsets */); } void dispatchConfiguration(@NonNull Configuration config) { diff --git a/services/tests/wmtests/src/com/android/server/wm/WindowProcessControllerTests.java b/services/tests/wmtests/src/com/android/server/wm/WindowProcessControllerTests.java index 0cb22ad47355..e6648dad4bbe 100644 --- a/services/tests/wmtests/src/com/android/server/wm/WindowProcessControllerTests.java +++ b/services/tests/wmtests/src/com/android/server/wm/WindowProcessControllerTests.java @@ -18,7 +18,6 @@ package com.android.server.wm; import static android.app.WindowConfiguration.ACTIVITY_TYPE_HOME; import static android.app.WindowConfiguration.ACTIVITY_TYPE_UNDEFINED; -import static android.content.pm.ActivityInfo.INSETS_DECOUPLED_CONFIGURATION_ENFORCED; import static android.content.res.Configuration.GRAMMATICAL_GENDER_NOT_SPECIFIED; import static android.content.res.Configuration.ORIENTATION_LANDSCAPE; import static android.content.res.Configuration.ORIENTATION_PORTRAIT; @@ -87,7 +86,6 @@ public class WindowProcessControllerTests extends WindowTestsBase { ApplicationInfo info = mock(ApplicationInfo.class); info.packageName = "test.package.name"; - doReturn(true).when(info).isChangeEnabled(INSETS_DECOUPLED_CONFIGURATION_ENFORCED); mWpc = new WindowProcessController( mAtm, info, null, 0, -1, null, mMockListener); mWpc.setThread(mock(IApplicationThread.class)); |