Merge "Set tooltip color scheme to match app scheme" into main
diff --git a/libs/WindowManager/Shell/res/drawable/app_handle_education_tooltip_icon.xml b/libs/WindowManager/Shell/res/drawable/app_handle_education_tooltip_icon.xml
index 07e5ac1..b74d922 100644
--- a/libs/WindowManager/Shell/res/drawable/app_handle_education_tooltip_icon.xml
+++ b/libs/WindowManager/Shell/res/drawable/app_handle_education_tooltip_icon.xml
@@ -22,6 +22,6 @@
     android:viewportHeight="960"
     android:viewportWidth="960">
     <path
-        android:fillColor="@android:color/system_on_tertiary_fixed"
+        android:fillColor="@android:color/system_on_tertiary_container_light"
         android:pathData="M419,880Q391,880 366.5,868Q342,856 325,834L107,557L126,537Q146,516 174,512Q202,508 226,523L300,568L300,240Q300,223 311.5,211.5Q323,200 340,200Q357,200 369,211.5Q381,223 381,240L381,712L284,652L388,785Q394,792 402,796Q410,800 419,800L640,800Q673,800 696.5,776.5Q720,753 720,720L720,560Q720,543 708.5,531.5Q697,520 680,520L461,520L461,440L680,440Q730,440 765,475Q800,510 800,560L800,720Q800,786 753,833Q706,880 640,880L419,880ZM167,340Q154,318 147,292.5Q140,267 140,240Q140,157 198.5,98.5Q257,40 340,40Q423,40 481.5,98.5Q540,157 540,240Q540,267 533,292.5Q526,318 513,340L444,300Q452,286 456,271.5Q460,257 460,240Q460,190 425,155Q390,120 340,120Q290,120 255,155Q220,190 220,240Q220,257 224,271.5Q228,286 236,300L167,340ZM502,620L502,620L502,620L502,620Q502,620 502,620Q502,620 502,620L502,620Q502,620 502,620Q502,620 502,620L502,620Q502,620 502,620Q502,620 502,620L502,620L502,620Z" />
 </vector>
diff --git a/libs/WindowManager/Shell/res/layout/desktop_windowing_education_tooltip_container.xml b/libs/WindowManager/Shell/res/layout/desktop_windowing_education_tooltip_container.xml
index bdee883..09a049c 100644
--- a/libs/WindowManager/Shell/res/layout/desktop_windowing_education_tooltip_container.xml
+++ b/libs/WindowManager/Shell/res/layout/desktop_windowing_education_tooltip_container.xml
@@ -37,7 +37,7 @@
         android:layout_marginStart="2dp"
         android:lineHeight="20dp"
         android:maxWidth="150dp"
-        android:textColor="@android:color/system_on_tertiary_fixed"
+        android:textColor="@android:color/system_on_tertiary_container_light"
         android:textFontWeight="500"
         android:textSize="14sp" />
 </LinearLayout>
\ No newline at end of file
diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/desktopmode/education/AppHandleEducationController.kt b/libs/WindowManager/Shell/src/com/android/wm/shell/desktopmode/education/AppHandleEducationController.kt
index 68a250d..334dc5a 100644
--- a/libs/WindowManager/Shell/src/com/android/wm/shell/desktopmode/education/AppHandleEducationController.kt
+++ b/libs/WindowManager/Shell/src/com/android/wm/shell/desktopmode/education/AppHandleEducationController.kt
@@ -23,6 +23,7 @@
 import android.graphics.Point
 import android.os.SystemProperties
 import android.util.Slog
+import androidx.core.content.withStyledAttributes
 import com.android.window.flags.Flags
 import com.android.wm.shell.R
 import com.android.wm.shell.desktopmode.CaptionState
@@ -32,8 +33,11 @@
 import com.android.wm.shell.shared.annotations.ShellMainThread
 import com.android.wm.shell.shared.desktopmode.DesktopModeStatus.canEnterDesktopMode
 import com.android.wm.shell.shared.desktopmode.DesktopModeTransitionSource
+import com.android.wm.shell.windowdecor.common.DecorThemeUtil
+import com.android.wm.shell.windowdecor.common.Theme
 import com.android.wm.shell.windowdecor.education.DesktopWindowingEducationTooltipController
 import com.android.wm.shell.windowdecor.education.DesktopWindowingEducationTooltipController.EducationViewConfig
+import com.android.wm.shell.windowdecor.education.DesktopWindowingEducationTooltipController.TooltipColorScheme
 import kotlin.time.Duration.Companion.milliseconds
 import kotlinx.coroutines.CoroutineScope
 import kotlinx.coroutines.MainCoroutineDispatcher
@@ -70,6 +74,7 @@
     @ShellMainThread private val applicationCoroutineScope: CoroutineScope,
     @ShellBackgroundThread private val backgroundDispatcher: MainCoroutineDispatcher,
 ) {
+  private val decorThemeUtil = DecorThemeUtil(context)
   private lateinit var openHandleMenuCallback: (Int) -> Unit
   private lateinit var toDesktopModeCallback: (Int, DesktopModeTransitionSource) -> Unit
 
@@ -97,7 +102,9 @@
             }
             .flowOn(backgroundDispatcher)
             .collectLatest { captionState ->
-              showEducation(captionState)
+              val tooltipColorScheme = tooltipColorScheme(captionState)
+
+              showEducation(captionState, tooltipColorScheme)
               // After showing first tooltip, mark education as viewed
               appHandleEducationDatastoreRepository.updateEducationViewedTimestampMillis(true)
             }
@@ -123,7 +130,7 @@
     if (canEnterDesktopMode(context) && Flags.enableDesktopWindowingAppHandleEducation()) block()
   }
 
-  private fun showEducation(captionState: CaptionState) {
+  private fun showEducation(captionState: CaptionState, tooltipColorScheme: TooltipColorScheme) {
     val appHandleBounds = (captionState as CaptionState.AppHandle).globalAppHandleBounds
     val tooltipGlobalCoordinates =
         Point(appHandleBounds.left + appHandleBounds.width() / 2, appHandleBounds.bottom)
@@ -132,14 +139,17 @@
     val appHandleTooltipConfig =
         EducationViewConfig(
             tooltipViewLayout = R.layout.desktop_windowing_education_top_arrow_tooltip,
+            tooltipColorScheme = tooltipColorScheme,
             tooltipViewGlobalCoordinates = tooltipGlobalCoordinates,
             tooltipText = getString(R.string.windowing_app_handle_education_tooltip),
             arrowDirection = DesktopWindowingEducationTooltipController.TooltipArrowDirection.UP,
             onEducationClickAction = {
-              launchWithExceptionHandling { showWindowingImageButtonTooltip() }
+              launchWithExceptionHandling { showWindowingImageButtonTooltip(tooltipColorScheme) }
               openHandleMenuCallback(captionState.runningTaskInfo.taskId)
             },
-            onDismissAction = { launchWithExceptionHandling { showWindowingImageButtonTooltip() } },
+            onDismissAction = {
+              launchWithExceptionHandling { showWindowingImageButtonTooltip(tooltipColorScheme) }
+            },
         )
 
     windowingEducationViewController.showEducationTooltip(
@@ -147,7 +157,7 @@
   }
 
   /** Show tooltip that points to windowing image button in app handle menu */
-  private suspend fun showWindowingImageButtonTooltip() {
+  private suspend fun showWindowingImageButtonTooltip(tooltipColorScheme: TooltipColorScheme) {
     val appInfoPillHeight = getSize(R.dimen.desktop_mode_handle_menu_app_info_pill_height)
     val windowingOptionPillHeight = getSize(R.dimen.desktop_mode_handle_menu_windowing_pill_height)
     val appHandleMenuWidth =
@@ -188,18 +198,21 @@
           val windowingImageButtonTooltipConfig =
               EducationViewConfig(
                   tooltipViewLayout = R.layout.desktop_windowing_education_left_arrow_tooltip,
+                  tooltipColorScheme = tooltipColorScheme,
                   tooltipViewGlobalCoordinates = tooltipGlobalCoordinates,
                   tooltipText =
                       getString(R.string.windowing_desktop_mode_image_button_education_tooltip),
                   arrowDirection =
                       DesktopWindowingEducationTooltipController.TooltipArrowDirection.LEFT,
                   onEducationClickAction = {
-                    launchWithExceptionHandling { showExitWindowingTooltip() }
+                    launchWithExceptionHandling { showExitWindowingTooltip(tooltipColorScheme) }
                     toDesktopModeCallback(
                         captionState.runningTaskInfo.taskId,
                         DesktopModeTransitionSource.APP_HANDLE_MENU_BUTTON)
                   },
-                  onDismissAction = { launchWithExceptionHandling { showExitWindowingTooltip() } },
+                  onDismissAction = {
+                    launchWithExceptionHandling { showExitWindowingTooltip(tooltipColorScheme) }
+                  },
               )
 
           windowingEducationViewController.showEducationTooltip(
@@ -209,7 +222,7 @@
   }
 
   /** Show tooltip that points to app chip button and educates user on how to exit desktop mode */
-  private suspend fun showExitWindowingTooltip() {
+  private suspend fun showExitWindowingTooltip(tooltipColorScheme: TooltipColorScheme) {
     windowDecorCaptionHandleRepository.captionStateFlow
         // After the previous tooltip was dismissed, wait for 400 ms and see if the user entered
         // desktop mode.
@@ -238,6 +251,7 @@
           val exitWindowingTooltipConfig =
               EducationViewConfig(
                   tooltipViewLayout = R.layout.desktop_windowing_education_left_arrow_tooltip,
+                  tooltipColorScheme = tooltipColorScheme,
                   tooltipViewGlobalCoordinates = tooltipGlobalCoordinates,
                   tooltipText = getString(R.string.windowing_desktop_mode_exit_education_tooltip),
                   arrowDirection =
@@ -254,6 +268,32 @@
         }
   }
 
+  private fun tooltipColorScheme(captionState: CaptionState): TooltipColorScheme {
+    context.withStyledAttributes(
+        set = null,
+        attrs =
+            intArrayOf(
+                com.android.internal.R.attr.materialColorOnTertiaryFixed,
+                com.android.internal.R.attr.materialColorTertiaryFixed,
+                com.android.internal.R.attr.materialColorTertiaryFixedDim),
+        defStyleAttr = 0,
+        defStyleRes = 0) {
+          val onTertiaryFixed = getColor(/* index= */ 0, /* defValue= */ 0)
+          val tertiaryFixed = getColor(/* index= */ 1, /* defValue= */ 0)
+          val tertiaryFixedDim = getColor(/* index= */ 2, /* defValue= */ 0)
+          val taskInfo = (captionState as CaptionState.AppHandle).runningTaskInfo
+
+          val tooltipContainerColor =
+              if (decorThemeUtil.getAppTheme(taskInfo) == Theme.LIGHT) {
+                tertiaryFixed
+              } else {
+                tertiaryFixedDim
+              }
+          return TooltipColorScheme(tooltipContainerColor, onTertiaryFixed, onTertiaryFixed)
+        }
+    return TooltipColorScheme(0, 0, 0)
+  }
+
   /**
    * Setup callbacks for app handle education tooltips.
    *
diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/windowdecor/education/DesktopWindowingEducationTooltipController.kt b/libs/WindowManager/Shell/src/com/android/wm/shell/windowdecor/education/DesktopWindowingEducationTooltipController.kt
index a9a16bc..c61b31e 100644
--- a/libs/WindowManager/Shell/src/com/android/wm/shell/windowdecor/education/DesktopWindowingEducationTooltipController.kt
+++ b/libs/WindowManager/Shell/src/com/android/wm/shell/windowdecor/education/DesktopWindowingEducationTooltipController.kt
@@ -16,6 +16,7 @@
 
 package com.android.wm.shell.windowdecor.education
 
+import android.annotation.ColorInt
 import android.annotation.DimenRes
 import android.annotation.LayoutRes
 import android.content.Context
@@ -32,6 +33,7 @@
 import android.widget.TextView
 import android.window.DisplayAreaInfo
 import android.window.WindowContainerTransaction
+import androidx.core.graphics.drawable.DrawableCompat
 import androidx.dynamicanimation.animation.DynamicAnimation
 import androidx.dynamicanimation.animation.SpringForce
 import com.android.wm.shell.R
@@ -120,6 +122,7 @@
                 hideEducationTooltip()
                 tooltipViewConfig.onEducationClickAction()
               }
+              setTooltipColorScheme(tooltipViewConfig.tooltipColorScheme)
             }
 
     val tooltipDimens = tooltipDimens(tooltipView = tooltipView, tooltipViewConfig.arrowDirection)
@@ -189,6 +192,21 @@
             view = tooltipView)
   }
 
+  private fun View.setTooltipColorScheme(tooltipColorScheme: TooltipColorScheme) {
+    requireViewById<LinearLayout>(R.id.tooltip_container).apply {
+      background.setTint(tooltipColorScheme.container)
+    }
+    requireViewById<ImageView>(R.id.arrow_icon).apply {
+      val wrappedDrawable = DrawableCompat.wrap(this.drawable)
+      DrawableCompat.setTint(wrappedDrawable, tooltipColorScheme.container)
+    }
+    requireViewById<TextView>(R.id.tooltip_text).apply { setTextColor(tooltipColorScheme.text) }
+    requireViewById<ImageView>(R.id.tooltip_icon).apply {
+      val wrappedDrawable = DrawableCompat.wrap(this.drawable)
+      DrawableCompat.setTint(wrappedDrawable, tooltipColorScheme.icon)
+    }
+  }
+
   private fun tooltipViewGlobalCoordinates(
       tooltipViewGlobalCoordinates: Point,
       arrowDirection: TooltipArrowDirection,
@@ -255,6 +273,7 @@
    */
   data class EducationViewConfig(
       @LayoutRes val tooltipViewLayout: Int,
+      val tooltipColorScheme: TooltipColorScheme,
       val tooltipViewGlobalCoordinates: Point,
       val tooltipText: String,
       val arrowDirection: TooltipArrowDirection,
@@ -262,6 +281,19 @@
       val onDismissAction: () -> Unit,
   )
 
+  /**
+   * Color scheme of education view:
+   *
+   * @property container Color of the container of the tooltip.
+   * @property text Text color of the [TextView] of education tooltip.
+   * @property icon Color to be filled in tooltip's icon.
+   */
+  data class TooltipColorScheme(
+      @ColorInt val container: Int,
+      @ColorInt val text: Int,
+      @ColorInt val icon: Int,
+  )
+
   /** Direction of arrow of the tooltip */
   enum class TooltipArrowDirection {
     UP,
diff --git a/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/windowdecor/education/DesktopWindowingEducationTooltipControllerTest.kt b/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/windowdecor/education/DesktopWindowingEducationTooltipControllerTest.kt
index 6749776..741dfb8 100644
--- a/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/windowdecor/education/DesktopWindowingEducationTooltipControllerTest.kt
+++ b/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/windowdecor/education/DesktopWindowingEducationTooltipControllerTest.kt
@@ -30,12 +30,15 @@
 import android.view.WindowManager
 import android.widget.TextView
 import android.window.WindowContainerTransaction
+import androidx.compose.ui.graphics.Color
+import androidx.compose.ui.graphics.toArgb
 import androidx.test.filters.SmallTest
 import com.android.wm.shell.R
 import com.android.wm.shell.ShellTestCase
 import com.android.wm.shell.common.DisplayController
 import com.android.wm.shell.windowdecor.additionalviewcontainer.AdditionalSystemViewContainer
 import com.android.wm.shell.windowdecor.education.DesktopWindowingEducationTooltipController.TooltipArrowDirection
+import com.android.wm.shell.windowdecor.education.DesktopWindowingEducationTooltipController.TooltipColorScheme
 import com.google.common.truth.Truth.assertThat
 import org.junit.Before
 import org.junit.Test
@@ -240,14 +243,42 @@
         /* fromRotation= */ ROTATION_90,
         /* toRotation= */ ROTATION_180,
         /* newDisplayAreaInfo= */ null,
-        WindowContainerTransaction())
+        WindowContainerTransaction(),
+    )
 
     verify(mockPopupWindow, times(1)).releaseView()
     verify(mockDisplayController, atLeastOnce()).removeDisplayChangingController(any())
   }
 
+  @Test
+  fun showEducationTooltip_setTooltipColorScheme_correctColorsAreSet() {
+    val tooltipColorScheme =
+        TooltipColorScheme(
+            container = Color.Red.toArgb(), text = Color.Blue.toArgb(), icon = Color.Green.toArgb())
+    val tooltipViewConfig = createTooltipConfig(tooltipColorScheme = tooltipColorScheme)
+
+    tooltipController.showEducationTooltip(tooltipViewConfig = tooltipViewConfig, taskId = 123)
+
+    verify(mockViewContainerFactory, times(1))
+        .create(
+            windowManagerWrapper = any(),
+            taskId = anyInt(),
+            x = anyInt(),
+            y = anyInt(),
+            width = anyInt(),
+            height = anyInt(),
+            flags = anyInt(),
+            view = tooltipViewArgumentCaptor.capture())
+    val tooltipTextView =
+        tooltipViewArgumentCaptor.lastValue.findViewById<TextView>(R.id.tooltip_text)
+    assertThat(tooltipTextView.textColors.defaultColor).isEqualTo(Color.Blue.toArgb())
+  }
+
   private fun createTooltipConfig(
       @LayoutRes tooltipViewLayout: Int = R.layout.desktop_windowing_education_top_arrow_tooltip,
+      tooltipColorScheme: TooltipColorScheme =
+          TooltipColorScheme(
+              container = Color.Red.toArgb(), text = Color.Red.toArgb(), icon = Color.Red.toArgb()),
       tooltipViewGlobalCoordinates: Point = Point(0, 0),
       tooltipText: String = "This is a tooltip",
       arrowDirection: TooltipArrowDirection = TooltipArrowDirection.UP,
@@ -256,6 +287,7 @@
   ) =
       DesktopWindowingEducationTooltipController.EducationViewConfig(
           tooltipViewLayout = tooltipViewLayout,
+          tooltipColorScheme = tooltipColorScheme,
           tooltipViewGlobalCoordinates = tooltipViewGlobalCoordinates,
           tooltipText = tooltipText,
           arrowDirection = arrowDirection,