Merge "Enforce edge-to-edge policy to apps targeting SDK level 35+" into main
diff --git a/core/java/android/view/WindowManager.java b/core/java/android/view/WindowManager.java
index 61cf126..f61ed51 100644
--- a/core/java/android/view/WindowManager.java
+++ b/core/java/android/view/WindowManager.java
@@ -3163,6 +3163,12 @@
public static final int PRIVATE_FLAG_DISABLE_WALLPAPER_TOUCH_EVENTS = 1 << 10;
/**
+ * Flag to indicate that the window is forcibly to go edge-to-edge.
+ * @hide
+ */
+ public static final int PRIVATE_FLAG_EDGE_TO_EDGE_ENFORCED = 1 << 11;
+
+ /**
* Flag to indicate that the window frame should be the requested frame adding the display
* cutout frame. This will only be applied if a specific size smaller than the parent frame
* is given, and the window is covering the display cutout. The extended frame will not be
@@ -3338,6 +3344,7 @@
PRIVATE_FLAG_SYSTEM_ERROR,
PRIVATE_FLAG_OPTIMIZE_MEASURE,
PRIVATE_FLAG_DISABLE_WALLPAPER_TOUCH_EVENTS,
+ PRIVATE_FLAG_EDGE_TO_EDGE_ENFORCED,
PRIVATE_FLAG_LAYOUT_SIZE_EXTENDED_BY_CUTOUT,
PRIVATE_FLAG_FORCE_DECOR_VIEW_VISIBILITY,
PRIVATE_FLAG_LAYOUT_CHILD_WINDOW_IN_PARENT_FRAME,
@@ -3400,6 +3407,10 @@
equals = PRIVATE_FLAG_DISABLE_WALLPAPER_TOUCH_EVENTS,
name = "DISABLE_WALLPAPER_TOUCH_EVENTS"),
@ViewDebug.FlagToString(
+ mask = PRIVATE_FLAG_EDGE_TO_EDGE_ENFORCED,
+ equals = PRIVATE_FLAG_EDGE_TO_EDGE_ENFORCED,
+ name = "EDGE_TO_EDGE_ENFORCED"),
+ @ViewDebug.FlagToString(
mask = PRIVATE_FLAG_LAYOUT_SIZE_EXTENDED_BY_CUTOUT,
equals = PRIVATE_FLAG_LAYOUT_SIZE_EXTENDED_BY_CUTOUT,
name = "LAYOUT_SIZE_EXTENDED_BY_CUTOUT"),
diff --git a/core/java/com/android/internal/policy/PhoneWindow.java b/core/java/com/android/internal/policy/PhoneWindow.java
index 31910ac..54fdcc6 100644
--- a/core/java/com/android/internal/policy/PhoneWindow.java
+++ b/core/java/com/android/internal/policy/PhoneWindow.java
@@ -31,6 +31,7 @@
import static android.view.WindowManager.LayoutParams.FLAG_TRANSLUCENT_STATUS;
import static android.view.WindowManager.LayoutParams.LAYOUT_IN_DISPLAY_CUTOUT_MODE_ALWAYS;
import static android.view.WindowManager.LayoutParams.LAYOUT_IN_DISPLAY_CUTOUT_MODE_DEFAULT;
+import static android.view.WindowManager.LayoutParams.PRIVATE_FLAG_EDGE_TO_EDGE_ENFORCED;
import static android.view.WindowManager.LayoutParams.PRIVATE_FLAG_FORCE_DRAW_BAR_BACKGROUNDS;
import static android.view.WindowManager.LayoutParams.PRIVATE_FLAG_NO_MOVE_ANIMATION;
@@ -294,9 +295,9 @@
private int mFrameResource = 0;
private int mTextColor = 0;
- int mStatusBarColor = 0;
- int mNavigationBarColor = 0;
- int mNavigationBarDividerColor = 0;
+ int mStatusBarColor = Color.TRANSPARENT;
+ int mNavigationBarColor = Color.TRANSPARENT;
+ int mNavigationBarDividerColor = Color.TRANSPARENT;
private boolean mForcedStatusBarColor = false;
private boolean mForcedNavigationBarColor = false;
@@ -393,6 +394,7 @@
|| (CompatChanges.isChangeEnabled(ENFORCE_EDGE_TO_EDGE)
&& Flags.enforceEdgeToEdge());
if (mEdgeToEdgeEnforced) {
+ getAttributes().privateFlags |= PRIVATE_FLAG_EDGE_TO_EDGE_ENFORCED;
mDecorFitsSystemWindows = false;
}
}
@@ -2548,17 +2550,10 @@
final boolean targetPreL = targetSdk < android.os.Build.VERSION_CODES.LOLLIPOP;
final boolean targetPreQ = targetSdk < Build.VERSION_CODES.Q;
- if (!mForcedStatusBarColor) {
- final int statusBarCompatibleColor = context.getColor(R.color.status_bar_compatible);
- final int statusBarDefaultColor = context.getColor(R.color.status_bar_default);
- final int statusBarColor = a.getColor(R.styleable.Window_statusBarColor,
- statusBarDefaultColor);
-
- mStatusBarColor = statusBarColor == statusBarDefaultColor && !mEdgeToEdgeEnforced
- ? statusBarCompatibleColor
- : statusBarColor;
+ if (!mForcedStatusBarColor && !mEdgeToEdgeEnforced) {
+ mStatusBarColor = a.getColor(R.styleable.Window_statusBarColor, Color.BLACK);
}
- if (!mForcedNavigationBarColor) {
+ if (!mForcedNavigationBarColor && !mEdgeToEdgeEnforced) {
final int navBarCompatibleColor = context.getColor(R.color.navigation_bar_compatible);
final int navBarDefaultColor = context.getColor(R.color.navigation_bar_default);
final int navBarColor = a.getColor(R.styleable.Window_navigationBarColor,
@@ -2566,7 +2561,6 @@
mNavigationBarColor =
navBarColor == navBarDefaultColor
- && !mEdgeToEdgeEnforced
&& !context.getResources().getBoolean(
R.bool.config_navBarDefaultTransparent)
? navBarCompatibleColor
@@ -2575,7 +2569,7 @@
mNavigationBarDividerColor = a.getColor(R.styleable.Window_navigationBarDividerColor,
Color.TRANSPARENT);
}
- if (!targetPreQ) {
+ if (!targetPreQ && !mEdgeToEdgeEnforced) {
mEnsureStatusBarContrastWhenTransparent = a.getBoolean(
R.styleable.Window_enforceStatusBarContrast, false);
mEnsureNavigationBarContrastWhenTransparent = a.getBoolean(
@@ -3899,6 +3893,9 @@
@Override
public void setStatusBarColor(int color) {
+ if (mEdgeToEdgeEnforced) {
+ return;
+ }
if (mStatusBarColor == color && mForcedStatusBarColor) {
return;
}
@@ -3920,6 +3917,9 @@
@Override
public void setNavigationBarColor(int color) {
+ if (mEdgeToEdgeEnforced) {
+ return;
+ }
if (mNavigationBarColor == color && mForcedNavigationBarColor) {
return;
}
@@ -3936,6 +3936,9 @@
@Override
public void setNavigationBarDividerColor(int navigationBarDividerColor) {
+ if (mEdgeToEdgeEnforced) {
+ return;
+ }
mNavigationBarDividerColor = navigationBarDividerColor;
if (mDecor != null) {
mDecor.updateColorViews(null, false /* animate */);
@@ -3949,6 +3952,9 @@
@Override
public void setStatusBarContrastEnforced(boolean ensureContrast) {
+ if (mEdgeToEdgeEnforced) {
+ return;
+ }
mEnsureStatusBarContrastWhenTransparent = ensureContrast;
if (mDecor != null) {
mDecor.updateColorViews(null, false /* animate */);
@@ -3962,6 +3968,9 @@
@Override
public void setNavigationBarContrastEnforced(boolean enforceContrast) {
+ if (mEdgeToEdgeEnforced) {
+ return;
+ }
mEnsureNavigationBarContrastWhenTransparent = enforceContrast;
if (mDecor != null) {
mDecor.updateColorViews(null, false /* animate */);
@@ -4031,6 +4040,9 @@
@Override
public void setDecorFitsSystemWindows(boolean decorFitsSystemWindows) {
+ if (mEdgeToEdgeEnforced) {
+ return;
+ }
mDecorFitsSystemWindows = decorFitsSystemWindows;
applyDecorFitsSystemWindows();
}
diff --git a/core/res/res/values/colors.xml b/core/res/res/values/colors.xml
index eddd81e..53a6270 100644
--- a/core/res/res/values/colors.xml
+++ b/core/res/res/values/colors.xml
@@ -568,10 +568,6 @@
<color name="side_fps_button_color">#00677E</color>
<!-- Color for system bars -->
- <color name="status_bar_compatible">@android:color/black</color>
- <!-- This uses non-regular transparent intentionally. It is used to tell if the transparent
- color is set by the framework or not. -->
- <color name="status_bar_default">#00808080</color>
<color name="navigation_bar_compatible">@android:color/black</color>
<!-- This uses non-regular transparent intentionally. It is used to tell if the transparent
color is set by the framework or not. -->
diff --git a/core/res/res/values/symbols.xml b/core/res/res/values/symbols.xml
index b0a4c16..d12ef2b 100644
--- a/core/res/res/values/symbols.xml
+++ b/core/res/res/values/symbols.xml
@@ -3095,8 +3095,6 @@
<java-symbol type="bool" name="config_navBarDefaultTransparent" />
<java-symbol type="color" name="navigation_bar_default"/>
<java-symbol type="color" name="navigation_bar_compatible"/>
- <java-symbol type="color" name="status_bar_default"/>
- <java-symbol type="color" name="status_bar_compatible"/>
<!-- EditText suggestion popup. -->
<java-symbol type="id" name="suggestionWindowContainer" />
diff --git a/core/res/res/values/themes.xml b/core/res/res/values/themes.xml
index d5d67ab..bdbf96b 100644
--- a/core/res/res/values/themes.xml
+++ b/core/res/res/values/themes.xml
@@ -190,7 +190,7 @@
<item name="windowTranslucentStatus">false</item>
<item name="windowTranslucentNavigation">false</item>
<item name="windowDrawsSystemBarBackgrounds">false</item>
- <item name="statusBarColor">@color/status_bar_default</item>
+ <item name="statusBarColor">@color/black</item>
<item name="navigationBarColor">@color/navigation_bar_default</item>
<item name="windowActionBarFullscreenDecorLayout">@layout/screen_action_bar</item>
<item name="windowContentTransitions">false</item>
diff --git a/services/core/java/com/android/server/wm/DisplayPolicy.java b/services/core/java/com/android/server/wm/DisplayPolicy.java
index 460a68f..63ca592 100644
--- a/services/core/java/com/android/server/wm/DisplayPolicy.java
+++ b/services/core/java/com/android/server/wm/DisplayPolicy.java
@@ -40,6 +40,7 @@
import static android.view.WindowManager.LayoutParams.FLAG_NOT_TOUCHABLE;
import static android.view.WindowManager.LayoutParams.LAYOUT_IN_DISPLAY_CUTOUT_MODE_ALWAYS;
import static android.view.WindowManager.LayoutParams.PRIVATE_FLAG_CONSUME_IME_INSETS;
+import static android.view.WindowManager.LayoutParams.PRIVATE_FLAG_EDGE_TO_EDGE_ENFORCED;
import static android.view.WindowManager.LayoutParams.PRIVATE_FLAG_FORCE_DRAW_BAR_BACKGROUNDS;
import static android.view.WindowManager.LayoutParams.PRIVATE_FLAG_IMMERSIVE_CONFIRMATION_WINDOW;
import static android.view.WindowManager.LayoutParams.PRIVATE_FLAG_INTERCEPT_GLOBAL_DRAG_AND_DROP;
@@ -959,15 +960,17 @@
case TYPE_BASE_APPLICATION:
- // A non-translucent main app window isn't allowed to fit insets, as it would create
- // a hole on the display!
+ // A non-translucent main app window isn't allowed to fit insets or display cutouts,
+ // as it would create a hole on the display!
if (attrs.isFullscreen() && win.mActivityRecord != null
&& win.mActivityRecord.fillsParent()
- && (win.mAttrs.privateFlags & PRIVATE_FLAG_FORCE_DRAW_BAR_BACKGROUNDS) != 0
- && attrs.getFitInsetsTypes() != 0) {
+ && (attrs.privateFlags & PRIVATE_FLAG_FORCE_DRAW_BAR_BACKGROUNDS) != 0
+ && (attrs.getFitInsetsTypes() != 0
+ || (attrs.privateFlags & PRIVATE_FLAG_EDGE_TO_EDGE_ENFORCED) != 0
+ && attrs.layoutInDisplayCutoutMode
+ != LAYOUT_IN_DISPLAY_CUTOUT_MODE_ALWAYS)) {
throw new IllegalArgumentException("Illegal attributes: Main activity window"
- + " that isn't translucent trying to fit insets: "
- + attrs.getFitInsetsTypes()
+ + " that isn't translucent trying to fit insets or display cutouts."
+ " attrs=" + attrs);
}
break;