Allow Workspace Scrim to be colored per state

Make it possible to set the color of workspace scrim to a different color
per state. Motivated by making Overview Scrim and All Apps scrims different
colors.

Bug: 186253733
Test: Local build and flash
Change-Id: Id7c38ce3c9173308eedfcb7592ececa7bd6bf220
diff --git a/src/com/android/launcher3/LauncherAnimUtils.java b/src/com/android/launcher3/LauncherAnimUtils.java
index 803f8d2..b56c012 100644
--- a/src/com/android/launcher3/LauncherAnimUtils.java
+++ b/src/com/android/launcher3/LauncherAnimUtils.java
@@ -19,6 +19,8 @@
 import android.animation.Animator;
 import android.animation.Animator.AnimatorListener;
 import android.animation.AnimatorListenerAdapter;
+import android.graphics.Color;
+import android.graphics.drawable.ColorDrawable;
 import android.graphics.drawable.Drawable;
 import android.util.FloatProperty;
 import android.util.IntProperty;
@@ -135,6 +137,22 @@
                         }
                     };
 
+    public static final IntProperty<View> VIEW_BACKGROUND_COLOR =
+            new IntProperty<View>("backgroundColor") {
+                @Override
+                public void setValue(View view, int color) {
+                    view.setBackgroundColor(color);
+                }
+
+                @Override
+                public Integer get(View view) {
+                    if (!(view.getBackground() instanceof ColorDrawable)) {
+                        return Color.TRANSPARENT;
+                    }
+                    return ((ColorDrawable) view.getBackground()).getColor();
+                }
+            };
+
     /**
      * Utility method to create an {@link AnimatorListener} which executes a callback on animation
      * cancel.
diff --git a/src/com/android/launcher3/LauncherState.java b/src/com/android/launcher3/LauncherState.java
index 58df9c8..4c11725 100644
--- a/src/com/android/launcher3/LauncherState.java
+++ b/src/com/android/launcher3/LauncherState.java
@@ -30,6 +30,7 @@
 import static com.android.launcher3.testing.TestProtocol.SPRING_LOADED_STATE_ORDINAL;
 
 import android.content.Context;
+import android.graphics.Color;
 import android.view.animation.Interpolator;
 
 import com.android.launcher3.statemanager.BaseState;
@@ -217,8 +218,12 @@
         return 0;
     }
 
-    public float getWorkspaceScrimAlpha(Launcher launcher) {
-        return 0;
+    /**
+     * What color should the workspace scrim be in when at rest in this state.
+     * Return {@link Color#TRANSPARENT} for no scrim.
+     */
+    public int getWorkspaceScrimColor(Launcher launcher) {
+        return Color.TRANSPARENT;
     }
 
     /**
diff --git a/src/com/android/launcher3/WorkspaceStateTransitionAnimation.java b/src/com/android/launcher3/WorkspaceStateTransitionAnimation.java
index ed854dc..b35d702 100644
--- a/src/com/android/launcher3/WorkspaceStateTransitionAnimation.java
+++ b/src/com/android/launcher3/WorkspaceStateTransitionAnimation.java
@@ -166,8 +166,9 @@
         propertySetter.setFloat(sysUiScrim, SYSUI_PROGRESS,
                 state.hasFlag(FLAG_HAS_SYS_UI_SCRIM) ? 1 : 0, LINEAR);
 
-        propertySetter.setViewAlpha(mLauncher.getScrimView(),
-                state.getWorkspaceScrimAlpha(mLauncher),
+
+        propertySetter.setViewBackgroundColor(mLauncher.getScrimView(),
+                state.getWorkspaceScrimColor(mLauncher),
                 config.getInterpolator(ANIM_WORKSPACE_SCRIM_FADE, LINEAR));
     }
 
diff --git a/src/com/android/launcher3/anim/PendingAnimation.java b/src/com/android/launcher3/anim/PendingAnimation.java
index 9068331..8057475 100644
--- a/src/com/android/launcher3/anim/PendingAnimation.java
+++ b/src/com/android/launcher3/anim/PendingAnimation.java
@@ -16,6 +16,7 @@
 package com.android.launcher3.anim;
 
 import static com.android.launcher3.LauncherAnimUtils.SUCCESS_TRANSITION_PROGRESS;
+import static com.android.launcher3.LauncherAnimUtils.VIEW_BACKGROUND_COLOR;
 import static com.android.launcher3.anim.AnimatorPlaybackController.addAnimationHoldersRecur;
 
 import android.animation.Animator;
@@ -25,6 +26,7 @@
 import android.animation.ObjectAnimator;
 import android.animation.TimeInterpolator;
 import android.animation.ValueAnimator;
+import android.graphics.drawable.ColorDrawable;
 import android.util.FloatProperty;
 import android.util.IntProperty;
 import android.view.View;
@@ -85,6 +87,17 @@
     }
 
     @Override
+    public void setViewBackgroundColor(View view, int color, TimeInterpolator interpolator) {
+        if (view == null || (view.getBackground() instanceof ColorDrawable
+                && ((ColorDrawable) view.getBackground()).getColor() == color)) {
+            return;
+        }
+        ObjectAnimator anim = ObjectAnimator.ofArgb(view, VIEW_BACKGROUND_COLOR, color);
+        anim.setInterpolator(interpolator);
+        add(anim);
+    }
+
+    @Override
     public <T> void setFloat(T target, FloatProperty<T> property, float value,
             TimeInterpolator interpolator) {
         if (property.get(target) == value) {
diff --git a/src/com/android/launcher3/anim/PropertySetter.java b/src/com/android/launcher3/anim/PropertySetter.java
index 2ce620b..729523f 100644
--- a/src/com/android/launcher3/anim/PropertySetter.java
+++ b/src/com/android/launcher3/anim/PropertySetter.java
@@ -41,6 +41,15 @@
     }
 
     /**
+     * Sets the background color of the provided view using the provided interpolator.
+     */
+    default void setViewBackgroundColor(View view, int color, TimeInterpolator interpolator) {
+        if (view != null) {
+            view.setBackgroundColor(color);
+        }
+    }
+
+    /**
      * Updates the float property of the target using the provided interpolator
      */
     default <T> void setFloat(T target, FloatProperty<T> property, float value,
diff --git a/src/com/android/launcher3/states/HintState.java b/src/com/android/launcher3/states/HintState.java
index 22c9d5b..8b52016 100644
--- a/src/com/android/launcher3/states/HintState.java
+++ b/src/com/android/launcher3/states/HintState.java
@@ -19,8 +19,12 @@
 
 import android.content.Context;
 
+import androidx.core.graphics.ColorUtils;
+
 import com.android.launcher3.Launcher;
 import com.android.launcher3.LauncherState;
+import com.android.launcher3.R;
+import com.android.launcher3.util.Themes;
 
 /**
  * Scale down workspace/hotseat to hint at going to either overview (on pause) or first home screen.
@@ -49,8 +53,9 @@
     }
 
     @Override
-    public float getWorkspaceScrimAlpha(Launcher launcher) {
-        return 0.4f;
+    public int getWorkspaceScrimColor(Launcher launcher) {
+        return ColorUtils.setAlphaComponent(
+                Themes.getAttrColor(launcher, R.attr.overviewScrimColor), 100);
     }
 
     @Override
diff --git a/src/com/android/launcher3/views/ScrimView.java b/src/com/android/launcher3/views/ScrimView.java
index c9424de..722f578 100644
--- a/src/com/android/launcher3/views/ScrimView.java
+++ b/src/com/android/launcher3/views/ScrimView.java
@@ -19,6 +19,7 @@
 
 import android.content.Context;
 import android.graphics.Rect;
+import android.graphics.drawable.ColorDrawable;
 import android.util.AttributeSet;
 import android.view.View;
 
@@ -26,9 +27,7 @@
 
 import com.android.launcher3.Insettable;
 import com.android.launcher3.Launcher;
-import com.android.launcher3.R;
 import com.android.launcher3.util.SystemUiController;
-import com.android.launcher3.util.Themes;
 
 /**
  * Simple scrim which draws a flat color
@@ -36,13 +35,10 @@
 public class ScrimView extends View implements Insettable {
     private static final float STATUS_BAR_COLOR_FORCE_UPDATE_THRESHOLD = 0.9f;
 
-    private final boolean mIsScrimDark;
     private SystemUiController mSystemUiController;
 
     public ScrimView(Context context, AttributeSet attrs) {
         super(context, attrs);
-        mIsScrimDark = ColorUtils.calculateLuminance(
-                Themes.getAttrColor(context, R.attr.allAppsScrimColor)) < 0.5f;
         setFocusable(false);
     }
 
@@ -61,6 +57,12 @@
     }
 
     @Override
+    public void setBackgroundColor(int color) {
+        updateSysUiColors();
+        super.setBackgroundColor(color);
+    }
+
+    @Override
     protected void onVisibilityChanged(View changedView, int visibility) {
         super.onVisibilityChanged(changedView, visibility);
         updateSysUiColors();
@@ -72,7 +74,7 @@
         boolean forceChange =
                 getVisibility() == VISIBLE && getAlpha() > STATUS_BAR_COLOR_FORCE_UPDATE_THRESHOLD;
         if (forceChange) {
-            getSystemUiController().updateUiState(UI_STATE_SCRIM_VIEW, !mIsScrimDark);
+            getSystemUiController().updateUiState(UI_STATE_SCRIM_VIEW, !isScrimDark());
         } else {
             getSystemUiController().updateUiState(UI_STATE_SCRIM_VIEW, 0);
         }
@@ -84,4 +86,14 @@
         }
         return mSystemUiController;
     }
+
+    private boolean isScrimDark() {
+        if (!(getBackground() instanceof ColorDrawable)) {
+            throw new IllegalStateException(
+                    "ScrimView must have a ColorDrawable background, this one has: "
+                            + getBackground());
+        }
+        return ColorUtils.calculateLuminance(
+                ((ColorDrawable) getBackground()).getColor()) < 0.5f;
+    }
 }