From ca35e71bfd4432fd6b3e72681c855dd3b91601c1 Mon Sep 17 00:00:00 2001 From: Tiger Date: Tue, 12 Nov 2024 21:59:14 +0800 Subject: Disable windowOptOutEdgeToEdgeEnforcement if the app targets SDK 36+ This attribute has been introduced since API level 35. To make apps go edge-to-edge properly, this shouldn't be used anymore. Bug: 377864165 Flag: com.android.window.flags.disable_opt_out_edge_to_edge Test: presubmit Change-Id: I964d4483f4e2436d260151c41411700358696243 --- core/java/android/view/WindowManagerGlobal.java | 4 ++- .../com/android/internal/policy/PhoneWindow.java | 37 +++++++++++++++++++--- .../java/com/android/server/wm/ActivityRecord.java | 5 +-- 3 files changed, 38 insertions(+), 8 deletions(-) diff --git a/core/java/android/view/WindowManagerGlobal.java b/core/java/android/view/WindowManagerGlobal.java index f50ea9106a61..617e4762ebf0 100644 --- a/core/java/android/view/WindowManagerGlobal.java +++ b/core/java/android/view/WindowManagerGlobal.java @@ -50,6 +50,7 @@ import android.window.TrustedPresentationThresholds; import com.android.internal.R; import com.android.internal.annotations.GuardedBy; +import com.android.internal.policy.PhoneWindow; import com.android.internal.util.FastPrintWriter; import java.io.FileDescriptor; @@ -375,7 +376,8 @@ public final class WindowManagerGlobal { if (context != null && wparams.type > LAST_APPLICATION_WINDOW) { final TypedArray styles = context.obtainStyledAttributes(R.styleable.Window); - if (styles.getBoolean(R.styleable.Window_windowOptOutEdgeToEdgeEnforcement, false)) { + if (PhoneWindow.isOptingOutEdgeToEdgeEnforcement( + context.getApplicationInfo(), true /* local */, styles)) { wparams.privateFlags |= PRIVATE_FLAG_OPT_OUT_EDGE_TO_EDGE; } styles.recycle(); diff --git a/core/java/com/android/internal/policy/PhoneWindow.java b/core/java/com/android/internal/policy/PhoneWindow.java index e0529b339d4a..67e358a47cce 100644 --- a/core/java/com/android/internal/policy/PhoneWindow.java +++ b/core/java/com/android/internal/policy/PhoneWindow.java @@ -183,6 +183,14 @@ public class PhoneWindow extends Window implements MenuBuilder.Callback { @EnabledSince(targetSdkVersion = Build.VERSION_CODES.VANILLA_ICE_CREAM) private static final long ENFORCE_EDGE_TO_EDGE = 309578419; + /** + * Disable opting out the edge-to-edge enforcement. + * {@link Build.VERSION_CODES#BAKLAVA} or above. + */ + @ChangeId + @EnabledSince(targetSdkVersion = Build.VERSION_CODES.BAKLAVA) + private static final long DISABLE_OPT_OUT_EDGE_TO_EDGE = 377864165; + /** * Override the layout in display cutout mode behavior. This will only apply if the edge to edge * is not enforced. @@ -450,7 +458,7 @@ public class PhoneWindow extends Window implements MenuBuilder.Callback { */ public static boolean isEdgeToEdgeEnforced(ApplicationInfo info, boolean local, TypedArray windowStyle) { - return !windowStyle.getBoolean(R.styleable.Window_windowOptOutEdgeToEdgeEnforcement, false) + return !isOptingOutEdgeToEdgeEnforcement(info, local, windowStyle) && (info.targetSdkVersion >= ENFORCE_EDGE_TO_EDGE_SDK_VERSION || (Flags.enforceEdgeToEdge() && (local // Calling this doesn't require a permission. @@ -459,6 +467,26 @@ public class PhoneWindow extends Window implements MenuBuilder.Callback { : info.isChangeEnabled(ENFORCE_EDGE_TO_EDGE)))); } + /** + * Returns whether the given application is opting out edge-to-edge enforcement. + * + * @param info The application to query. + * @param local Whether this is called from the process of the given application. + * @param windowStyle The style of the window. + * @return {@code true} if the edge-to-edge enforcement is opting out. Otherwise, {@code false}. + */ + public static boolean isOptingOutEdgeToEdgeEnforcement(ApplicationInfo info, boolean local, + TypedArray windowStyle) { + final boolean disabled = (Flags.disableOptOutEdgeToEdge() && (local + // Calling this doesn't require a permission. + ? CompatChanges.isChangeEnabled(DISABLE_OPT_OUT_EDGE_TO_EDGE) + // Calling this requires permissions. + : info.isChangeEnabled(DISABLE_OPT_OUT_EDGE_TO_EDGE))); + return !disabled && windowStyle.getBoolean( + R.styleable.Window_windowOptOutEdgeToEdgeEnforcement, false /* default */); + + } + @Override public final void setContainer(Window container) { super.setContainer(container); @@ -2486,6 +2514,7 @@ public class PhoneWindow extends Window implements MenuBuilder.Callback { TypedArray a = getWindowStyle(); WindowManager.LayoutParams params = getAttributes(); + ApplicationInfo appInfo = getContext().getApplicationInfo(); if (false) { System.out.println("From style:"); @@ -2497,8 +2526,7 @@ public class PhoneWindow extends Window implements MenuBuilder.Callback { System.out.println(s); } - mEdgeToEdgeEnforced = isEdgeToEdgeEnforced( - getContext().getApplicationInfo(), true /* local */, a); + mEdgeToEdgeEnforced = isEdgeToEdgeEnforced(appInfo, true /* local */, a); if (mEdgeToEdgeEnforced) { getAttributes().privateFlags |= PRIVATE_FLAG_EDGE_TO_EDGE_ENFORCED; mDecorFitsSystemWindows = false; @@ -2507,8 +2535,7 @@ public class PhoneWindow extends Window implements MenuBuilder.Callback { // mNavigationBarColor is not reset here because it might be used to draw the scrim. } if (CompatChanges.isChangeEnabled(OVERRIDE_LAYOUT_IN_DISPLAY_CUTOUT_MODE) - && !a.getBoolean(R.styleable.Window_windowOptOutEdgeToEdgeEnforcement, - false /* defValue */)) { + && !isOptingOutEdgeToEdgeEnforcement(appInfo, true /* local */, a)) { getAttributes().privateFlags |= PRIVATE_FLAG_OVERRIDE_LAYOUT_IN_DISPLAY_CUTOUT_MODE; } diff --git a/services/core/java/com/android/server/wm/ActivityRecord.java b/services/core/java/com/android/server/wm/ActivityRecord.java index c6e6e761c0bc..99f9b761ea98 100644 --- a/services/core/java/com/android/server/wm/ActivityRecord.java +++ b/services/core/java/com/android/server/wm/ActivityRecord.java @@ -366,6 +366,7 @@ import com.android.internal.content.ReferrerIntent; import com.android.internal.os.TimeoutRecord; import com.android.internal.os.TransferPipe; import com.android.internal.policy.AttributeCache; +import com.android.internal.policy.PhoneWindow; import com.android.internal.protolog.ProtoLog; import com.android.internal.util.XmlUtils; import com.android.modules.utils.TypedXmlPullParser; @@ -2017,8 +2018,8 @@ final class ActivityRecord extends WindowToken implements WindowManagerService.A || ent.array.getBoolean(R.styleable.Window_windowShowWallpaper, false); mStyleFillsParent = mOccludesParent; mNoDisplay = ent.array.getBoolean(R.styleable.Window_windowNoDisplay, false); - mOptOutEdgeToEdge = ent.array.getBoolean( - R.styleable.Window_windowOptOutEdgeToEdgeEnforcement, false); + mOptOutEdgeToEdge = PhoneWindow.isOptingOutEdgeToEdgeEnforcement( + aInfo.applicationInfo, false /* local */, ent.array); } else { mStyleFillsParent = mOccludesParent = true; mNoDisplay = false; -- cgit v1.2.3-59-g8ed1b