Add Z scaling during unfold to launcher

The unfold progresses are mapped to 0.85 - 1 range and set as a scale for launcher.

In case of multiple scale animations for workspace and hotseat, they are combined using MultiScaleProperty (e.g. opening an app while unfolding/going to all apps while unfolding). Note that this is a pretty difficult scenario to be in. If that happens, we multiply all values and bound the result between the max and min values.

Bug: 217368525
Test: atest MultiScalePropertyTest and manually
Change-Id: I6131c39f36deade0b7280c72edda2d72045344e9
diff --git a/src/com/android/launcher3/LauncherAnimUtils.java b/src/com/android/launcher3/LauncherAnimUtils.java
index b56c012..4300392 100644
--- a/src/com/android/launcher3/LauncherAnimUtils.java
+++ b/src/com/android/launcher3/LauncherAnimUtils.java
@@ -27,6 +27,8 @@
 import android.view.View;
 import android.view.ViewGroup.LayoutParams;
 
+import com.android.launcher3.util.MultiScalePropertyFactory;
+
 public class LauncherAnimUtils {
     /**
      * Durations for various state animations. These are not defined in resources to allow
@@ -64,6 +66,25 @@
                 }
             };
 
+    /**
+     * Property to set the scale of workspace and hotseat. The value is based on a combination
+     * of all the ones set, to have a smooth experience even in the case of overlapping scaling
+     * animation.
+     */
+    public static final MultiScalePropertyFactory<View> SCALE_PROPERTY_FACTORY =
+            new MultiScalePropertyFactory<View>("scale_property") {
+                @Override
+                protected void apply(View view, float scale) {
+                    view.setScaleX(scale);
+                    view.setScaleY(scale);
+                }
+            };
+
+    public static final int SCALE_INDEX_UNFOLD_ANIMATION = 1;
+    public static final int SCALE_INDEX_UNLOCK_ANIMATION = 2;
+    public static final int SCALE_INDEX_WORKSPACE_STATE = 3;
+    public static final int SCALE_INDEX_REVEAL_ANIM = 4;
+
     /** Increase the duration if we prevented the fling, as we are going against a high velocity. */
     public static int blockedFlingDurationFactor(float velocity) {
         return (int) Utilities.boundToRange(Math.abs(velocity) / 2, 2f, 6f);