Merge "Implementing available part of UX spec for DW toast" into ub-launcher3-master
diff --git a/quickstep/src/com/android/quickstep/ActivityControlHelper.java b/quickstep/src/com/android/quickstep/ActivityControlHelper.java
index 1678f06..c3df9c7 100644
--- a/quickstep/src/com/android/quickstep/ActivityControlHelper.java
+++ b/quickstep/src/com/android/quickstep/ActivityControlHelper.java
@@ -21,6 +21,7 @@
 import static com.android.launcher3.LauncherState.BACKGROUND_APP;
 import static com.android.launcher3.LauncherState.FAST_OVERVIEW;
 import static com.android.launcher3.LauncherState.OVERVIEW;
+import static com.android.launcher3.allapps.AllAppsTransitionController.ALL_APPS_PROGRESS_SPRING;
 import static com.android.launcher3.anim.Interpolators.LINEAR;
 import static com.android.launcher3.states.RotationHelper.REQUEST_LOCK;
 import static com.android.quickstep.TouchConsumer.INTERACTION_NORMAL;
@@ -295,7 +296,8 @@
 
             AnimatorSet anim = new AnimatorSet();
             if (!activity.getDeviceProfile().isVerticalBarLayout()) {
-                Animator shiftAnim = new SpringObjectAnimator(activity.getAllAppsController(),
+                Animator shiftAnim = new SpringObjectAnimator<>(activity.getAllAppsController(),
+                        ALL_APPS_PROGRESS_SPRING, "allAppsSpringFromACH",
                         activity.getAllAppsController().getShiftRange(),
                         fromState.getVerticalProgress(activity),
                         endState.getVerticalProgress(activity));
diff --git a/src/com/android/launcher3/ProgressInterface.java b/src/com/android/launcher3/ProgressInterface.java
new file mode 100644
index 0000000..663d8ba
--- /dev/null
+++ b/src/com/android/launcher3/ProgressInterface.java
@@ -0,0 +1,26 @@
+/*
+ * Copyright (C) 2019 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;
+
+/**
+ * Progress is defined as a value with range [0, 1], and is specific to each implementor.
+ * It is used when there is a transition from one state of the UI to another.
+ */
+public interface ProgressInterface {
+    void setProgress(float progress);
+    float getProgress();
+}
\ No newline at end of file
diff --git a/src/com/android/launcher3/allapps/AllAppsTransitionController.java b/src/com/android/launcher3/allapps/AllAppsTransitionController.java
index 962c25b..e8e93fe 100644
--- a/src/com/android/launcher3/allapps/AllAppsTransitionController.java
+++ b/src/com/android/launcher3/allapps/AllAppsTransitionController.java
@@ -23,17 +23,16 @@
 import com.android.launcher3.LauncherState;
 import com.android.launcher3.LauncherStateManager.AnimationConfig;
 import com.android.launcher3.LauncherStateManager.StateHandler;
+import com.android.launcher3.ProgressInterface;
 import com.android.launcher3.R;
 import com.android.launcher3.anim.AnimationSuccessListener;
 import com.android.launcher3.anim.AnimatorSetBuilder;
 import com.android.launcher3.anim.SpringObjectAnimator;
 import com.android.launcher3.anim.PropertySetter;
-import com.android.launcher3.anim.SpringObjectAnimator.SpringProperty;
 import com.android.launcher3.util.Themes;
 import com.android.launcher3.views.ScrimView;
 
 import androidx.dynamicanimation.animation.FloatPropertyCompat;
-import androidx.dynamicanimation.animation.SpringAnimation;
 
 /**
  * Handles AllApps view transition.
@@ -45,7 +44,8 @@
  * If release velocity < THRES1, snap according to either top or bottom depending on whether it's
  * closer to top or closer to the page indicator.
  */
-public class AllAppsTransitionController implements StateHandler, OnDeviceProfileChangeListener {
+public class AllAppsTransitionController implements StateHandler, OnDeviceProfileChangeListener,
+        ProgressInterface {
 
     public static final Property<AllAppsTransitionController, Float> ALL_APPS_PROGRESS =
             new Property<AllAppsTransitionController, Float>(Float.class, "allAppsProgress") {
@@ -74,40 +74,6 @@
         }
     };
 
-    /**
-     * Property that either sets the progress directly or animates the progress via a spring.
-     */
-    public static class AllAppsSpringProperty extends
-            SpringProperty<AllAppsTransitionController, Float> {
-
-        SpringAnimation mSpring;
-        boolean useSpring = false;
-
-        public AllAppsSpringProperty(SpringAnimation spring) {
-            super(Float.class, "allAppsSpringProperty");
-            mSpring = spring;
-        }
-
-        @Override
-        public Float get(AllAppsTransitionController controller) {
-            return controller.getProgress();
-        }
-
-        @Override
-        public void set(AllAppsTransitionController controller, Float progress) {
-            if (useSpring) {
-                mSpring.animateToFinalPosition(progress);
-            } else {
-                controller.setProgress(progress);
-            }
-        }
-
-        @Override
-        public void switchToSpring() {
-            useSpring = true;
-        }
-    }
-
     private AllAppsContainerView mAppsView;
     private ScrimView mScrimView;
 
@@ -161,6 +127,7 @@
      * @see #setState(LauncherState)
      * @see #setStateWithAnimation(LauncherState, AnimatorSetBuilder, AnimationConfig)
      */
+    @Override
     public void setProgress(float progress) {
         mProgress = progress;
         mScrimView.setProgress(progress);
@@ -185,6 +152,7 @@
         }
     }
 
+    @Override
     public float getProgress() {
         return mProgress;
     }
@@ -223,8 +191,8 @@
         Interpolator interpolator = config.userControlled ? LINEAR : toState == OVERVIEW
                 ? builder.getInterpolator(ANIM_OVERVIEW_SCALE, FAST_OUT_SLOW_IN)
                 : FAST_OUT_SLOW_IN;
-        Animator anim = new SpringObjectAnimator(this, 1f / mShiftRange, mProgress,
-                targetProgress);
+        Animator anim = new SpringObjectAnimator<>(this, ALL_APPS_PROGRESS_SPRING,
+                "allAppsSpringFromAATC", 1f / mShiftRange, mProgress, targetProgress);
         anim.setDuration(config.duration);
         anim.setInterpolator(builder.getInterpolator(ANIM_VERTICAL_PROGRESS, interpolator));
         anim.addListener(getProgressAnimatorListener());
diff --git a/src/com/android/launcher3/anim/SpringObjectAnimator.java b/src/com/android/launcher3/anim/SpringObjectAnimator.java
index 4f037ef..4ece909 100644
--- a/src/com/android/launcher3/anim/SpringObjectAnimator.java
+++ b/src/com/android/launcher3/anim/SpringObjectAnimator.java
@@ -23,12 +23,12 @@
 import android.util.Log;
 import android.util.Property;
 
-import com.android.launcher3.allapps.AllAppsTransitionController;
-import com.android.launcher3.allapps.AllAppsTransitionController.AllAppsSpringProperty;
+import com.android.launcher3.ProgressInterface;
 
 import java.util.ArrayList;
 
 import androidx.dynamicanimation.animation.DynamicAnimation.OnAnimationEndListener;
+import androidx.dynamicanimation.animation.FloatPropertyCompat;
 import androidx.dynamicanimation.animation.SpringAnimation;
 import androidx.dynamicanimation.animation.SpringForce;
 
@@ -38,17 +38,17 @@
  * This animator allows for an object's property to be be controlled by an {@link ObjectAnimator} or
  * a {@link SpringAnimation}. It extends ValueAnimator so it can be used in an AnimatorSet.
  */
-public class SpringObjectAnimator extends ValueAnimator {
+public class SpringObjectAnimator<T extends ProgressInterface> extends ValueAnimator {
 
     private static final String TAG = "SpringObjectAnimator";
     private static boolean DEBUG = false;
 
-    private AllAppsTransitionController mObject;
+    private T mObject;
     private ObjectAnimator mObjectAnimator;
     private float[] mValues;
 
     private SpringAnimation mSpring;
-    private AllAppsSpringProperty mProperty;
+    private SpringProperty<T> mProperty;
 
     private ArrayList<AnimatorListener> mListeners;
     private boolean mSpringEnded = false;
@@ -58,16 +58,16 @@
     private static final float SPRING_DAMPING_RATIO = 0.9f;
     private static final float SPRING_STIFFNESS = 600f;
 
-    public SpringObjectAnimator(AllAppsTransitionController object, float minimumVisibleChange,
-            float... values) {
+    public SpringObjectAnimator(T object, FloatPropertyCompat<T> floatProperty,
+            String name, float minimumVisibleChange, float... values) {
         mObject = object;
-        mSpring = new SpringAnimation(object, AllAppsTransitionController.ALL_APPS_PROGRESS_SPRING);
+        mSpring = new SpringAnimation(object, floatProperty);
         mSpring.setMinimumVisibleChange(minimumVisibleChange);
         mSpring.setSpring(new SpringForce(0)
                 .setDampingRatio(SPRING_DAMPING_RATIO)
                 .setStiffness(SPRING_STIFFNESS));
         mSpring.setStartVelocity(0.01f);
-        mProperty = new AllAppsSpringProperty(mSpring);
+        mProperty = new SpringProperty<T>(name, mSpring);
         mObjectAnimator = ObjectAnimator.ofFloat(object, mProperty, values);
         mValues = values;
         mListeners = new ArrayList<>();
@@ -261,13 +261,32 @@
         mObjectAnimator.setCurrentPlayTime(playTime);
     }
 
-    public static abstract class SpringProperty<T, V> extends Property<T, V> {
+    public static class SpringProperty<T extends ProgressInterface> extends Property<T, Float> {
 
-        public SpringProperty(Class<V> type, String name) {
-            super(type, name);
+        boolean useSpring = false;
+        final SpringAnimation mSpring;
+
+        public SpringProperty(String name, SpringAnimation spring) {
+            super(Float.class, name);
+            mSpring = spring;
         }
 
-        abstract public void switchToSpring();
-    }
+        public void switchToSpring() {
+            useSpring = true;
+        }
 
+        @Override
+        public Float get(T object) {
+            return object.getProgress();
+        }
+
+        @Override
+        public void set(T object, Float progress) {
+            if (useSpring) {
+                mSpring.animateToFinalPosition(progress);
+            } else {
+                object.setProgress(progress);
+            }
+        }
+    }
 }
diff --git a/src/com/android/launcher3/compat/AlphabeticIndexCompat.java b/src/com/android/launcher3/compat/AlphabeticIndexCompat.java
index 84e82e3..a7c0a47 100644
--- a/src/com/android/launcher3/compat/AlphabeticIndexCompat.java
+++ b/src/com/android/launcher3/compat/AlphabeticIndexCompat.java
@@ -12,6 +12,8 @@
 import java.lang.reflect.Method;
 import java.util.Locale;
 
+import androidx.annotation.NonNull;
+
 public class AlphabeticIndexCompat {
     private static final String TAG = "AlphabeticIndexCompat";
 
@@ -53,7 +55,7 @@
     /**
      * Computes the section name for an given string {@param s}.
      */
-    public String computeSectionName(CharSequence cs) {
+    public String computeSectionName(@NonNull CharSequence cs) {
         String s = Utilities.trim(cs);
         String sectionName = mBaseIndex.getBucketLabel(mBaseIndex.getBucketIndex(s));
         if (Utilities.trim(sectionName).isEmpty() && s.length() > 0) {
@@ -89,7 +91,7 @@
         /**
          * Returns the index of the bucket in which the given string should appear.
          */
-        protected int getBucketIndex(String s) {
+        protected int getBucketIndex(@NonNull String s) {
             if (s.isEmpty()) {
                 return UNKNOWN_BUCKET_INDEX;
             }
diff --git a/src_shortcuts_overrides/com/android/launcher3/model/WidgetsModel.java b/src_shortcuts_overrides/com/android/launcher3/model/WidgetsModel.java
index 9a17ec6..7a7f828 100644
--- a/src_shortcuts_overrides/com/android/launcher3/model/WidgetsModel.java
+++ b/src_shortcuts_overrides/com/android/launcher3/model/WidgetsModel.java
@@ -69,7 +69,8 @@
         WidgetItemComparator widgetComparator = new WidgetItemComparator();
         for (Map.Entry<PackageItemInfo, ArrayList<WidgetItem>> entry : mWidgetsList.entrySet()) {
             WidgetListRowEntry row = new WidgetListRowEntry(entry.getKey(), entry.getValue());
-            row.titleSectionName = indexer.computeSectionName(row.pkgItem.title);
+            row.titleSectionName = (row.pkgItem.title == null) ? "" :
+                    indexer.computeSectionName(row.pkgItem.title);
             Collections.sort(row.widgets, widgetComparator);
             result.add(row);
         }
diff --git a/tests/tapl/com/android/launcher3/tapl/Background.java b/tests/tapl/com/android/launcher3/tapl/Background.java
index 27e0954..08d2889 100644
--- a/tests/tapl/com/android/launcher3/tapl/Background.java
+++ b/tests/tapl/com/android/launcher3/tapl/Background.java
@@ -64,7 +64,7 @@
 
             mLauncher.swipe(
                     navBar.getVisibleBounds().centerX(), navBar.getVisibleBounds().centerY(),
-                    navBar.getVisibleBounds().centerX(), height - 300);
+                    navBar.getVisibleBounds().centerX(), height - 400);
         } else {
             mLauncher.getSystemUiObject("recent_apps").click();
         }