Merge "Animate launcher when launching recent tasks" into ub-launcher3-master
diff --git a/Android.mk b/Android.mk
index 256d95d..a1cba4a2 100644
--- a/Android.mk
+++ b/Android.mk
@@ -20,9 +20,13 @@
 # Prebuilt Java Libraries
 #
 include $(CLEAR_VARS)
-LOCAL_PREBUILT_STATIC_JAVA_LIBRARIES := \
-    libSharedSystemUI:quickstep/libs/sysui_shared.jar
-include $(BUILD_MULTI_PREBUILT)
+LOCAL_MODULE := libSharedSystemUI
+LOCAL_MODULE_TAGS := optional
+LOCAL_MODULE_CLASS := JAVA_LIBRARIES
+LOCAL_SRC_FILES := quickstep/libs/sysui_shared.jar
+LOCAL_UNINSTALLABLE_MODULE := true
+LOCAL_SDK_VERSION := current
+include $(BUILD_PREBUILT)
 
 #
 # Build rule for Launcher3 app.
diff --git a/quickstep/src/com/android/quickstep/OtherActivityTouchConsumer.java b/quickstep/src/com/android/quickstep/OtherActivityTouchConsumer.java
index db50a00..353bd9c 100644
--- a/quickstep/src/com/android/quickstep/OtherActivityTouchConsumer.java
+++ b/quickstep/src/com/android/quickstep/OtherActivityTouchConsumer.java
@@ -157,7 +157,7 @@
                 mActivePointerId = ev.getPointerId(0);
                 mDownPos.set(ev.getX(), ev.getY());
                 mLastPos.set(mDownPos);
-                mTouchSlop = ViewConfiguration.get(this).getScaledTouchSlop();
+                mTouchSlop = ViewConfiguration.get(this).getScaledPagingTouchSlop();
                 mTouchThresholdCrossed = false;
 
                 // Start the window animation on down to give more time for launcher to draw if the
diff --git a/quickstep/src/com/android/quickstep/TaskMenuView.java b/quickstep/src/com/android/quickstep/TaskMenuView.java
index 52b2400..6bbcb37 100644
--- a/quickstep/src/com/android/quickstep/TaskMenuView.java
+++ b/quickstep/src/com/android/quickstep/TaskMenuView.java
@@ -144,6 +144,7 @@
         icon.setBounds(0, 0, iconSize, iconSize);
         mTaskIconAndName.setCompoundDrawables(null, icon, null, null);
         mTaskIconAndName.setText(TaskUtils.getTitle(mLauncher, taskView.getTask()));
+        mTaskIconAndName.setOnClickListener(v -> close(true));
 
         for (TaskSystemShortcut menuOption : MENU_OPTIONS) {
             OnClickListener onClickListener = menuOption.getOnClickListener(mLauncher, taskView);
diff --git a/quickstep/src/com/android/quickstep/WindowTransformSwipeHandler.java b/quickstep/src/com/android/quickstep/WindowTransformSwipeHandler.java
index 11b4e5a..19942c3 100644
--- a/quickstep/src/com/android/quickstep/WindowTransformSwipeHandler.java
+++ b/quickstep/src/com/android/quickstep/WindowTransformSwipeHandler.java
@@ -737,7 +737,7 @@
                         if (taskView != null) {
                             // Defer finishing the animation until the next launcher frame with the
                             // new thumbnail
-                            ViewOnDrawExecutor executor = new ViewOnDrawExecutor(mMainExecutor) {
+                            ViewOnDrawExecutor executor = new ViewOnDrawExecutor() {
                                 @Override
                                 public void onViewDetachedFromWindow(View v) {
                                     if (!isCompleted()) {
diff --git a/src/com/android/launcher3/IconCache.java b/src/com/android/launcher3/IconCache.java
index 957a5e5..d0581a2 100644
--- a/src/com/android/launcher3/IconCache.java
+++ b/src/com/android/launcher3/IconCache.java
@@ -785,7 +785,7 @@
     }
 
     private static final class IconDB extends SQLiteCacheHelper {
-        private final static int RELEASE_VERSION = 20;
+        private final static int RELEASE_VERSION = 21;
 
         private final static String TABLE_NAME = "icons";
         private final static String COLUMN_ROWID = "rowid";
diff --git a/src/com/android/launcher3/Launcher.java b/src/com/android/launcher3/Launcher.java
index ed8d39c..55bfef6 100644
--- a/src/com/android/launcher3/Launcher.java
+++ b/src/com/android/launcher3/Launcher.java
@@ -305,12 +305,11 @@
 
         LauncherAppState app = LauncherAppState.getInstance(this);
         mOldConfig = new Configuration(getResources().getConfiguration());
+        mModel = app.setLauncher(this);
         initDeviceProfile(app.getInvariantDeviceProfile());
 
         mSharedPrefs = Utilities.getPrefs(this);
         mIsSafeModeEnabled = getPackageManager().isSafeMode();
-        mModel = app.setLauncher(this);
-        mModelWriter = mModel.getWriter(mDeviceProfile.isVerticalBarLayout());
         mIconCache = app.getIconCache();
         mAccessibilityDelegate = new LauncherAccessibilityDelegate(this);
 
@@ -435,6 +434,7 @@
             display.getSize(mwSize);
             mDeviceProfile = mDeviceProfile.getMultiWindowProfile(this, mwSize);
         }
+        mModelWriter = mModel.getWriter(mDeviceProfile.isVerticalBarLayout());
     }
 
     @Override
diff --git a/src/com/android/launcher3/LauncherModel.java b/src/com/android/launcher3/LauncherModel.java
index a4d188f..6646b78 100644
--- a/src/com/android/launcher3/LauncherModel.java
+++ b/src/com/android/launcher3/LauncherModel.java
@@ -444,11 +444,7 @@
             if (mCallbacks != null && mCallbacks.get() != null) {
                 final Callbacks oldCallbacks = mCallbacks.get();
                 // Clear any pending bind-runnables from the synchronized load process.
-                mUiExecutor.execute(new Runnable() {
-                            public void run() {
-                                oldCallbacks.clearPendingBinds();
-                            }
-                        });
+                mUiExecutor.execute(oldCallbacks::clearPendingBinds);
 
                 // If there is already one running, tell it to stop.
                 stopLoader();
diff --git a/src/com/android/launcher3/allapps/PersonalWorkSlidingTabStrip.java b/src/com/android/launcher3/allapps/PersonalWorkSlidingTabStrip.java
index b42d4cd..a069d5d 100644
--- a/src/com/android/launcher3/allapps/PersonalWorkSlidingTabStrip.java
+++ b/src/com/android/launcher3/allapps/PersonalWorkSlidingTabStrip.java
@@ -25,9 +25,9 @@
 import android.view.View;
 import android.widget.Button;
 import android.widget.LinearLayout;
-
 import com.android.launcher3.Launcher;
 import com.android.launcher3.R;
+import com.android.launcher3.Utilities;
 import com.android.launcher3.pageindicators.PageIndicator;
 import com.android.launcher3.util.Themes;
 
@@ -47,12 +47,12 @@
     private int mSelectedIndicatorHeight;
     private int mIndicatorLeft = -1;
     private int mIndicatorRight = -1;
-    private int mIndicatorPosition = 0;
-    private float mIndicatorOffset;
+    private float mScrollOffset;
     private int mSelectedPosition = 0;
 
     private AllAppsContainerView mContainerView;
     private int mLastActivePage = 0;
+    private boolean mIsRtl;
 
     public PersonalWorkSlidingTabStrip(@NonNull Context context, @Nullable AttributeSet attrs) {
         super(context, attrs);
@@ -72,11 +72,11 @@
                 getResources().getDimensionPixelSize(R.dimen.all_apps_divider_height));
 
         mSharedPreferences = Launcher.getLauncher(getContext()).getSharedPrefs();
+        mIsRtl = Utilities.isRtl(getResources());
     }
 
-    private void updateIndicatorPosition(int position, float positionOffset) {
-        mIndicatorPosition = position;
-        mIndicatorOffset = positionOffset;
+    private void updateIndicatorPosition(float scrollOffset) {
+        mScrollOffset = scrollOffset;
         updateIndicatorPosition();
     }
 
@@ -92,32 +92,23 @@
     protected void onLayout(boolean changed, int l, int t, int r, int b) {
         super.onLayout(changed, l, t, r, b);
         updateTabTextColor(mSelectedPosition);
-        updateIndicatorPosition(mIndicatorPosition, mIndicatorOffset);
+        updateIndicatorPosition(mScrollOffset);
     }
 
     private void updateIndicatorPosition() {
-        final View tab = getChildAt(mIndicatorPosition);
-        int left, right;
-
-        if (tab != null && tab.getWidth() > 0) {
-            left = tab.getLeft();
-            right = tab.getRight();
-
-            if (mIndicatorOffset > 0f && mIndicatorPosition < getChildCount() - 1) {
-                // Draw the selection partway between the tabs
-                View nextTitle = getChildAt(mIndicatorPosition + 1);
-                left = (int) (mIndicatorOffset * nextTitle.getLeft() +
-                        (1.0f - mIndicatorOffset) * left);
-                right = (int) (mIndicatorOffset * nextTitle.getRight() +
-                        (1.0f - mIndicatorOffset) * right);
-            }
-        } else {
-            left = right = -1;
+        int left = -1, right = -1;
+        final View leftTab = getLeftTab();
+        if (leftTab != null) {
+            left = (int) (leftTab.getLeft() + leftTab.getWidth() * mScrollOffset);
+            right = left + leftTab.getWidth();
         }
-
         setIndicatorPosition(left, right);
     }
 
+    private View getLeftTab() {
+        return mIsRtl ? getChildAt(1) : getChildAt(0);
+    }
+
     private void setIndicatorPosition(int left, int right) {
         if (left != mIndicatorLeft || right != mIndicatorRight) {
             mIndicatorLeft = left;
@@ -140,7 +131,7 @@
         if (mSharedPreferences.getBoolean(KEY_SHOWED_PEEK_WORK_TAB, false)) {
             return;
         }
-        if (mIndicatorPosition != POSITION_PERSONAL) {
+        if (mLastActivePage != POSITION_PERSONAL) {
             return;
         }
         highlightWorkTab();
@@ -157,11 +148,8 @@
 
     @Override
     public void setScroll(int currentScroll, int totalScroll) {
-        if (currentScroll == totalScroll) {
-            updateIndicatorPosition(1, 0);
-        } else if (totalScroll > 0) {
-            updateIndicatorPosition(0, ((float) currentScroll) / totalScroll);
-        }
+        float scrollOffset = ((float) currentScroll) / totalScroll;
+        updateIndicatorPosition(scrollOffset);
     }
 
     @Override
diff --git a/src/com/android/launcher3/model/LoaderResults.java b/src/com/android/launcher3/model/LoaderResults.java
index 24e5b9c..5acc790 100644
--- a/src/com/android/launcher3/model/LoaderResults.java
+++ b/src/com/android/launcher3/model/LoaderResults.java
@@ -162,7 +162,7 @@
         // This ensures that the first screen is immediately visible (eg. during rotation)
         // In case of !validFirstPage, bind all pages one after other.
         final Executor deferredExecutor =
-                validFirstPage ? new ViewOnDrawExecutor(mUiExecutor) : mainExecutor;
+                validFirstPage ? new ViewOnDrawExecutor() : mainExecutor;
 
         mainExecutor.execute(new Runnable() {
             @Override
diff --git a/src/com/android/launcher3/util/ViewOnDrawExecutor.java b/src/com/android/launcher3/util/ViewOnDrawExecutor.java
index 34bdcc9..acce308 100644
--- a/src/com/android/launcher3/util/ViewOnDrawExecutor.java
+++ b/src/com/android/launcher3/util/ViewOnDrawExecutor.java
@@ -34,20 +34,14 @@
         OnAttachStateChangeListener {
 
     private final ArrayList<Runnable> mTasks = new ArrayList<>();
-    private final Executor mExecutor;
 
     private Launcher mLauncher;
     private View mAttachedView;
     private boolean mCompleted;
-    private boolean mIsExecuting;
 
     private boolean mLoadAnimationCompleted;
     private boolean mFirstDrawCompleted;
 
-    public ViewOnDrawExecutor(Executor executor) {
-        mExecutor = executor;
-    }
-
     public void attachTo(Launcher launcher) {
         attachTo(launcher, launcher.getWorkspace(), true /* waitForLoadAnimation */);
     }
@@ -89,13 +83,6 @@
         mAttachedView.post(this);
     }
 
-    /**
-     * Returns whether the executor is still queuing tasks and hasn't yet executed them.
-     */
-    public boolean canQueue() {
-        return !mIsExecuting && !mCompleted;
-    }
-
     public void onLoadAnimationCompleted() {
         mLoadAnimationCompleted = true;
         if (mAttachedView != null) {
@@ -107,7 +94,6 @@
     public void run() {
         // Post the pending tasks after both onDraw and onLoadAnimationCompleted have been called.
         if (mLoadAnimationCompleted && mFirstDrawCompleted && !mCompleted) {
-            mIsExecuting = true;
             runAllTasks();
         }
     }
@@ -115,7 +101,6 @@
     public void markCompleted() {
         mTasks.clear();
         mCompleted = true;
-        mIsExecuting = false;
         if (mAttachedView != null) {
             mAttachedView.getViewTreeObserver().removeOnDrawListener(this);
             mAttachedView.removeOnAttachStateChangeListener(this);
@@ -132,7 +117,7 @@
 
     protected void runAllTasks() {
         for (final Runnable r : mTasks) {
-            mExecutor.execute(r);
+            r.run();
         }
         markCompleted();
     }