Show maximize vs immersive icon in the Header based on immersive state
Flag: com.android.window.flags.enable_fully_immersive_in_desktop
Bug: 369402633
Test: using Youtube Music, open and close a fullscreen video and verify
the App Header icon changes based on immersive request.
Change-Id: Ie28602cae077627ee7d1792a45f1f63be20253e4
diff --git a/libs/WindowManager/Shell/res/drawable/decor_desktop_mode_immersive_button_dark.xml b/libs/WindowManager/Shell/res/drawable/decor_desktop_mode_immersive_button_dark.xml
new file mode 100644
index 0000000..f3800e0
--- /dev/null
+++ b/libs/WindowManager/Shell/res/drawable/decor_desktop_mode_immersive_button_dark.xml
@@ -0,0 +1,25 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+ ~ Copyright (C) 2024 The Android Open Source Project
+ ~
+ ~ Licensed under the Apache License, Version 2.0 (the "License");
+ ~ you may not use this file except in compliance with the License.
+ ~ You may obtain a copy of the License at
+ ~
+ ~ http://www.apache.org/licenses/LICENSE-2.0
+ ~
+ ~ Unless required by applicable law or agreed to in writing, software
+ ~ distributed under the License is distributed on an "AS IS" BASIS,
+ ~ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ ~ See the License for the specific language governing permissions and
+ ~ limitations under the License.
+ -->
+<vector xmlns:android="http://schemas.android.com/apk/res/android"
+ android:height="24dp"
+ android:width="24dp"
+ android:viewportWidth="24"
+ android:viewportHeight="24">
+ <path
+ android:fillColor="#000000"
+ android:pathData="M5,5H10V7H7V10H5V5M14,5H19V10H17V7H14V5M17,14H19V19H14V17H17V14M10,17V19H5V14H7V17H10Z"/>
+</vector>
diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/windowdecor/MaximizeButtonView.kt b/libs/WindowManager/Shell/src/com/android/wm/shell/windowdecor/MaximizeButtonView.kt
index 2d97dc0..68a58ee0 100644
--- a/libs/WindowManager/Shell/src/com/android/wm/shell/windowdecor/MaximizeButtonView.kt
+++ b/libs/WindowManager/Shell/src/com/android/wm/shell/windowdecor/MaximizeButtonView.kt
@@ -18,6 +18,7 @@
import android.animation.AnimatorSet
import android.animation.ObjectAnimator
import android.animation.ValueAnimator
+import android.annotation.DrawableRes
import android.content.Context
import android.content.res.ColorStateList
import android.graphics.Color
@@ -132,6 +133,11 @@
}
}
+ /** Set the drawable resource to use for the maximize button. */
+ fun setIcon(@DrawableRes icon: Int) {
+ maximizeWindow.setImageResource(icon)
+ }
+
companion object {
private const val OPACITY_15 = 38
}
diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/windowdecor/extension/TaskInfo.kt b/libs/WindowManager/Shell/src/com/android/wm/shell/windowdecor/extension/TaskInfo.kt
index 6f8e001..052cfaf 100644
--- a/libs/WindowManager/Shell/src/com/android/wm/shell/windowdecor/extension/TaskInfo.kt
+++ b/libs/WindowManager/Shell/src/com/android/wm/shell/windowdecor/extension/TaskInfo.kt
@@ -20,6 +20,7 @@
import android.app.WindowConfiguration.WINDOWING_MODE_FULLSCREEN
import android.app.WindowConfiguration.WINDOWING_MODE_MULTI_WINDOW
import android.app.WindowConfiguration.WINDOWING_MODE_PINNED
+import android.view.WindowInsets
import android.view.WindowInsetsController.APPEARANCE_LIGHT_CAPTION_BARS
import android.view.WindowInsetsController.APPEARANCE_TRANSPARENT_CAPTION_BAR_BACKGROUND
@@ -46,3 +47,10 @@
/** Whether the task is in multi-window windowing mode. */
val TaskInfo.isMultiWindow: Boolean
get() = windowingMode == WINDOWING_MODE_MULTI_WINDOW
+
+/** Whether the task is requesting immersive mode. */
+val TaskInfo.requestingImmersive: Boolean
+ get() {
+ // Considered to be requesting immersive when requesting to hide the status bar.
+ return (requestedVisibleTypes and WindowInsets.Type.statusBars()) == 0
+ }
diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/windowdecor/viewholder/AppHeaderViewHolder.kt b/libs/WindowManager/Shell/src/com/android/wm/shell/windowdecor/viewholder/AppHeaderViewHolder.kt
index e996165..306103c 100644
--- a/libs/WindowManager/Shell/src/com/android/wm/shell/windowdecor/viewholder/AppHeaderViewHolder.kt
+++ b/libs/WindowManager/Shell/src/com/android/wm/shell/windowdecor/viewholder/AppHeaderViewHolder.kt
@@ -46,6 +46,7 @@
import com.android.internal.R.attr.materialColorSurfaceContainerHigh
import com.android.internal.R.attr.materialColorSurfaceContainerLow
import com.android.internal.R.attr.materialColorSurfaceDim
+import com.android.window.flags.Flags
import com.android.window.flags.Flags.enableMinimizeButton
import com.android.wm.shell.R
import android.window.flags.DesktopModeFlags
@@ -59,6 +60,7 @@
import com.android.wm.shell.windowdecor.common.Theme
import com.android.wm.shell.windowdecor.extension.isLightCaptionBarAppearance
import com.android.wm.shell.windowdecor.extension.isTransparentCaptionBarAppearance
+import com.android.wm.shell.windowdecor.extension.requestingImmersive
/**
* A desktop mode window decoration used when the window is floating (i.e. freeform). It hosts
@@ -241,16 +243,25 @@
}
minimizeWindowButton.isGone = !enableMinimizeButton()
// Maximize button.
- maximizeButtonView.setAnimationTints(
- darkMode = header.appTheme == Theme.DARK,
- iconForegroundColor = colorStateList,
- baseForegroundColor = foregroundColor,
- rippleDrawable = createRippleDrawable(
- color = foregroundColor,
- cornerRadius = headerButtonsRippleRadius,
- drawableInsets = maximizeDrawableInsets
+ maximizeButtonView.apply {
+ setAnimationTints(
+ darkMode = header.appTheme == Theme.DARK,
+ iconForegroundColor = colorStateList,
+ baseForegroundColor = foregroundColor,
+ rippleDrawable = createRippleDrawable(
+ color = foregroundColor,
+ cornerRadius = headerButtonsRippleRadius,
+ drawableInsets = maximizeDrawableInsets
+ )
)
- )
+ setIcon(
+ if (taskInfo.requestingImmersive && Flags.enableFullyImmersiveInDesktop()) {
+ R.drawable.decor_desktop_mode_immersive_button_dark
+ } else {
+ R.drawable.decor_desktop_mode_maximize_button_dark
+ }
+ )
+ }
// Close button.
closeWindowButton.apply {
imageTintList = colorStateList