Re-land "Add hover state border to overview task item"

Fix: 249859410
Test: b/291266459
Change-Id: I5ac1e9e77439e587f11c994d22fdc72d20d8502d
diff --git a/quickstep/res/layout-land/keyboard_quick_switch_taskview.xml b/quickstep/res/layout-land/keyboard_quick_switch_taskview.xml
index 4e67629..69e1574 100644
--- a/quickstep/res/layout-land/keyboard_quick_switch_taskview.xml
+++ b/quickstep/res/layout-land/keyboard_quick_switch_taskview.xml
@@ -23,7 +23,7 @@
     android:importantForAccessibility="yes"
     android:background="@drawable/keyboard_quick_switch_task_view_background"
     android:clipToOutline="true"
-    launcher:borderColor="?androidprv:attr/materialColorOutline">
+    launcher:focusBorderColor="?androidprv:attr/materialColorOutline">
 
     <androidx.constraintlayout.widget.ConstraintLayout
         android:id="@+id/content"
diff --git a/quickstep/res/layout/keyboard_quick_switch_overview.xml b/quickstep/res/layout/keyboard_quick_switch_overview.xml
index e7b1f23..4a9b023 100644
--- a/quickstep/res/layout/keyboard_quick_switch_overview.xml
+++ b/quickstep/res/layout/keyboard_quick_switch_overview.xml
@@ -22,7 +22,7 @@
     android:layout_height="@dimen/keyboard_quick_switch_taskview_height"
     android:clipToOutline="true"
     android:importantForAccessibility="yes"
-    launcher:borderColor="?androidprv:attr/materialColorOutline">
+    launcher:focusBorderColor="?androidprv:attr/materialColorOutline">
 
     <androidx.constraintlayout.widget.ConstraintLayout
         android:id="@+id/content"
diff --git a/quickstep/res/layout/keyboard_quick_switch_taskview.xml b/quickstep/res/layout/keyboard_quick_switch_taskview.xml
index 4d213fa..6ed3c6e 100644
--- a/quickstep/res/layout/keyboard_quick_switch_taskview.xml
+++ b/quickstep/res/layout/keyboard_quick_switch_taskview.xml
@@ -23,7 +23,7 @@
     android:importantForAccessibility="yes"
     android:background="@drawable/keyboard_quick_switch_task_view_background"
     android:clipToOutline="true"
-    launcher:borderColor="?androidprv:attr/materialColorOutline">
+    launcher:focusBorderColor="?androidprv:attr/materialColorOutline">
 
     <androidx.constraintlayout.widget.ConstraintLayout
         android:id="@+id/content"
diff --git a/quickstep/res/layout/task.xml b/quickstep/res/layout/task.xml
index 4865aef..29c9992 100644
--- a/quickstep/res/layout/task.xml
+++ b/quickstep/res/layout/task.xml
@@ -24,7 +24,8 @@
     android:clipChildren="false"
     android:defaultFocusHighlightEnabled="false"
     android:focusable="true"
-    launcher:borderColor="?androidprv:attr/materialColorOutline">
+    launcher:focusBorderColor="?androidprv:attr/materialColorOutline"
+    launcher:hoverBorderColor="?androidprv:attr/materialColorPrimary">
 
     <com.android.quickstep.views.TaskThumbnailView
         android:id="@+id/snapshot"
diff --git a/quickstep/res/layout/task_desktop.xml b/quickstep/res/layout/task_desktop.xml
index fd82c66..06f4d06 100644
--- a/quickstep/res/layout/task_desktop.xml
+++ b/quickstep/res/layout/task_desktop.xml
@@ -25,7 +25,8 @@
     android:clipToOutline="true"
     android:defaultFocusHighlightEnabled="false"
     android:focusable="true"
-    launcher:borderColor="?androidprv:attr/materialColorOutline">
+    launcher:focusBorderColor="?androidprv:attr/materialColorOutline"
+    launcher:hoverBorderColor="?androidprv:attr/materialColorPrimary">
 
     <View
         android:id="@+id/background"
diff --git a/quickstep/res/layout/task_grouped.xml b/quickstep/res/layout/task_grouped.xml
index c9fa9c0..75ff626 100644
--- a/quickstep/res/layout/task_grouped.xml
+++ b/quickstep/res/layout/task_grouped.xml
@@ -29,7 +29,8 @@
     android:clipChildren="false"
     android:defaultFocusHighlightEnabled="false"
     android:focusable="true"
-    launcher:borderColor="?androidprv:attr/materialColorOutline">
+    launcher:focusBorderColor="?androidprv:attr/materialColorOutline"
+    launcher:hoverBorderColor="?androidprv:attr/materialColorPrimary">
 
     <com.android.quickstep.views.TaskThumbnailView
         android:id="@+id/snapshot"
diff --git a/quickstep/res/values/attrs.xml b/quickstep/res/values/attrs.xml
index fb51919..7288774 100644
--- a/quickstep/res/values/attrs.xml
+++ b/quickstep/res/values/attrs.xml
@@ -26,7 +26,8 @@
      -->
     <declare-styleable name="TaskView">
         <!-- Border color for a keyboard quick switch task views -->
-        <attr name="borderColor" format="color" />
+        <attr name="focusBorderColor" format="color" />
+        <attr name="hoverBorderColor" format="color" />
     </declare-styleable>
 
     <!--
diff --git a/quickstep/res/values/dimens.xml b/quickstep/res/values/dimens.xml
index e4f6555..b0e91a1 100644
--- a/quickstep/res/values/dimens.xml
+++ b/quickstep/res/values/dimens.xml
@@ -38,6 +38,8 @@
     <dimen name="task_thumbnail_icon_size">48dp</dimen>
     <!--  The icon size for the focused task, placed in center of touch target  -->
     <dimen name="task_thumbnail_icon_drawable_size">44dp</dimen>
+    <!--  The border width shown when task is hovered  -->
+    <dimen name="task_hover_border_width">4dp</dimen>
     <!--  The space under the focused task icon  -->
     <dimen name="overview_task_margin">16dp</dimen>
     <!--  The horizontal space between tasks  -->
diff --git a/quickstep/src/com/android/launcher3/taskbar/KeyboardQuickSwitchTaskView.java b/quickstep/src/com/android/launcher3/taskbar/KeyboardQuickSwitchTaskView.java
index 8a11b57..3e1a6ae 100644
--- a/quickstep/src/com/android/launcher3/taskbar/KeyboardQuickSwitchTaskView.java
+++ b/quickstep/src/com/android/launcher3/taskbar/KeyboardQuickSwitchTaskView.java
@@ -80,7 +80,7 @@
         setWillNotDraw(false);
 
         mBorderColor = ta.getColor(
-                R.styleable.TaskView_borderColor, DEFAULT_BORDER_COLOR);
+                R.styleable.TaskView_focusBorderColor, DEFAULT_BORDER_COLOR);
         ta.recycle();
     }
 
diff --git a/quickstep/src/com/android/quickstep/views/TaskView.java b/quickstep/src/com/android/quickstep/views/TaskView.java
index 5301c7c..6b0843c 100644
--- a/quickstep/src/com/android/quickstep/views/TaskView.java
+++ b/quickstep/src/com/android/quickstep/views/TaskView.java
@@ -97,7 +97,6 @@
 import com.android.quickstep.RemoteTargetGluer.RemoteTargetHandle;
 import com.android.quickstep.TaskAnimationManager;
 import com.android.quickstep.TaskIconCache;
-import com.android.quickstep.TaskOverlayFactory;
 import com.android.quickstep.TaskThumbnailCache;
 import com.android.quickstep.TaskUtils;
 import com.android.quickstep.TaskViewUtils;
@@ -413,7 +412,9 @@
 
     private boolean mIsClickableAsLiveTile = true;
 
-    @Nullable private final BorderAnimator mBorderAnimator;
+    @Nullable private final BorderAnimator mFocusBorderAnimator;
+
+    @Nullable private final BorderAnimator mHoverBorderAnimator;
 
     public TaskView(Context context) {
         this(context, null);
@@ -439,23 +440,40 @@
         boolean keyboardFocusHighlightEnabled = FeatureFlags.ENABLE_KEYBOARD_QUICK_SWITCH.get()
                 || DesktopTaskView.DESKTOP_MODE_SUPPORTED;
 
-        setWillNotDraw(!keyboardFocusHighlightEnabled);
+        boolean willDrawBorder =
+                keyboardFocusHighlightEnabled || FeatureFlags.ENABLE_CURSOR_HOVER_STATES.get();
+        setWillNotDraw(!willDrawBorder);
 
-        TypedArray ta = context.obtainStyledAttributes(
-                attrs, R.styleable.TaskView, defStyleAttr, defStyleRes);
+        if (willDrawBorder) {
+            TypedArray styledAttrs = context.obtainStyledAttributes(
+                    attrs, R.styleable.TaskView, defStyleAttr, defStyleRes);
 
-        mBorderAnimator = !keyboardFocusHighlightEnabled
-                ? null
-                : new BorderAnimator(
-                        /* borderRadiusPx= */ (int) mCurrentFullscreenParams.mCornerRadius,
-                        /* borderColor= */ ta.getColor(
-                                R.styleable.TaskView_borderColor, DEFAULT_BORDER_COLOR),
-                        /* borderAnimationParams= */ new BorderAnimator.SimpleParams(
-                                /* borderWidthPx= */ context.getResources().getDimensionPixelSize(
-                                        R.dimen.keyboard_quick_switch_border_width),
-                                /* boundsBuilder= */ this::updateBorderBounds,
-                                /* targetView= */ this));
-        ta.recycle();
+            mFocusBorderAnimator = keyboardFocusHighlightEnabled ? new BorderAnimator(
+                    /* borderRadiusPx= */ (int) mCurrentFullscreenParams.mCornerRadius,
+                    /* borderColor= */ styledAttrs.getColor(
+                            R.styleable.TaskView_focusBorderColor, DEFAULT_BORDER_COLOR),
+                    /* borderAnimationParams= */ new BorderAnimator.SimpleParams(
+                            /* borderWidthPx= */ context.getResources().getDimensionPixelSize(
+                                    R.dimen.keyboard_quick_switch_border_width),
+                            /* boundsBuilder= */ this::updateBorderBounds,
+                            /* targetView= */ this)) : null;
+
+            mHoverBorderAnimator =
+                    FeatureFlags.ENABLE_CURSOR_HOVER_STATES.get() ? new BorderAnimator(
+                            /* borderRadiusPx= */ (int) mCurrentFullscreenParams.mCornerRadius,
+                            /* borderColor= */ styledAttrs.getColor(
+                                    R.styleable.TaskView_hoverBorderColor, DEFAULT_BORDER_COLOR),
+                            /* borderAnimationParams= */ new BorderAnimator.SimpleParams(
+                                    /* borderWidthPx= */ context.getResources()
+                                            .getDimensionPixelSize(R.dimen.task_hover_border_width),
+                                    /* boundsBuilder= */ this::updateBorderBounds,
+                                    /* targetView= */ this)) : null;
+
+            styledAttrs.recycle();
+        } else {
+            mFocusBorderAnimator = null;
+            mHoverBorderAnimator = null;
+        }
     }
 
     protected void updateBorderBounds(Rect bounds) {
@@ -509,16 +527,48 @@
     @Override
     protected void onFocusChanged(boolean gainFocus, int direction, Rect previouslyFocusedRect) {
         super.onFocusChanged(gainFocus, direction, previouslyFocusedRect);
-        if (mBorderAnimator != null) {
-            mBorderAnimator.buildAnimator(gainFocus).start();
+        if (mFocusBorderAnimator != null) {
+            mFocusBorderAnimator.buildAnimator(gainFocus).start();
+        }
+    }
+
+    @Override
+    public boolean onHoverEvent(MotionEvent event) {
+        if (FeatureFlags.ENABLE_CURSOR_HOVER_STATES.get()) {
+            switch (event.getAction()) {
+                case MotionEvent.ACTION_HOVER_ENTER:
+                    mHoverBorderAnimator.buildAnimator(/* isAppearing= */ true).start();
+                    break;
+                case MotionEvent.ACTION_HOVER_EXIT:
+                    mHoverBorderAnimator.buildAnimator(/* isAppearing= */ false).start();
+                    break;
+                default:
+                    break;
+            }
+        }
+        return super.onHoverEvent(event);
+    }
+
+    @Override
+    public boolean onInterceptHoverEvent(MotionEvent event) {
+        if (FeatureFlags.ENABLE_CURSOR_HOVER_STATES.get()) {
+            // avoid triggering hover event on child elements which would cause HOVER_EXIT for this
+            // task view
+            return true;
+        } else {
+            return super.onInterceptHoverEvent(event);
         }
     }
 
     @Override
     public void draw(Canvas canvas) {
         super.draw(canvas);
-        if (mBorderAnimator != null) {
-            mBorderAnimator.drawBorder(canvas);
+        if (mFocusBorderAnimator != null) {
+            mFocusBorderAnimator.drawBorder(canvas);
+        }
+
+        if (mHoverBorderAnimator != null) {
+            mHoverBorderAnimator.drawBorder(canvas);
         }
     }