Merge "Import translations. DO NOT MERGE" into ub-launcher3-master
diff --git a/quickstep/libs/sysui_shared.jar b/quickstep/libs/sysui_shared.jar
index f5c6149..fec7317 100644
--- a/quickstep/libs/sysui_shared.jar
+++ b/quickstep/libs/sysui_shared.jar
Binary files differ
diff --git a/quickstep/src/com/android/launcher3/uioverrides/UiFactory.java b/quickstep/src/com/android/launcher3/uioverrides/UiFactory.java
index c1590f6..a10583c 100644
--- a/quickstep/src/com/android/launcher3/uioverrides/UiFactory.java
+++ b/quickstep/src/com/android/launcher3/uioverrides/UiFactory.java
@@ -18,8 +18,6 @@
 
 import static com.android.launcher3.LauncherState.NORMAL;
 import static com.android.launcher3.LauncherState.OVERVIEW;
-import static com.android.launcher3.Utilities.getPrefs;
-import static com.android.quickstep.OverviewInteractionState.KEY_SWIPE_UP_ENABLED;
 import static com.android.launcher3.LauncherState.ALL_APPS;
 
 import android.content.Context;
@@ -39,8 +37,8 @@
 public class UiFactory {
 
     public static TouchController[] createTouchControllers(Launcher launcher) {
-        SharedPreferences prefs = getPrefs(launcher);
-        boolean swipeUpEnabled = prefs.getBoolean(KEY_SWIPE_UP_ENABLED, true);
+        boolean swipeUpEnabled = OverviewInteractionState.getInstance(launcher)
+                .isSwipeUpGestureEnabled();
         if (!swipeUpEnabled) {
             return new TouchController[] {
                     launcher.getDragController(),
diff --git a/quickstep/src/com/android/quickstep/OverviewInteractionState.java b/quickstep/src/com/android/quickstep/OverviewInteractionState.java
index 22b1757..471262b 100644
--- a/quickstep/src/com/android/quickstep/OverviewInteractionState.java
+++ b/quickstep/src/com/android/quickstep/OverviewInteractionState.java
@@ -21,13 +21,14 @@
 import static com.android.systemui.shared.system.NavigationBarCompat.FLAG_HIDE_BACK_BUTTON;
 import static com.android.systemui.shared.system.NavigationBarCompat.FLAG_SHOW_OVERVIEW_BUTTON;
 
+import android.content.ContentResolver;
 import android.content.Context;
-import android.content.SharedPreferences;
-import android.content.SharedPreferences.OnSharedPreferenceChangeListener;
+import android.database.ContentObserver;
 import android.os.Handler;
 import android.os.Looper;
 import android.os.Message;
 import android.os.RemoteException;
+import android.provider.Settings;
 import android.support.annotation.WorkerThread;
 import android.util.Log;
 
@@ -47,7 +48,7 @@
  *
  * @see com.android.systemui.shared.system.NavigationBarCompat.InteractionType and associated flags.
  */
-public class OverviewInteractionState implements OnSharedPreferenceChangeListener {
+public class OverviewInteractionState {
 
     private static final String TAG = "OverviewFlags";
 
@@ -70,12 +71,13 @@
         return INSTANCE;
     }
 
-    public static final String KEY_SWIPE_UP_ENABLED = "pref_enable_quickstep";
-
     private static final int MSG_SET_PROXY = 200;
     private static final int MSG_SET_BACK_BUTTON_VISIBLE = 201;
     private static final int MSG_SET_SWIPE_UP_ENABLED = 202;
 
+    private static final String SWIPE_UP_SETTING_NAME = "swipe_up_to_switch_apps_enabled";
+    private final SwipeUpGestureEnabledSettingObserver mSwipeUpSettingObserver;
+
     private final Handler mUiHandler;
     private final Handler mBgHandler;
 
@@ -88,19 +90,13 @@
         mUiHandler = new Handler(this::handleUiMessage);
         mBgHandler = new Handler(UiThreadHelper.getBackgroundLooper(), this::handleBgMessage);
 
-        SharedPreferences prefs = getPrefs(context);
-        prefs.registerOnSharedPreferenceChangeListener(this);
-        onSharedPreferenceChanged(prefs, KEY_SWIPE_UP_ENABLED);
+        mSwipeUpSettingObserver = new SwipeUpGestureEnabledSettingObserver(mUiHandler,
+                context.getContentResolver());
+        mSwipeUpSettingObserver.register();
     }
 
-    @Override
-    public void onSharedPreferenceChanged(SharedPreferences prefs, String s) {
-        if (KEY_SWIPE_UP_ENABLED.equals(s)) {
-            mUiHandler.removeMessages(MSG_SET_SWIPE_UP_ENABLED);
-            boolean swipeUpEnabled = prefs.getBoolean(s, true);
-            mUiHandler.obtainMessage(MSG_SET_SWIPE_UP_ENABLED,
-                    swipeUpEnabled ? 1 : 0, 0).sendToTarget();
-        }
+    public boolean isSwipeUpGestureEnabled() {
+        return mSwipeUpEnabled;
     }
 
     public void setBackButtonVisible(boolean visible) {
@@ -152,4 +148,32 @@
             Log.w(TAG, "Unable to update overview interaction flags", e);
         }
     }
+
+    private class SwipeUpGestureEnabledSettingObserver extends ContentObserver {
+        private Handler mHandler;
+        private ContentResolver mResolver;
+
+        SwipeUpGestureEnabledSettingObserver(Handler handler, ContentResolver resolver) {
+            super(handler);
+            mHandler = handler;
+            mResolver = resolver;
+        }
+
+        public void register() {
+            mResolver.registerContentObserver(Settings.Secure.getUriFor(SWIPE_UP_SETTING_NAME),
+                    false, this);
+            mSwipeUpEnabled = getValue();
+        }
+
+        @Override
+        public void onChange(boolean selfChange) {
+            super.onChange(selfChange);
+            mHandler.removeMessages(MSG_SET_SWIPE_UP_ENABLED);
+            mHandler.obtainMessage(MSG_SET_SWIPE_UP_ENABLED, getValue() ? 1 : 0, 0).sendToTarget();
+        }
+
+        private boolean getValue() {
+            return Settings.Secure.getInt(mResolver, SWIPE_UP_SETTING_NAME, 0) == 1;
+        }
+    }
 }
diff --git a/quickstep/src/com/android/quickstep/QuickScrubController.java b/quickstep/src/com/android/quickstep/QuickScrubController.java
index fd089b5..ea9d009 100644
--- a/quickstep/src/com/android/quickstep/QuickScrubController.java
+++ b/quickstep/src/com/android/quickstep/QuickScrubController.java
@@ -138,17 +138,26 @@
     }
 
     public void snapToNextTaskIfAvailable() {
-        if (!mStartedFromHome && mInQuickScrub && mRecentsView.getChildCount() > 0) {
-            mRecentsView.snapToPage(mRecentsView.getNextPage() + 1, QUICK_SCRUB_START_DURATION);
+        if (mInQuickScrub && mRecentsView.getChildCount() > 0) {
+            int pageToGoTo = mStartedFromHome ? 0 : mRecentsView.getNextPage() + 1;
+            goToPageWithHaptic(pageToGoTo, QUICK_SCRUB_START_DURATION, true /* forceHaptic */);
         }
     }
 
     private void goToPageWithHaptic(int pageToGoTo) {
+        goToPageWithHaptic(pageToGoTo, -1 /* overrideDuration */, false /* forceHaptic */);
+    }
+
+    private void goToPageWithHaptic(int pageToGoTo, int overrideDuration, boolean forceHaptic) {
         pageToGoTo = Utilities.boundToRange(pageToGoTo, 0, mRecentsView.getPageCount() - 1);
-        if (pageToGoTo != mRecentsView.getNextPage()) {
-            int duration = Math.abs(pageToGoTo - mRecentsView.getNextPage())
+        boolean snappingToPage = pageToGoTo != mRecentsView.getNextPage();
+        if (snappingToPage) {
+            int duration = overrideDuration > -1 ? overrideDuration
+                    : Math.abs(pageToGoTo - mRecentsView.getNextPage())
                             * QUICKSCRUB_SNAP_DURATION_PER_PAGE;
             mRecentsView.snapToPage(pageToGoTo, duration);
+        }
+        if (snappingToPage || forceHaptic) {
             mRecentsView.performHapticFeedback(HapticFeedbackConstants.VIRTUAL_KEY,
                     HapticFeedbackConstants.FLAG_IGNORE_VIEW_SETTING);
         }
diff --git a/quickstep/src/com/android/quickstep/WindowTransformSwipeHandler.java b/quickstep/src/com/android/quickstep/WindowTransformSwipeHandler.java
index fe9f0c3..06e6556 100644
--- a/quickstep/src/com/android/quickstep/WindowTransformSwipeHandler.java
+++ b/quickstep/src/com/android/quickstep/WindowTransformSwipeHandler.java
@@ -31,6 +31,7 @@
 import android.app.ActivityManager.RunningTaskInfo;
 import android.content.Context;
 import android.content.res.Resources;
+import android.graphics.Canvas;
 import android.graphics.Point;
 import android.graphics.Rect;
 import android.os.Build;
@@ -73,6 +74,7 @@
 import com.android.systemui.shared.system.RecentsAnimationControllerCompat;
 import com.android.systemui.shared.system.RemoteAnimationTargetCompat;
 import com.android.systemui.shared.system.TransactionCompat;
+import com.android.systemui.shared.system.WindowCallbacksCompat;
 import com.android.systemui.shared.system.WindowManagerWrapper;
 
 import java.util.StringJoiner;
@@ -645,24 +647,30 @@
 
         synchronized (mRecentsAnimationWrapper) {
             if (mRecentsAnimationWrapper.controller != null) {
-                TransactionCompat transaction = new TransactionCompat();
                 for (RemoteAnimationTargetCompat app : mRecentsAnimationWrapper.targets) {
                     if (app.mode == MODE_CLOSING) {
                         // Update the screenshot of the task
                         ThumbnailData thumbnail =
                                 mRecentsAnimationWrapper.controller.screenshotTask(app.taskId);
-                        TaskView taskView = mRecentsView.updateThumbnail(app.taskId, thumbnail);
+                        final TaskView taskView =
+                                mRecentsView.updateThumbnail(app.taskId, thumbnail);
                         if (taskView != null) {
                             taskView.setAlpha(1);
+
                             // Defer finishing the animation until the next launcher frame with the
                             // new thumbnail
-                            mActivityControlHelper.executeOnNextDraw(mActivity, taskView,
-                                    finishTransitionRunnable);
-                            finishTransitionPosted = true;
+                            finishTransitionPosted = new WindowCallbacksCompat(taskView) {
+
+                                @Override
+                                public void onPostDraw(Canvas canvas) {
+                                    finishTransitionRunnable.run();
+                                    detach();
+                                }
+                            }.attach();
+                            break;
                         }
                     }
                 }
-                transaction.apply();
             }
         }
         if (!finishTransitionPosted) {
diff --git a/src/com/android/launcher3/PagedView.java b/src/com/android/launcher3/PagedView.java
index 15bf76d..9da5cf0 100644
--- a/src/com/android/launcher3/PagedView.java
+++ b/src/com/android/launcher3/PagedView.java
@@ -695,7 +695,11 @@
     public boolean requestChildRectangleOnScreen(View child, Rect rectangle, boolean immediate) {
         int page = indexToPage(indexOfChild(child));
         if (page != mCurrentPage || !mScroller.isFinished()) {
-            snapToPage(page);
+            if (immediate) {
+                setCurrentPage(page);
+            } else {
+                snapToPage(page);
+            }
             return true;
         }
         return false;