Merge changes I865871e5,Ie655de7a into tm-qpr-dev am: 6e21d310c1

Original change: https://googleplex-android-review.googlesource.com/c/platform/packages/apps/Launcher3/+/21074655

Change-Id: I3253ef6d326b7b0dc2c20ee9f3679ca969bd39b0
Signed-off-by: Automerger Merge Worker <android-build-automerger-merge-worker@system.gserviceaccount.com>
diff --git a/quickstep/src/com/android/launcher3/taskbar/NavbarButtonsViewController.java b/quickstep/src/com/android/launcher3/taskbar/NavbarButtonsViewController.java
index 4b7d8fc..9cec881 100644
--- a/quickstep/src/com/android/launcher3/taskbar/NavbarButtonsViewController.java
+++ b/quickstep/src/com/android/launcher3/taskbar/NavbarButtonsViewController.java
@@ -18,6 +18,7 @@
 import static android.view.View.AccessibilityDelegate;
 import static android.view.ViewGroup.LayoutParams.MATCH_PARENT;
 import static android.view.ViewTreeObserver.InternalInsetsInfo.TOUCHABLE_INSETS_REGION;
+import static android.view.WindowManager.LayoutParams.TYPE_NAVIGATION_BAR_PANEL;
 
 import static com.android.launcher3.LauncherAnimUtils.VIEW_TRANSLATE_X;
 import static com.android.launcher3.Utilities.getDescendantCoordRelativeToAncestor;
@@ -864,8 +865,8 @@
         mAreNavButtonsInSeparateWindow = true;
         mContext.getDragLayer().removeView(mNavButtonsView);
         mSeparateWindowParent.addView(mNavButtonsView);
-        WindowManager.LayoutParams windowLayoutParams = mContext.createDefaultWindowLayoutParams();
-        windowLayoutParams.setTitle(NAV_BUTTONS_SEPARATE_WINDOW_TITLE);
+        WindowManager.LayoutParams windowLayoutParams = mContext.createDefaultWindowLayoutParams(
+                TYPE_NAVIGATION_BAR_PANEL, NAV_BUTTONS_SEPARATE_WINDOW_TITLE);
         mContext.addWindowView(mSeparateWindowParent, windowLayoutParams);
 
     }
diff --git a/quickstep/src/com/android/launcher3/taskbar/TaskbarActivityContext.java b/quickstep/src/com/android/launcher3/taskbar/TaskbarActivityContext.java
index 20e4b55..dc2c720 100644
--- a/quickstep/src/com/android/launcher3/taskbar/TaskbarActivityContext.java
+++ b/quickstep/src/com/android/launcher3/taskbar/TaskbarActivityContext.java
@@ -241,7 +241,8 @@
 
     public void init(@NonNull TaskbarSharedState sharedState) {
         mLastRequestedNonFullscreenHeight = getDefaultTaskbarWindowHeight();
-        mWindowLayoutParams = createDefaultWindowLayoutParams();
+        mWindowLayoutParams =
+                createDefaultWindowLayoutParams(TYPE_NAVIGATION_BAR_PANEL, WINDOW_TITLE);
 
         // Initialize controllers after all are constructed.
         mControllers.init(sharedState);
@@ -317,16 +318,12 @@
         return super.getStatsLogManager();
     }
 
-    /** @see #createDefaultWindowLayoutParams(int) */
-    public WindowManager.LayoutParams createDefaultWindowLayoutParams() {
-        return createDefaultWindowLayoutParams(TYPE_NAVIGATION_BAR_PANEL);
-    }
-
     /**
      * Creates LayoutParams for adding a view directly to WindowManager as a new window.
      * @param type The window type to pass to the created WindowManager.LayoutParams.
+     * @param title The window title to pass to the created WindowManager.LayoutParams.
      */
-    public WindowManager.LayoutParams createDefaultWindowLayoutParams(int type) {
+    public WindowManager.LayoutParams createDefaultWindowLayoutParams(int type, String title) {
         DeviceProfile deviceProfile = getDeviceProfile();
         // Taskbar is on the logical bottom of the screen
         boolean isVerticalBarLayout = TaskbarManager.isPhoneMode(deviceProfile) &&
@@ -346,7 +343,7 @@
                 type,
                 windowFlags,
                 PixelFormat.TRANSLUCENT);
-        windowLayoutParams.setTitle(WINDOW_TITLE);
+        windowLayoutParams.setTitle(title);
         windowLayoutParams.packageName = getPackageName();
         windowLayoutParams.gravity = !isVerticalBarLayout ?
                 Gravity.BOTTOM :
diff --git a/quickstep/src/com/android/launcher3/taskbar/TaskbarDragLayerController.java b/quickstep/src/com/android/launcher3/taskbar/TaskbarDragLayerController.java
index cd27a46..267bee1 100644
--- a/quickstep/src/com/android/launcher3/taskbar/TaskbarDragLayerController.java
+++ b/quickstep/src/com/android/launcher3/taskbar/TaskbarDragLayerController.java
@@ -49,6 +49,8 @@
     private final AnimatedFloat mNotificationShadeBgTaskbar = new AnimatedFloat(
             this::updateBackgroundAlpha);
     private final AnimatedFloat mImeBgTaskbar = new AnimatedFloat(this::updateBackgroundAlpha);
+    private final AnimatedFloat mAssistantBgTaskbar = new AnimatedFloat(
+            this::updateBackgroundAlpha);
     // Used to hide our background color when someone else (e.g. ScrimView) is handling it.
     private final AnimatedFloat mBgOverride = new AnimatedFloat(this::updateBackgroundAlpha);
 
@@ -60,6 +62,7 @@
     private AnimatedFloat mNavButtonDarkIntensityMultiplier;
 
     private float mLastSetBackgroundAlpha;
+    private boolean mIsBackgroundDrawnElsewhere;
 
     public TaskbarDragLayerController(TaskbarActivityContext activity,
             TaskbarDragLayer taskbarDragLayer) {
@@ -81,6 +84,7 @@
         mKeyguardBgTaskbar.value = 1;
         mNotificationShadeBgTaskbar.value = 1;
         mImeBgTaskbar.value = 1;
+        mAssistantBgTaskbar.value = 1;
         mBgOverride.value = 1;
         updateBackgroundAlpha();
     }
@@ -119,6 +123,10 @@
         return mImeBgTaskbar;
     }
 
+    public AnimatedFloat getAssistantBgTaskbar() {
+        return mAssistantBgTaskbar;
+    }
+
     public AnimatedFloat getOverrideBackgroundAlpha() {
         return mBgOverride;
     }
@@ -143,7 +151,8 @@
     private void updateBackgroundAlpha() {
         final float bgNavbar = mBgNavbar.value;
         final float bgTaskbar = mBgTaskbar.value * mKeyguardBgTaskbar.value
-                * mNotificationShadeBgTaskbar.value * mImeBgTaskbar.value;
+                * mNotificationShadeBgTaskbar.value * mImeBgTaskbar.value
+                * mAssistantBgTaskbar.value;
         mLastSetBackgroundAlpha = mBgOverride.value * Math.max(bgNavbar, bgTaskbar);
         mTaskbarDragLayer.setTaskbarBackgroundAlpha(mLastSetBackgroundAlpha);
 
@@ -168,9 +177,23 @@
         mTaskbarDragLayer.setCornerRoundness(cornerRoundness);
     }
 
+    /**
+     * Set if another controller is temporarily handling background drawing. In this case we:
+     * - Override our background alpha to be 0.
+     * - Keep the nav bar dark intensity assuming taskbar background is at full alpha.
+     */
+    public void setIsBackgroundDrawnElsewhere(boolean isBackgroundDrawnElsewhere) {
+        mIsBackgroundDrawnElsewhere = isBackgroundDrawnElsewhere;
+        mBgOverride.updateValue(mIsBackgroundDrawnElsewhere ? 0 : 1);
+        updateNavBarDarkIntensityMultiplier();
+    }
+
     private void updateNavBarDarkIntensityMultiplier() {
         // Zero out the app-requested dark intensity when we're drawing our own background.
         float effectiveBgAlpha = mLastSetBackgroundAlpha * (1 - mBgOffset.value);
+        if (mIsBackgroundDrawnElsewhere) {
+            effectiveBgAlpha = 1;
+        }
         mNavButtonDarkIntensityMultiplier.updateValue(1 - effectiveBgAlpha);
     }
 
@@ -181,6 +204,13 @@
         pw.println(prefix + "\tmBgOffset=" + mBgOffset.value);
         pw.println(prefix + "\tmFolderMargin=" + mFolderMargin);
         pw.println(prefix + "\tmLastSetBackgroundAlpha=" + mLastSetBackgroundAlpha);
+        pw.println(prefix + "\t\tmBgOverride=" + mBgOverride.value);
+        pw.println(prefix + "\t\tmBgNavbar=" + mBgNavbar.value);
+        pw.println(prefix + "\t\tmBgTaskbar=" + mBgTaskbar.value);
+        pw.println(prefix + "\t\tmKeyguardBgTaskbar=" + mKeyguardBgTaskbar.value);
+        pw.println(prefix + "\t\tmNotificationShadeBgTaskbar=" + mNotificationShadeBgTaskbar.value);
+        pw.println(prefix + "\t\tmImeBgTaskbar=" + mImeBgTaskbar.value);
+        pw.println(prefix + "\t\tmAssistantBgTaskbar=" + mAssistantBgTaskbar.value);
     }
 
     /**
diff --git a/quickstep/src/com/android/launcher3/taskbar/TaskbarEduTooltipController.kt b/quickstep/src/com/android/launcher3/taskbar/TaskbarEduTooltipController.kt
index c4d1ab2..faf7451 100644
--- a/quickstep/src/com/android/launcher3/taskbar/TaskbarEduTooltipController.kt
+++ b/quickstep/src/com/android/launcher3/taskbar/TaskbarEduTooltipController.kt
@@ -151,7 +151,7 @@
     }
 
     override fun dumpLogs(prefix: String?, pw: PrintWriter?) {
-        pw?.println("$(prefix)TaskbarEduController:")
+        pw?.println(prefix + "TaskbarEduTooltipController:")
         pw?.println("$prefix\tisTooltipEnabled=$isTooltipEnabled")
         pw?.println("$prefix\tisOpen=$isOpen")
         pw?.println("$prefix\ttooltipStep=$tooltipStep")
diff --git a/quickstep/src/com/android/launcher3/taskbar/TaskbarScrimViewController.java b/quickstep/src/com/android/launcher3/taskbar/TaskbarScrimViewController.java
index 88767dd..5ea00cf 100644
--- a/quickstep/src/com/android/launcher3/taskbar/TaskbarScrimViewController.java
+++ b/quickstep/src/com/android/launcher3/taskbar/TaskbarScrimViewController.java
@@ -67,7 +67,8 @@
         final boolean manageMenuExpanded =
                 (stateFlags & SYSUI_STATE_BUBBLES_MANAGE_MENU_EXPANDED) != 0;
         final boolean showScrim = !mControllers.navbarButtonsViewController.isImeVisible()
-                && bubblesExpanded && mControllers.taskbarStashController.isInAppAndNotStashed();
+                && bubblesExpanded
+                && mControllers.taskbarStashController.isTaskbarVisibleAndNotStashing();
         final float scrimAlpha = manageMenuExpanded
                 // When manage menu shows there's the first scrim and second scrim so figure out
                 // what the total transparency would be.
diff --git a/quickstep/src/com/android/launcher3/taskbar/TaskbarStashController.java b/quickstep/src/com/android/launcher3/taskbar/TaskbarStashController.java
index a717136..6b7bfa0 100644
--- a/quickstep/src/com/android/launcher3/taskbar/TaskbarStashController.java
+++ b/quickstep/src/com/android/launcher3/taskbar/TaskbarStashController.java
@@ -349,10 +349,10 @@
 
 
     /**
-     * Returns whether the taskbar is currently visible and in an app.
+     * Returns whether the taskbar is currently visible and not in the process of being stashed.
      */
-    public boolean isInAppAndNotStashed() {
-        return !mIsStashed && isInApp();
+    public boolean isTaskbarVisibleAndNotStashing() {
+        return !mIsStashed && mControllers.taskbarViewController.areIconsVisible();
     }
 
     public boolean isInApp() {
diff --git a/quickstep/src/com/android/launcher3/taskbar/TaskbarTranslationController.java b/quickstep/src/com/android/launcher3/taskbar/TaskbarTranslationController.java
index 586115d..80f030f 100644
--- a/quickstep/src/com/android/launcher3/taskbar/TaskbarTranslationController.java
+++ b/quickstep/src/com/android/launcher3/taskbar/TaskbarTranslationController.java
@@ -113,7 +113,7 @@
                 return;
             }
             reset();
-            if (mControllers.taskbarStashController.isInAppAndNotStashed()) {
+            if (mControllers.taskbarStashController.isTaskbarVisibleAndNotStashing()) {
                 mControllers.taskbarEduTooltipController.maybeShowFeaturesEdu();
             }
         }));
diff --git a/quickstep/src/com/android/launcher3/taskbar/VoiceInteractionWindowController.kt b/quickstep/src/com/android/launcher3/taskbar/VoiceInteractionWindowController.kt
index be34fb1..7a5deb7 100644
--- a/quickstep/src/com/android/launcher3/taskbar/VoiceInteractionWindowController.kt
+++ b/quickstep/src/com/android/launcher3/taskbar/VoiceInteractionWindowController.kt
@@ -1,31 +1,70 @@
+/*
+ * Copyright (C) 2023 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.
+ */
 package com.android.launcher3.taskbar
 
+import android.animation.AnimatorSet
 import android.graphics.Canvas
+import android.view.View
+import android.view.ViewTreeObserver
+import android.view.ViewTreeObserver.InternalInsetsInfo.TOUCHABLE_INSETS_REGION
 import android.view.WindowManager
 import android.view.WindowManager.LayoutParams.TYPE_APPLICATION_OVERLAY
+import com.android.launcher3.util.DisplayController
 import com.android.launcher3.views.BaseDragLayer
 import com.android.systemui.animation.ViewRootSync
 import java.io.PrintWriter
 
 private const val TASKBAR_ICONS_FADE_DURATION = 300L
 private const val STASHED_HANDLE_FADE_DURATION = 180L
+private const val TEMP_BACKGROUND_WINDOW_TITLE = "VoiceInteractionTaskbarBackground"
 
-/** Controls Taskbar behavior while Voice Interaction Window (assistant) is showing. */
+/**
+ * Controls Taskbar behavior while Voice Interaction Window (assistant) is showing. Specifically:
+ * - We always hide the taskbar icons or stashed handle, whichever is currently showing.
+ * - For persistent taskbar, we also move the taskbar background to a new window/layer
+ * (TYPE_APPLICATION_OVERLAY) which is behind the assistant.
+ * - For transient taskbar, we hide the real taskbar background (if it's showing).
+ */
 class VoiceInteractionWindowController(val context: TaskbarActivityContext) :
     TaskbarControllers.LoggableTaskbarController, TaskbarControllers.BackgroundRendererController {
 
+    private val isSeparateBackgroundEnabled = !DisplayController.isTransientTaskbar(context)
     private val taskbarBackgroundRenderer = TaskbarBackgroundRenderer(context)
+    private val nonTouchableInsetsComputer =
+        ViewTreeObserver.OnComputeInternalInsetsListener {
+            it.touchableRegion.setEmpty()
+            it.setTouchableInsets(TOUCHABLE_INSETS_REGION)
+        }
 
     // Initialized in init.
     private lateinit var controllers: TaskbarControllers
-    private lateinit var separateWindowForTaskbarBackground: BaseDragLayer<TaskbarActivityContext>
-    private lateinit var separateWindowLayoutParams: WindowManager.LayoutParams
+    // Only initialized if isSeparateBackgroundEnabled
+    private var separateWindowForTaskbarBackground: BaseDragLayer<TaskbarActivityContext>? = null
+    private var separateWindowLayoutParams: WindowManager.LayoutParams? = null
 
     private var isVoiceInteractionWindowVisible: Boolean = false
+    private var pendingAttachedToWindowListener: View.OnAttachStateChangeListener? = null
 
     fun init(controllers: TaskbarControllers) {
         this.controllers = controllers
 
+        if (!isSeparateBackgroundEnabled) {
+            return
+        }
+
         separateWindowForTaskbarBackground =
             object : BaseDragLayer<TaskbarActivityContext>(context, null, 0) {
                 override fun recreateControllers() {
@@ -34,24 +73,39 @@
 
                 override fun draw(canvas: Canvas) {
                     super.draw(canvas)
-                    if (
-                        this@VoiceInteractionWindowController.context.isGestureNav &&
-                            controllers.taskbarStashController.isInAppAndNotStashed
-                    ) {
+                    if (controllers.taskbarStashController.isTaskbarVisibleAndNotStashing) {
                         taskbarBackgroundRenderer.draw(canvas)
                     }
                 }
+
+                override fun onAttachedToWindow() {
+                    super.onAttachedToWindow()
+                    viewTreeObserver.addOnComputeInternalInsetsListener(nonTouchableInsetsComputer)
+                }
+
+                override fun onDetachedFromWindow() {
+                    super.onDetachedFromWindow()
+                    viewTreeObserver.removeOnComputeInternalInsetsListener(
+                        nonTouchableInsetsComputer
+                    )
+                }
             }
-        separateWindowForTaskbarBackground.recreateControllers()
-        separateWindowForTaskbarBackground.setWillNotDraw(false)
+        separateWindowForTaskbarBackground?.recreateControllers()
+        separateWindowForTaskbarBackground?.setWillNotDraw(false)
 
         separateWindowLayoutParams =
-            context.createDefaultWindowLayoutParams(TYPE_APPLICATION_OVERLAY)
-        separateWindowLayoutParams.isSystemApplicationOverlay = true
+            context.createDefaultWindowLayoutParams(
+                TYPE_APPLICATION_OVERLAY,
+                TEMP_BACKGROUND_WINDOW_TITLE
+            )
+        separateWindowLayoutParams?.isSystemApplicationOverlay = true
     }
 
     fun onDestroy() {
         setIsVoiceInteractionWindowVisible(visible = false, skipAnim = true)
+        separateWindowForTaskbarBackground?.removeOnAttachStateChangeListener(
+            pendingAttachedToWindowListener
+        )
     }
 
     fun setIsVoiceInteractionWindowVisible(visible: Boolean, skipAnim: Boolean) {
@@ -72,14 +126,24 @@
                 .get(StashedHandleViewController.ALPHA_INDEX_ASSISTANT_INVOKED)
                 .animateToValue(taskbarIconAlpha)
                 .setDuration(STASHED_HANDLE_FADE_DURATION)
-        fadeTaskbarIcons.start()
-        fadeStashedHandle.start()
+        val animSet = AnimatorSet()
+        animSet.play(fadeTaskbarIcons)
+        animSet.play(fadeStashedHandle)
+        if (!isSeparateBackgroundEnabled) {
+            val fadeTaskbarBackground =
+                controllers.taskbarDragLayerController.assistantBgTaskbar
+                    .animateToValue(taskbarIconAlpha)
+                    .setDuration(TASKBAR_ICONS_FADE_DURATION)
+            animSet.play(fadeTaskbarBackground)
+        }
+        animSet.start()
         if (skipAnim) {
-            fadeTaskbarIcons.end()
-            fadeStashedHandle.end()
+            animSet.end()
         }
 
-        moveTaskbarBackgroundToAppropriateLayer(skipAnim)
+        if (isSeparateBackgroundEnabled) {
+            moveTaskbarBackgroundToAppropriateLayer(skipAnim)
+        }
     }
 
     /**
@@ -92,8 +156,6 @@
      * Removes the temporary window and show the TaskbarDragLayer background again.
      */
     private fun moveTaskbarBackgroundToAppropriateLayer(skipAnim: Boolean) {
-        val taskbarBackgroundOverride =
-            controllers.taskbarDragLayerController.overrideBackgroundAlpha
         val moveToLowerLayer = isVoiceInteractionWindowVisible
         val onWindowsSynchronized =
             if (moveToLowerLayer) {
@@ -102,31 +164,60 @@
                     separateWindowForTaskbarBackground,
                     separateWindowLayoutParams
                 );
-                { taskbarBackgroundOverride.updateValue(0f) }
+                { controllers.taskbarDragLayerController.setIsBackgroundDrawnElsewhere(true) }
             } else {
                 // First reapply the original taskbar background, then remove the temporary window.
-                taskbarBackgroundOverride.updateValue(1f);
+                controllers.taskbarDragLayerController.setIsBackgroundDrawnElsewhere(false);
                 { context.removeWindowView(separateWindowForTaskbarBackground) }
             }
 
         if (skipAnim) {
             onWindowsSynchronized()
         } else {
-            ViewRootSync.synchronizeNextDraw(
-                separateWindowForTaskbarBackground,
-                context.dragLayer,
-                onWindowsSynchronized
-            )
+            separateWindowForTaskbarBackground?.runWhenAttachedToWindow {
+                ViewRootSync.synchronizeNextDraw(
+                    separateWindowForTaskbarBackground!!,
+                    context.dragLayer,
+                    onWindowsSynchronized
+                )
+            }
         }
     }
 
+    private fun View.runWhenAttachedToWindow(onAttachedToWindow: () -> Unit) {
+        if (isAttachedToWindow) {
+            onAttachedToWindow()
+            return
+        }
+        removeOnAttachStateChangeListener(pendingAttachedToWindowListener)
+        pendingAttachedToWindowListener =
+            object : View.OnAttachStateChangeListener {
+                override fun onViewAttachedToWindow(v: View?) {
+                    onAttachedToWindow()
+                    removeOnAttachStateChangeListener(this)
+                    pendingAttachedToWindowListener = null
+                }
+
+                override fun onViewDetachedFromWindow(v: View?) {}
+            }
+        addOnAttachStateChangeListener(pendingAttachedToWindowListener)
+    }
+
     override fun setCornerRoundness(cornerRoundness: Float) {
+        if (!isSeparateBackgroundEnabled) {
+            return
+        }
         taskbarBackgroundRenderer.setCornerRoundness(cornerRoundness)
-        separateWindowForTaskbarBackground.invalidate()
+        separateWindowForTaskbarBackground?.invalidate()
     }
 
     override fun dumpLogs(prefix: String, pw: PrintWriter) {
         pw.println(prefix + "VoiceInteractionWindowController:")
+        pw.println("$prefix\tisSeparateBackgroundEnabled=$isSeparateBackgroundEnabled")
         pw.println("$prefix\tisVoiceInteractionWindowVisible=$isVoiceInteractionWindowVisible")
+        pw.println(
+            "$prefix\tisSeparateTaskbarBackgroundAttachedToWindow=" +
+                "${separateWindowForTaskbarBackground?.isAttachedToWindow}"
+        )
     }
 }