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/quickstep/src/com/android/launcher3/uioverrides/states/AllAppsState.java b/quickstep/src/com/android/launcher3/uioverrides/states/AllAppsState.java
index 4e03971..a81bdd5 100644
--- a/quickstep/src/com/android/launcher3/uioverrides/states/AllAppsState.java
+++ b/quickstep/src/com/android/launcher3/uioverrides/states/AllAppsState.java
@@ -22,7 +22,9 @@
 
 import com.android.launcher3.Launcher;
 import com.android.launcher3.LauncherState;
+import com.android.launcher3.R;
 import com.android.launcher3.allapps.AllAppsContainerView;
+import com.android.launcher3.util.Themes;
 
 /**
  * Definition for AllApps state
@@ -92,7 +94,7 @@
     }
 
     @Override
-    public float getWorkspaceScrimAlpha(Launcher launcher) {
-        return 1;
+    public int getWorkspaceScrimColor(Launcher launcher) {
+        return Themes.getAttrColor(launcher, R.attr.allAppsScrimColor);
     }
 }
diff --git a/quickstep/src/com/android/launcher3/uioverrides/states/OverviewState.java b/quickstep/src/com/android/launcher3/uioverrides/states/OverviewState.java
index 30c07b0..135c478 100644
--- a/quickstep/src/com/android/launcher3/uioverrides/states/OverviewState.java
+++ b/quickstep/src/com/android/launcher3/uioverrides/states/OverviewState.java
@@ -29,6 +29,7 @@
 import com.android.launcher3.R;
 import com.android.launcher3.Workspace;
 import com.android.launcher3.config.FeatureFlags;
+import com.android.launcher3.util.Themes;
 import com.android.quickstep.SysUINavigationMode;
 import com.android.quickstep.util.LayoutUtils;
 import com.android.quickstep.views.RecentsView;
@@ -108,8 +109,8 @@
     }
 
     @Override
-    public float getWorkspaceScrimAlpha(Launcher launcher) {
-        return 1f;
+    public int getWorkspaceScrimColor(Launcher launcher) {
+        return Themes.getAttrColor(launcher, R.attr.overviewScrimColor);
     }
 
     @Override
diff --git a/quickstep/src/com/android/launcher3/uioverrides/touchcontrollers/NoButtonNavbarToOverviewTouchController.java b/quickstep/src/com/android/launcher3/uioverrides/touchcontrollers/NoButtonNavbarToOverviewTouchController.java
index 694998c..2d95ce2 100644
--- a/quickstep/src/com/android/launcher3/uioverrides/touchcontrollers/NoButtonNavbarToOverviewTouchController.java
+++ b/quickstep/src/com/android/launcher3/uioverrides/touchcontrollers/NoButtonNavbarToOverviewTouchController.java
@@ -16,7 +16,7 @@
 
 package com.android.launcher3.uioverrides.touchcontrollers;
 
-import static com.android.launcher3.LauncherAnimUtils.VIEW_ALPHA;
+import static com.android.launcher3.LauncherAnimUtils.VIEW_BACKGROUND_COLOR;
 import static com.android.launcher3.LauncherAnimUtils.newCancelListener;
 import static com.android.launcher3.LauncherState.ALL_APPS;
 import static com.android.launcher3.LauncherState.HINT_STATE;
@@ -127,11 +127,11 @@
         }
 
         if (mFromState == NORMAL && mToState == HINT_STATE) {
-            mNormalToHintOverviewScrimAnimator = ObjectAnimator.ofFloat(
+            mNormalToHintOverviewScrimAnimator = ObjectAnimator.ofArgb(
                     mLauncher.getScrimView(),
-                    VIEW_ALPHA,
-                    mFromState.getWorkspaceScrimAlpha(mLauncher),
-                    mToState.getWorkspaceScrimAlpha(mLauncher));
+                    VIEW_BACKGROUND_COLOR,
+                    mFromState.getWorkspaceScrimColor(mLauncher),
+                    mToState.getWorkspaceScrimColor(mLauncher));
         }
         mStartedOverview = false;
         mReachedOverview = false;
diff --git a/quickstep/src/com/android/launcher3/uioverrides/touchcontrollers/NoButtonQuickSwitchTouchController.java b/quickstep/src/com/android/launcher3/uioverrides/touchcontrollers/NoButtonQuickSwitchTouchController.java
index 77b0804..12de4a6 100644
--- a/quickstep/src/com/android/launcher3/uioverrides/touchcontrollers/NoButtonQuickSwitchTouchController.java
+++ b/quickstep/src/com/android/launcher3/uioverrides/touchcontrollers/NoButtonQuickSwitchTouchController.java
@@ -15,7 +15,6 @@
  */
 package com.android.launcher3.uioverrides.touchcontrollers;
 
-import static com.android.launcher3.LauncherAnimUtils.VIEW_ALPHA;
 import static com.android.launcher3.LauncherAnimUtils.newCancelListener;
 import static com.android.launcher3.LauncherState.NORMAL;
 import static com.android.launcher3.LauncherState.OVERVIEW;
@@ -232,8 +231,8 @@
         //   - OverviewScrim
         PendingAnimation xAnim = new PendingAnimation((long) (mXRange * 2));
         xAnim.setFloat(mRecentsView, ADJACENT_PAGE_OFFSET, scaleAndOffset[1], LINEAR);
-        xAnim.setFloat(mLauncher.getScrimView(), VIEW_ALPHA,
-                toState.getWorkspaceScrimAlpha(mLauncher), LINEAR);
+        xAnim.setViewBackgroundColor(mLauncher.getScrimView(),
+                toState.getWorkspaceScrimColor(mLauncher), LINEAR);
         mXOverviewAnim = xAnim.createPlaybackController();
         mXOverviewAnim.dispatchOnStart();
 
diff --git a/res/color-v31/overview_scrim.xml b/res/color-v31/overview_scrim.xml
new file mode 100644
index 0000000..8079995
--- /dev/null
+++ b/res/color-v31/overview_scrim.xml
@@ -0,0 +1,18 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!-- Copyright (C) 2021 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.
+-->
+<selector xmlns:android="http://schemas.android.com/apk/res/android">
+  <item android:color="@android:color/system_neutral2_500" android:lStar="87" />
+</selector>
diff --git a/res/color-v31/overview_scrim_dark.xml b/res/color-v31/overview_scrim_dark.xml
new file mode 100644
index 0000000..b8ed774
--- /dev/null
+++ b/res/color-v31/overview_scrim_dark.xml
@@ -0,0 +1,18 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!-- Copyright (C) 2021 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.
+-->
+<selector xmlns:android="http://schemas.android.com/apk/res/android">
+  <item android:color="@android:color/system_neutral1_800" />
+</selector>
diff --git a/res/color/overview_scrim.xml b/res/color/overview_scrim.xml
new file mode 100644
index 0000000..48cf576
--- /dev/null
+++ b/res/color/overview_scrim.xml
@@ -0,0 +1,18 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!-- Copyright (C) 2021 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.
+-->
+<selector xmlns:android="http://schemas.android.com/apk/res/android">
+  <item android:color="#30000000" />
+</selector>
diff --git a/res/color/overview_scrim_dark.xml b/res/color/overview_scrim_dark.xml
new file mode 100644
index 0000000..48cf576
--- /dev/null
+++ b/res/color/overview_scrim_dark.xml
@@ -0,0 +1,18 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!-- Copyright (C) 2021 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.
+-->
+<selector xmlns:android="http://schemas.android.com/apk/res/android">
+  <item android:color="#30000000" />
+</selector>
diff --git a/res/layout/launcher.xml b/res/layout/launcher.xml
index f34e685..039d8d3 100644
--- a/res/layout/launcher.xml
+++ b/res/layout/launcher.xml
@@ -66,8 +66,7 @@
             android:layout_width="match_parent"
             android:layout_height="match_parent"
             android:id="@+id/scrim_view"
-            android:background="?attr/allAppsScrimColor"
-            android:alpha="0" />
+            android:background="@android:color/transparent" />
 
         <include
             android:id="@+id/apps_view"
diff --git a/res/values/attrs.xml b/res/values/attrs.xml
index 7fe53d5..df42828 100644
--- a/res/values/attrs.xml
+++ b/res/values/attrs.xml
@@ -36,6 +36,7 @@
     <attr name="widgetsTheme" format="reference" />
     <attr name="iconOnlyShortcutColor" format="color" />
     <attr name="eduHalfSheetBGColor" format="color" />
+    <attr name="overviewScrimColor" format="color" />
 
     <attr name="folderDotColor" format="color" />
     <attr name="folderFillColor" format="color" />
diff --git a/res/values/styles.xml b/res/values/styles.xml
index bae1485..beeae4b 100644
--- a/res/values/styles.xml
+++ b/res/values/styles.xml
@@ -58,6 +58,7 @@
         <item name="eduHalfSheetBGColor">?android:attr/colorAccent</item>
         <item name="disabledIconAlpha">.54</item>
         <item name="gridColor">?android:attr/colorAccent</item>
+        <item name="overviewScrimColor">@color/overview_scrim</item>
 
         <item name="android:windowTranslucentStatus">false</item>
         <item name="android:windowTranslucentNavigation">false</item>
@@ -115,6 +116,7 @@
         <item name="iconOnlyShortcutColor">#B3FFFFFF</item>
         <item name="workProfileOverlayTextColor">@android:color/white</item>
         <item name="eduHalfSheetBGColor">#DD000000</item>
+        <item name="overviewScrimColor">@color/overview_scrim_dark</item>
     </style>
 
     <style name="LauncherTheme.Dark.DarkMainColor" parent="@style/LauncherTheme.Dark">
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;
+    }
 }
diff --git a/src_ui_overrides/com/android/launcher3/uioverrides/states/AllAppsState.java b/src_ui_overrides/com/android/launcher3/uioverrides/states/AllAppsState.java
index 53748b7..978c321 100644
--- a/src_ui_overrides/com/android/launcher3/uioverrides/states/AllAppsState.java
+++ b/src_ui_overrides/com/android/launcher3/uioverrides/states/AllAppsState.java
@@ -23,6 +23,7 @@
 import com.android.launcher3.Launcher;
 import com.android.launcher3.LauncherState;
 import com.android.launcher3.R;
+import com.android.launcher3.util.Themes;
 
 /**
  * Definition for AllApps state
@@ -76,7 +77,7 @@
     }
 
     @Override
-    public float getWorkspaceScrimAlpha(Launcher launcher) {
-        return 1;
+    public int getWorkspaceScrimColor(Launcher launcher) {
+        return Themes.getAttrColor(launcher, R.attr.allAppsScrimColor);
     }
 }
diff --git a/src_ui_overrides/com/android/launcher3/uioverrides/states/OverviewState.java b/src_ui_overrides/com/android/launcher3/uioverrides/states/OverviewState.java
index e85e505..d154317 100644
--- a/src_ui_overrides/com/android/launcher3/uioverrides/states/OverviewState.java
+++ b/src_ui_overrides/com/android/launcher3/uioverrides/states/OverviewState.java
@@ -19,7 +19,10 @@
 
 import android.content.Context;
 
+import com.android.launcher3.Launcher;
 import com.android.launcher3.LauncherState;
+import com.android.launcher3.R;
+import com.android.launcher3.util.Themes;
 
 /**
  * Definition for overview state
@@ -56,4 +59,9 @@
     public static OverviewState newSplitSelectState(int id) {
         return new OverviewState(id);
     }
+
+    @Override
+    public int getWorkspaceScrimColor(Launcher launcher) {
+        return Themes.getAttrColor(launcher, R.attr.overviewScrimColor);
+    }
 }