Merge "Adding query length parameter to protobuf" into ub-launcher3-qt-dev
diff --git a/Android.bp b/Android.bp
index 5acec37..b80282e 100644
--- a/Android.bp
+++ b/Android.bp
@@ -24,6 +24,7 @@
     srcs: [
         "tests/tapl/**/*.java",
         "src/com/android/launcher3/util/SecureSettingsObserver.java",
+        "src/com/android/launcher3/ResourceUtils.java",
         "src/com/android/launcher3/TestProtocol.java",
     ],
     manifest: "tests/tapl/AndroidManifest.xml",
diff --git a/go/quickstep/res/values-sw480dp/dimens.xml b/go/quickstep/res/values-sw480dp/dimens.xml
index b48dafb..571b8a1 100644
--- a/go/quickstep/res/values-sw480dp/dimens.xml
+++ b/go/quickstep/res/values-sw480dp/dimens.xml
@@ -18,13 +18,13 @@
     <dimen name="recents_list_width">480dp</dimen>
 
     <dimen name="task_item_height">90dp</dimen>
-    <dimen name="task_item_top_margin">16dp</dimen>
-    <dimen name="task_thumbnail_icon_horiz_margin">20dp</dimen>
+    <dimen name="task_item_top_margin">24dp</dimen>
+    <dimen name="task_thumbnail_icon_horiz_margin">24dp</dimen>
 
     <dimen name="task_thumbnail_corner_radius">4dp</dimen>
 
-    <dimen name="clear_all_item_view_height">48dp</dimen>
+    <dimen name="clear_all_item_view_height">52dp</dimen>
     <dimen name="clear_all_item_view_top_margin">28dp</dimen>
     <dimen name="clear_all_item_view_bottom_margin">28dp</dimen>
-    <dimen name="clear_all_button_width">140dp</dimen>
+    <dimen name="clear_all_button_width">160dp</dimen>
 </resources>
\ No newline at end of file
diff --git a/go/quickstep/src/com/android/launcher3/GoLauncherAppTransitionManagerImpl.java b/go/quickstep/src/com/android/launcher3/GoLauncherAppTransitionManagerImpl.java
index d189c50..bcb1f5c 100644
--- a/go/quickstep/src/com/android/launcher3/GoLauncherAppTransitionManagerImpl.java
+++ b/go/quickstep/src/com/android/launcher3/GoLauncherAppTransitionManagerImpl.java
@@ -1,16 +1,20 @@
 package com.android.launcher3;
 
+import static com.android.launcher3.Utilities.postAsyncCallback;
 import static com.android.launcher3.anim.Interpolators.AGGRESSIVE_EASE;
 import static com.android.launcher3.anim.Interpolators.LINEAR;
+import static com.android.quickstep.TaskUtils.taskIsATargetWithMode;
 import static com.android.quickstep.views.IconRecentsView.CONTENT_ALPHA;
+import static com.android.systemui.shared.system.RemoteAnimationTargetCompat.MODE_OPENING;
 
 import android.animation.AnimatorSet;
 import android.animation.ObjectAnimator;
-import android.app.ActivityOptions;
 import android.content.Context;
+import android.os.Handler;
 import android.view.View;
 
 import com.android.quickstep.views.IconRecentsView;
+import com.android.systemui.shared.system.RemoteAnimationRunnerCompat;
 import com.android.systemui.shared.system.RemoteAnimationTargetCompat;
 
 /**
@@ -29,6 +33,12 @@
     }
 
     @Override
+    RemoteAnimationRunnerCompat getWallpaperOpenRunner(boolean fromUnlock) {
+        return new GoWallpaperOpenLauncherAnimationRunner(mHandler,
+                false /* startAtFrontOfQueue */, fromUnlock);
+    }
+
+    @Override
     protected void composeRecentsLaunchAnimator(AnimatorSet anim, View v,
             RemoteAnimationTargetCompat[] targets, boolean launcherClosing) {
         // Stubbed. Recents launch animation will come from the recents view itself and will not
@@ -51,4 +61,34 @@
 
         return mLauncher.getStateManager()::reapplyState;
     }
+
+    /**
+     * Remote animation runner for animation from app to Launcher. For Go, when going to recents,
+     * we need to ensure that the recents view is ready for remote animation before starting.
+     */
+    private final class GoWallpaperOpenLauncherAnimationRunner extends
+            WallpaperOpenLauncherAnimationRunner {
+        public GoWallpaperOpenLauncherAnimationRunner(Handler handler, boolean startAtFrontOfQueue,
+                boolean fromUnlock) {
+            super(handler, startAtFrontOfQueue, fromUnlock);
+        }
+
+        @Override
+        public void onCreateAnimation(RemoteAnimationTargetCompat[] targetCompats,
+                AnimationResult result) {
+            boolean isGoingToRecents =
+                    taskIsATargetWithMode(targetCompats, mLauncher.getTaskId(), MODE_OPENING)
+                    && (mLauncher.getStateManager().getState() == LauncherState.OVERVIEW);
+            if (isGoingToRecents) {
+                IconRecentsView recentsView = mLauncher.getOverviewPanel();
+                if (!recentsView.isReadyForRemoteAnim()) {
+                    recentsView.setOnReadyForRemoteAnimCallback(() ->
+                        postAsyncCallback(mHandler, () -> onCreateAnimation(targetCompats, result))
+                    );
+                    return;
+                }
+            }
+            super.onCreateAnimation(targetCompats, result);
+        }
+    }
 }
diff --git a/go/quickstep/src/com/android/quickstep/AppToOverviewAnimationProvider.java b/go/quickstep/src/com/android/quickstep/AppToOverviewAnimationProvider.java
index c228bb9..62e40d1 100644
--- a/go/quickstep/src/com/android/quickstep/AppToOverviewAnimationProvider.java
+++ b/go/quickstep/src/com/android/quickstep/AppToOverviewAnimationProvider.java
@@ -15,30 +15,20 @@
  */
 package com.android.quickstep;
 
-import static com.android.launcher3.anim.Interpolators.ACCEL_2;
-import static com.android.launcher3.anim.Interpolators.ACCEL_DEACCEL;
 import static com.android.launcher3.anim.Interpolators.FAST_OUT_SLOW_IN;
-import static com.android.quickstep.util.RemoteAnimationProvider.getLayer;
+import static com.android.quickstep.views.IconRecentsView.REMOTE_APP_TO_OVERVIEW_DURATION;
 import static com.android.systemui.shared.system.RemoteAnimationTargetCompat.MODE_CLOSING;
 import static com.android.systemui.shared.system.RemoteAnimationTargetCompat.MODE_OPENING;
 
 import android.animation.AnimatorSet;
 import android.animation.ValueAnimator;
-import android.graphics.Matrix;
-import android.graphics.Rect;
 import android.util.Log;
-import android.view.View;
-
-import androidx.annotation.NonNull;
 
 import com.android.launcher3.BaseDraggingActivity;
-import com.android.quickstep.util.MultiValueUpdateListener;
 import com.android.quickstep.util.RemoteAnimationProvider;
 import com.android.quickstep.util.RemoteAnimationTargetSet;
 import com.android.quickstep.views.IconRecentsView;
 import com.android.systemui.shared.system.RemoteAnimationTargetCompat;
-import com.android.systemui.shared.system.SyncRtSurfaceTransactionApplierCompat;
-import com.android.systemui.shared.system.SyncRtSurfaceTransactionApplierCompat.SurfaceParams;
 
 /**
  * Provider for the atomic remote window animation from the app to the overview.
@@ -47,9 +37,6 @@
  */
 final class AppToOverviewAnimationProvider<T extends BaseDraggingActivity> implements
         RemoteAnimationProvider {
-
-    private static final long APP_TO_THUMBNAIL_FADE_DURATION = 50;
-    private static final long APP_SCALE_DOWN_DURATION = 400;
     private static final String TAG = "AppToOverviewAnimationProvider";
 
     private final ActivityControlHelper<T> mHelper;
@@ -131,106 +118,17 @@
             return anim;
         }
 
-        View thumbnailView = mRecentsView.getBottomThumbnailView();
-        if (thumbnailView == null) {
-            // This can be null if there were previously 0 tasks and the recycler view has not had
-            // enough time to take in the data change, bind a new view, and lay out the new view.
-            // TODO: Have a fallback to animate to
-            if (Log.isLoggable(TAG, Log.WARN)) {
-                Log.w(TAG, "No thumbnail view for running task. Using stub animation.");
-            }
-            anim.play(ValueAnimator.ofInt(0, 1).setDuration(getRecentsLaunchDuration()));
-            return anim;
-        }
-
-        playAppScaleDownAnim(anim, closingAppTarget, recentsTarget, thumbnailView);
+        mRecentsView.playRemoteAppToRecentsAnimation(anim, closingAppTarget, recentsTarget);
 
         return anim;
     }
 
     /**
-     * Animate a closing app to scale down to the location of the thumbnail view in recents.
-     *
-     * @param anim animator set
-     * @param appTarget the app surface thats closing
-     * @param recentsTarget the surface containing recents
-     * @param thumbnailView the thumbnail view to animate to
-     */
-    private void playAppScaleDownAnim(@NonNull AnimatorSet anim,
-            @NonNull RemoteAnimationTargetCompat appTarget,
-            @NonNull RemoteAnimationTargetCompat recentsTarget, @NonNull View thumbnailView) {
-
-        // Identify where the entering remote app should animate to.
-        Rect endRect = new Rect();
-        thumbnailView.getGlobalVisibleRect(endRect);
-
-        Rect appBounds = appTarget.sourceContainerBounds;
-
-        ValueAnimator valueAnimator = ValueAnimator.ofInt(0, 1);
-        valueAnimator.setDuration(APP_SCALE_DOWN_DURATION);
-
-        SyncRtSurfaceTransactionApplierCompat surfaceApplier =
-                new SyncRtSurfaceTransactionApplierCompat(thumbnailView);
-
-        // Keep recents visible throughout the animation.
-        SurfaceParams[] params = new SurfaceParams[2];
-        // Closing app should stay on top.
-        int boostedMode = MODE_CLOSING;
-        params[0] = new SurfaceParams(recentsTarget.leash, 1f, null /* matrix */,
-                null /* windowCrop */, getLayer(recentsTarget, boostedMode), 0 /* cornerRadius */);
-
-        valueAnimator.addUpdateListener(new MultiValueUpdateListener() {
-            private final FloatProp mScaleX;
-            private final FloatProp mScaleY;
-            private final FloatProp mTranslationX;
-            private final FloatProp mTranslationY;
-            private final FloatProp mAlpha;
-
-            {
-                // Scale down and move to view location.
-                float endScaleX = ((float) endRect.width()) / appBounds.width();
-                mScaleX = new FloatProp(1f, endScaleX, 0, APP_SCALE_DOWN_DURATION,
-                        ACCEL_DEACCEL);
-                float endScaleY = ((float) endRect.height()) / appBounds.height();
-                mScaleY = new FloatProp(1f, endScaleY, 0, APP_SCALE_DOWN_DURATION,
-                        ACCEL_DEACCEL);
-                float endTranslationX = endRect.left -
-                        (appBounds.width() - thumbnailView.getWidth()) / 2.0f;
-                mTranslationX = new FloatProp(0, endTranslationX, 0, APP_SCALE_DOWN_DURATION,
-                        ACCEL_DEACCEL);
-                float endTranslationY = endRect.top -
-                        (appBounds.height() - thumbnailView.getHeight()) / 2.0f;
-                mTranslationY = new FloatProp(0, endTranslationY, 0, APP_SCALE_DOWN_DURATION,
-                        ACCEL_DEACCEL);
-
-                // Fade out quietly near the end to be replaced by the real view.
-                mAlpha = new FloatProp(1.0f, 0,
-                        APP_SCALE_DOWN_DURATION - APP_TO_THUMBNAIL_FADE_DURATION,
-                        APP_TO_THUMBNAIL_FADE_DURATION, ACCEL_2);
-            }
-
-            @Override
-            public void onUpdate(float percent) {
-                Matrix m = new Matrix();
-                m.setScale(mScaleX.value, mScaleY.value,
-                        appBounds.width() / 2.0f, appBounds.height() / 2.0f);
-                m.postTranslate(mTranslationX.value, mTranslationY.value);
-
-                params[1] = new SurfaceParams(appTarget.leash, mAlpha.value, m,
-                        null /* windowCrop */, getLayer(appTarget, boostedMode),
-                        0 /* cornerRadius */);
-                surfaceApplier.scheduleApply(params);
-            }
-        });
-        anim.play(valueAnimator);
-    }
-
-    /**
      * Get duration of animation from app to overview.
      *
      * @return duration of animation
      */
     long getRecentsLaunchDuration() {
-        return APP_SCALE_DOWN_DURATION;
+        return REMOTE_APP_TO_OVERVIEW_DURATION;
     }
 }
diff --git a/go/quickstep/src/com/android/quickstep/ContentFillItemAnimator.java b/go/quickstep/src/com/android/quickstep/ContentFillItemAnimator.java
index 9282345..808cd72 100644
--- a/go/quickstep/src/com/android/quickstep/ContentFillItemAnimator.java
+++ b/go/quickstep/src/com/android/quickstep/ContentFillItemAnimator.java
@@ -180,6 +180,7 @@
 
                     @Override
                     public void onAnimationEnd(Animator animation) {
+                        CONTENT_TRANSITION_PROGRESS.set(itemView, 1.0f);
                         dispatchChangeFinished(viewHolder, true /* oldItem */);
                         mRunningAnims.remove(anim);
                         dispatchFinishedWhenDone();
@@ -215,46 +216,43 @@
     @Override
     public void endAnimation(@NonNull ViewHolder item) {
         for (int i = mPendingAnims.size() - 1; i >= 0; i--) {
-            PendingAnimation pendAnim = mPendingAnims.get(i);
-            if (pendAnim.viewHolder == item) {
-                mPendingAnims.remove(i);
-                switch (pendAnim.animType) {
-                    case ANIM_TYPE_REMOVE:
-                        dispatchRemoveFinished(item);
-                        break;
-                    case ANIM_TYPE_CHANGE:
-                        dispatchChangeFinished(item, true /* oldItem */);
-                        break;
-                    default:
-                        break;
-                }
-            }
+            endPendingAnimation(mPendingAnims.get(i));
+            mPendingAnims.remove(i);
         }
         dispatchFinishedWhenDone();
     }
 
     @Override
     public void endAnimations() {
+        if (!isRunning()) {
+            return;
+        }
         for (int i = mPendingAnims.size() - 1; i >= 0; i--) {
-            PendingAnimation pendAnim = mPendingAnims.get(i);
-            ViewHolder item = pendAnim.viewHolder;
-            switch (pendAnim.animType) {
-                case ANIM_TYPE_REMOVE:
-                    dispatchRemoveFinished(item);
-                    break;
-                case ANIM_TYPE_CHANGE:
-                    dispatchChangeFinished(item, true /* oldItem */);
-                    break;
-                default:
-                    break;
-            }
+            endPendingAnimation(mPendingAnims.get(i));
             mPendingAnims.remove(i);
         }
-        for (int i = 0; i < mRunningAnims.size(); i++) {
+        for (int i = mRunningAnims.size() - 1; i >= 0; i--) {
             ObjectAnimator anim = mRunningAnims.get(i);
-            anim.end();
+            // This calls the on end animation callback which will set values to their end target.
+            anim.cancel();
         }
-        dispatchAnimationsFinished();
+        dispatchFinishedWhenDone();
+    }
+
+    private void endPendingAnimation(PendingAnimation pendAnim) {
+        ViewHolder item = pendAnim.viewHolder;
+        switch (pendAnim.animType) {
+            case ANIM_TYPE_REMOVE:
+                item.itemView.setAlpha(1.0f);
+                dispatchRemoveFinished(item);
+                break;
+            case ANIM_TYPE_CHANGE:
+                CONTENT_TRANSITION_PROGRESS.set(item.itemView, 1.0f);
+                dispatchChangeFinished(item, true /* oldItem */);
+                break;
+            default:
+                break;
+        }
     }
 
     @Override
diff --git a/go/quickstep/src/com/android/quickstep/FallbackActivityControllerHelper.java b/go/quickstep/src/com/android/quickstep/FallbackActivityControllerHelper.java
index bba08a4..d39a66c 100644
--- a/go/quickstep/src/com/android/quickstep/FallbackActivityControllerHelper.java
+++ b/go/quickstep/src/com/android/quickstep/FallbackActivityControllerHelper.java
@@ -45,6 +45,7 @@
     @Override
     public AnimationFactory prepareRecentsUI(RecentsActivity activity, boolean activityVisible,
             boolean animateActivity, Consumer<AnimatorPlaybackController> callback) {
+        // TODO: Logic for setting remote animation
         if (activityVisible) {
             return (transitionLength) -> { };
         }
diff --git a/go/quickstep/src/com/android/quickstep/LauncherActivityControllerHelper.java b/go/quickstep/src/com/android/quickstep/LauncherActivityControllerHelper.java
index 40db7dd..d595007 100644
--- a/go/quickstep/src/com/android/quickstep/LauncherActivityControllerHelper.java
+++ b/go/quickstep/src/com/android/quickstep/LauncherActivityControllerHelper.java
@@ -40,6 +40,7 @@
             boolean activityVisible, boolean animateActivity,
             Consumer<AnimatorPlaybackController> callback) {
         LauncherState fromState = activity.getStateManager().getState();
+        activity.<IconRecentsView>getOverviewPanel().setUsingRemoteAnimation(true);
         //TODO: Implement this based off where the recents view needs to be for app => recents anim.
         return new AnimationFactory() {
             @Override
@@ -87,6 +88,7 @@
         if (launcher == null) {
             return false;
         }
+        launcher.<IconRecentsView>getOverviewPanel().setUsingRemoteAnimation(false);
         launcher.getUserEventDispatcher().logActionCommand(
                 LauncherLogProto.Action.Command.RECENTS_BUTTON,
                 getContainerType(),
diff --git a/go/quickstep/src/com/android/quickstep/RecentsActivity.java b/go/quickstep/src/com/android/quickstep/RecentsActivity.java
index 9fb8067..7f813ce 100644
--- a/go/quickstep/src/com/android/quickstep/RecentsActivity.java
+++ b/go/quickstep/src/com/android/quickstep/RecentsActivity.java
@@ -42,7 +42,7 @@
 
     @Override
     protected void reapplyUi() {
-        //TODO: Implement this depending on how insets will affect the view.
+        // No-op. Insets are automatically re-applied in the root view.
     }
 
     @Override
@@ -67,8 +67,8 @@
     }
 
     @Override
-    protected void onStart() {
+    protected void onResume() {
         mIconRecentsView.onBeginTransitionToOverview();
-        super.onStart();
+        super.onResume();
     }
 }
diff --git a/go/quickstep/src/com/android/quickstep/fallback/GoRecentsActivityRootView.java b/go/quickstep/src/com/android/quickstep/fallback/GoRecentsActivityRootView.java
index c0ebcb5..b550011 100644
--- a/go/quickstep/src/com/android/quickstep/fallback/GoRecentsActivityRootView.java
+++ b/go/quickstep/src/com/android/quickstep/fallback/GoRecentsActivityRootView.java
@@ -16,7 +16,10 @@
 package com.android.quickstep.fallback;
 
 import android.content.Context;
+import android.graphics.Insets;
+import android.graphics.Rect;
 import android.util.AttributeSet;
+import android.view.WindowInsets;
 
 import com.android.launcher3.util.TouchController;
 import com.android.launcher3.views.BaseDragLayer;
@@ -30,5 +33,23 @@
         super(context, attrs, 1 /* alphaChannelCount */);
         // Go leaves touch control to the view itself.
         mControllers = new TouchController[0];
+        setSystemUiVisibility(SYSTEM_UI_FLAG_LAYOUT_FULLSCREEN
+                | SYSTEM_UI_FLAG_LAYOUT_HIDE_NAVIGATION
+                | SYSTEM_UI_FLAG_LAYOUT_STABLE);
+    }
+
+    @Override
+    public void setInsets(Rect insets) {
+        if (insets.equals(mInsets)) {
+            return;
+        }
+        super.setInsets(insets);
+    }
+
+    @Override
+    public WindowInsets onApplyWindowInsets(WindowInsets insets) {
+        Insets sysInsets = insets.getSystemWindowInsets();
+        setInsets(new Rect(sysInsets.left, sysInsets.top, sysInsets.right, sysInsets.bottom));
+        return insets.consumeSystemWindowInsets();
     }
 }
diff --git a/go/quickstep/src/com/android/quickstep/views/IconRecentsView.java b/go/quickstep/src/com/android/quickstep/views/IconRecentsView.java
index 7225e57..8276078 100644
--- a/go/quickstep/src/com/android/quickstep/views/IconRecentsView.java
+++ b/go/quickstep/src/com/android/quickstep/views/IconRecentsView.java
@@ -19,10 +19,14 @@
 
 import static androidx.recyclerview.widget.LinearLayoutManager.VERTICAL;
 
+import static com.android.launcher3.anim.Interpolators.ACCEL_2;
 import static com.android.quickstep.TaskAdapter.CHANGE_EVENT_TYPE_EMPTY_TO_CONTENT;
 import static com.android.quickstep.TaskAdapter.ITEM_TYPE_CLEAR_ALL;
 import static com.android.quickstep.TaskAdapter.ITEM_TYPE_TASK;
+import static com.android.quickstep.TaskAdapter.MAX_TASKS_TO_DISPLAY;
 import static com.android.quickstep.TaskAdapter.TASKS_START_POSITION;
+import static com.android.quickstep.util.RemoteAnimationProvider.getLayer;
+import static com.android.systemui.shared.system.RemoteAnimationTargetCompat.MODE_CLOSING;
 
 import android.animation.Animator;
 import android.animation.AnimatorListenerAdapter;
@@ -32,6 +36,7 @@
 import android.animation.ValueAnimator;
 import android.content.Context;
 import android.content.res.Resources;
+import android.graphics.Matrix;
 import android.graphics.Rect;
 import android.graphics.drawable.Drawable;
 import android.util.ArraySet;
@@ -40,10 +45,12 @@
 import android.view.View;
 import android.view.ViewDebug;
 import android.view.ViewTreeObserver;
+import android.view.animation.PathInterpolator;
 import android.widget.FrameLayout;
 
 import androidx.annotation.NonNull;
 import androidx.annotation.Nullable;
+import androidx.interpolator.view.animation.LinearOutSlowInInterpolator;
 import androidx.recyclerview.widget.DefaultItemAnimator;
 import androidx.recyclerview.widget.ItemTouchHelper;
 import androidx.recyclerview.widget.LinearLayoutManager;
@@ -64,7 +71,11 @@
 import com.android.quickstep.TaskHolder;
 import com.android.quickstep.TaskListLoader;
 import com.android.quickstep.TaskSwipeCallback;
+import com.android.quickstep.util.MultiValueUpdateListener;
 import com.android.systemui.shared.recents.model.Task;
+import com.android.systemui.shared.system.RemoteAnimationTargetCompat;
+import com.android.systemui.shared.system.SyncRtSurfaceTransactionApplierCompat;
+import com.android.systemui.shared.system.SyncRtSurfaceTransactionApplierCompat.SurfaceParams;
 
 import java.util.ArrayList;
 import java.util.List;
@@ -102,6 +113,22 @@
     private static final float ITEM_ANIMATE_OUT_TRANSLATION_X_RATIO = .25f;
     private static final long CLEAR_ALL_FADE_DELAY = 120;
 
+    private static final long REMOTE_TO_RECENTS_APP_SCALE_DOWN_DURATION = 300;
+    private static final long REMOTE_TO_RECENTS_VERTICAL_EASE_IN_DURATION = 400;
+    private static final long REMOTE_TO_RECENTS_ITEM_FADE_START_DELAY = 200;
+    private static final long REMOTE_TO_RECENTS_ITEM_FADE_DURATION = 217;
+    private static final long REMOTE_TO_RECENTS_ITEM_FADE_BETWEEN_DELAY = 33;
+
+    private static final PathInterpolator FAST_OUT_SLOW_IN_1 =
+            new PathInterpolator(.4f, 0f, 0f, 1f);
+    private static final PathInterpolator FAST_OUT_SLOW_IN_2 =
+            new PathInterpolator(.5f, 0f, 0f, 1f);
+    private static final LinearOutSlowInInterpolator OUT_SLOW_IN =
+            new LinearOutSlowInInterpolator();
+
+    public static final long REMOTE_APP_TO_OVERVIEW_DURATION =
+            REMOTE_TO_RECENTS_VERTICAL_EASE_IN_DURATION;
+
     /**
      * A ratio representing the view's relative placement within its padded space. For example, 0
      * is top aligned and 0.5 is centered vertically.
@@ -125,6 +152,7 @@
     private View mEmptyView;
     private View mContentView;
     private boolean mTransitionedFromApp;
+    private boolean mUsingRemoteAnimation;
     private AnimatorSet mLayoutAnimation;
     private final ArraySet<View> mLayingOutViews = new ArraySet<>();
     private Rect mInsets;
@@ -276,7 +304,9 @@
             // not be scrollable.
             mTaskLayoutManager.scrollToPositionWithOffset(TASKS_START_POSITION, 0 /* offset */);
         }
-        scheduleFadeInLayoutAnimation();
+        if (!mUsingRemoteAnimation) {
+            scheduleFadeInLayoutAnimation();
+        }
         // Load any task changes
         if (!mTaskLoader.needsToLoad()) {
             return;
@@ -315,6 +345,17 @@
     }
 
     /**
+     * Set whether we're using a custom remote animation. If so, we will not do the default layout
+     * animation when entering recents and instead wait for the remote app surface to be ready to
+     * use.
+     *
+     * @param usingRemoteAnimation true if doing a remote animation, false o/w
+     */
+    public void setUsingRemoteAnimation(boolean usingRemoteAnimation) {
+        mUsingRemoteAnimation = usingRemoteAnimation;
+    }
+
+    /**
      * Handles input from the overview button. Launch the most recent task unless we just came from
      * the app. In that case, we launch the next most recent.
      */
@@ -365,17 +406,49 @@
     }
 
     /**
-     * Get the bottom most thumbnail view to animate to.
+     * Get the bottom most task view to animate to.
      *
-     * @return the thumbnail view if laid out
+     * @return the task view
      */
-    public @Nullable View getBottomThumbnailView() {
-        ArrayList<TaskItemView> taskViews = getTaskViews();
-        if (taskViews.isEmpty()) {
-            return null;
+    private @Nullable TaskItemView getBottomTaskView() {
+        int childCount = mTaskRecyclerView.getChildCount();
+        for (int i = 0; i < childCount; i++) {
+            View view = mTaskRecyclerView.getChildAt(i);
+            if (mTaskRecyclerView.getChildViewHolder(view).getItemViewType() == ITEM_TYPE_TASK) {
+                return (TaskItemView) view;
+            }
         }
-        TaskItemView view = taskViews.get(0);
-        return view.getThumbnailView();
+        return null;
+    }
+
+    /**
+     * Whether this view has processed all data changes and is ready to animate from the app to
+     * the overview.
+     *
+     * @return true if ready to animate app to overview, false otherwise
+     */
+    public boolean isReadyForRemoteAnim() {
+        return !mTaskRecyclerView.hasPendingAdapterUpdates();
+    }
+
+    /**
+     * Set a callback for whenever this view is ready to do a remote animation from the app to
+     * overview. See {@link #isReadyForRemoteAnim()}.
+     *
+     * @param callback callback to run when view is ready to animate
+     */
+    public void setOnReadyForRemoteAnimCallback(onReadyForRemoteAnimCallback callback) {
+        mTaskRecyclerView.getViewTreeObserver().addOnGlobalLayoutListener(
+                new ViewTreeObserver.OnGlobalLayoutListener() {
+                    @Override
+                    public void onGlobalLayout() {
+                        if (isReadyForRemoteAnim()) {
+                            callback.onReadyForRemoteAnim();
+                            mTaskRecyclerView.getViewTreeObserver().
+                                    removeOnGlobalLayoutListener(this);
+                        }
+                    }
+                });
     }
 
     /**
@@ -551,10 +624,217 @@
         mLayoutAnimation.start();
     }
 
+    /**
+     * Play remote animation from app to recents. This should scale the currently closing app down
+     * to the recents thumbnail.
+     *
+     * @param anim animator set
+     * @param appTarget the app surface thats closing
+     * @param recentsTarget the surface containing recents
+     */
+    public void playRemoteAppToRecentsAnimation(@NonNull AnimatorSet anim,
+            @NonNull RemoteAnimationTargetCompat appTarget,
+            @NonNull RemoteAnimationTargetCompat recentsTarget) {
+        TaskItemView bottomView = getBottomTaskView();
+        if (bottomView == null) {
+            // This can be null if there were previously 0 tasks and the recycler view has not had
+            // enough time to take in the data change, bind a new view, and lay out the new view.
+            // TODO: Have a fallback to animate to
+            anim.play(ValueAnimator.ofInt(0, 1).setDuration(REMOTE_APP_TO_OVERVIEW_DURATION));
+        }
+        final Matrix appMatrix = new Matrix();
+        playRemoteTransYAnim(anim, appMatrix);
+        playRemoteAppScaleDownAnim(anim, appMatrix, appTarget, recentsTarget,
+                bottomView.getThumbnailView());
+        playRemoteTaskListFadeIn(anim, bottomView);
+    }
+
+    /**
+     * Play translation Y animation for the remote app to recents animation. Animates over all task
+     * views as well as the closing app, easing them into their final vertical positions.
+     *
+     * @param anim animator set to play on
+     * @param appMatrix transformation matrix for the closing app surface
+     */
+    private void playRemoteTransYAnim(@NonNull AnimatorSet anim, @NonNull Matrix appMatrix) {
+        final ArrayList<TaskItemView> views = getTaskViews();
+
+        // Start Y translation from about halfway through the tasks list to the bottom thumbnail.
+        float taskHeight = getResources().getDimension(R.dimen.task_item_height);
+        float totalTransY = -(MAX_TASKS_TO_DISPLAY / 2.0f - 1) * taskHeight;
+        for (int i = 0, size = views.size(); i < size; i++) {
+            views.get(i).setTranslationY(totalTransY);
+        }
+
+        ValueAnimator transYAnim = ValueAnimator.ofFloat(totalTransY, 0);
+        transYAnim.setDuration(REMOTE_TO_RECENTS_VERTICAL_EASE_IN_DURATION);
+        transYAnim.setInterpolator(FAST_OUT_SLOW_IN_2);
+        transYAnim.addUpdateListener(valueAnimator -> {
+            float transY = (float) valueAnimator.getAnimatedValue();
+            for (int i = 0, size = views.size(); i < size; i++) {
+                views.get(i).setTranslationY(transY);
+            }
+            appMatrix.postTranslate(0, transY - totalTransY);
+        });
+        transYAnim.addListener(new AnimatorListenerAdapter() {
+            @Override
+            public void onAnimationEnd(Animator animation) {
+                for (int i = 0, size = views.size(); i < size; i++) {
+                    views.get(i).setTranslationY(0);
+                }
+            }
+        });
+        anim.play(transYAnim);
+    }
+
+    /**
+     * Play the scale down animation for the remote app to recents animation where the app surface
+     * scales down to where the thumbnail is.
+     *
+     * @param anim animator set to play on
+     * @param appMatrix transformation matrix for the app surface
+     * @param appTarget closing app target
+     * @param recentsTarget opening recents target
+     * @param thumbnailView thumbnail view to animate to
+     */
+    private void playRemoteAppScaleDownAnim(@NonNull AnimatorSet anim, @NonNull Matrix appMatrix,
+            @NonNull RemoteAnimationTargetCompat appTarget,
+            @NonNull RemoteAnimationTargetCompat recentsTarget,
+            @NonNull View thumbnailView) {
+        // Identify where the entering remote app should animate to.
+        Rect endRect = new Rect();
+        thumbnailView.getGlobalVisibleRect(endRect);
+        Rect appBounds = appTarget.sourceContainerBounds;
+
+        SyncRtSurfaceTransactionApplierCompat surfaceApplier =
+                new SyncRtSurfaceTransactionApplierCompat(this);
+
+        // Keep recents visible throughout the animation.
+        SurfaceParams[] params = new SurfaceParams[2];
+        // Closing app should stay on top.
+        int boostedMode = MODE_CLOSING;
+        params[0] = new SurfaceParams(recentsTarget.leash, 1f, null /* matrix */,
+                null /* windowCrop */, getLayer(recentsTarget, boostedMode), 0 /* cornerRadius */);
+
+        ValueAnimator remoteAppAnim = ValueAnimator.ofInt(0, 1);
+        remoteAppAnim.setDuration(REMOTE_TO_RECENTS_VERTICAL_EASE_IN_DURATION);
+        remoteAppAnim.addUpdateListener(new MultiValueUpdateListener() {
+            private final FloatProp mScaleX;
+            private final FloatProp mScaleY;
+            private final FloatProp mTranslationX;
+            private final FloatProp mTranslationY;
+            private final FloatProp mAlpha;
+
+            {
+                // Scale down and move to view location.
+                float endScaleX = ((float) endRect.width()) / appBounds.width();
+                mScaleX = new FloatProp(1f, endScaleX, 0, REMOTE_TO_RECENTS_APP_SCALE_DOWN_DURATION,
+                        FAST_OUT_SLOW_IN_1);
+                float endScaleY = ((float) endRect.height()) / appBounds.height();
+                mScaleY = new FloatProp(1f, endScaleY, 0, REMOTE_TO_RECENTS_APP_SCALE_DOWN_DURATION,
+                        FAST_OUT_SLOW_IN_1);
+                float endTranslationX = endRect.left -
+                        (appBounds.width() - thumbnailView.getWidth()) / 2.0f;
+                mTranslationX = new FloatProp(0, endTranslationX, 0,
+                        REMOTE_TO_RECENTS_APP_SCALE_DOWN_DURATION, FAST_OUT_SLOW_IN_1);
+                float endTranslationY = endRect.top -
+                        (appBounds.height() - thumbnailView.getHeight()) / 2.0f;
+                mTranslationY = new FloatProp(0, endTranslationY, 0,
+                        REMOTE_TO_RECENTS_APP_SCALE_DOWN_DURATION, FAST_OUT_SLOW_IN_2);
+                mAlpha = new FloatProp(1.0f, 0, 0, REMOTE_TO_RECENTS_APP_SCALE_DOWN_DURATION,
+                        ACCEL_2);
+            }
+
+            @Override
+            public void onUpdate(float percent) {
+                appMatrix.preScale(mScaleX.value, mScaleY.value,
+                        appBounds.width() / 2.0f, appBounds.height() / 2.0f);
+                appMatrix.postTranslate(mTranslationX.value, mTranslationY.value);
+
+                params[1] = new SurfaceParams(appTarget.leash, mAlpha.value, appMatrix,
+                        null /* windowCrop */, getLayer(appTarget, boostedMode),
+                        0 /* cornerRadius */);
+                surfaceApplier.scheduleApply(params);
+                appMatrix.reset();
+            }
+        });
+        anim.play(remoteAppAnim);
+    }
+
+    /**
+     * Play task list fade in animation as part of remote app to recents animation. This animation
+     * ensures that the task views in the recents list fade in from bottom to top.
+     *
+     * @param anim animator set to play on
+     * @param appTaskView the task view associated with the remote app closing
+     */
+    private void playRemoteTaskListFadeIn(@NonNull AnimatorSet anim,
+            @NonNull TaskItemView appTaskView) {
+        long delay = REMOTE_TO_RECENTS_ITEM_FADE_START_DELAY;
+        int childCount = mTaskRecyclerView.getChildCount();
+        for (int i = 0; i < childCount; i++) {
+            ValueAnimator fadeAnim = ValueAnimator.ofFloat(0, 1.0f);
+            fadeAnim.setDuration(REMOTE_TO_RECENTS_ITEM_FADE_DURATION).setInterpolator(OUT_SLOW_IN);
+            fadeAnim.setStartDelay(delay);
+            View view = mTaskRecyclerView.getChildAt(i);
+            if (Objects.equals(view, appTaskView)) {
+                // Only animate icon and text for the view with snapshot animating in
+                final View icon = appTaskView.getIconView();
+                final View label = appTaskView.getLabelView();
+
+                icon.setAlpha(0.0f);
+                label.setAlpha(0.0f);
+
+                fadeAnim.addUpdateListener(alphaVal -> {
+                    float val = alphaVal.getAnimatedFraction();
+
+                    icon.setAlpha(val);
+                    label.setAlpha(val);
+                });
+                fadeAnim.addListener(new AnimatorListenerAdapter() {
+                    @Override
+                    public void onAnimationEnd(Animator animation) {
+                        icon.setAlpha(1.0f);
+                        label.setAlpha(1.0f);
+                    }
+                });
+            } else {
+                // Otherwise, fade in the entire view.
+                view.setAlpha(0.0f);
+                fadeAnim.addUpdateListener(alphaVal -> {
+                    float val = alphaVal.getAnimatedFraction();
+                    view.setAlpha(val);
+                });
+                fadeAnim.addListener(new AnimatorListenerAdapter() {
+                    @Override
+                    public void onAnimationEnd(Animator animation) {
+                        view.setAlpha(1.0f);
+                    }
+                });
+            }
+            anim.play(fadeAnim);
+
+            int itemType = mTaskRecyclerView.getChildViewHolder(view).getItemViewType();
+            if (itemType == ITEM_TYPE_CLEAR_ALL) {
+                // Don't add delay. Clear all should animate at same time as next view.
+                continue;
+            }
+            delay += REMOTE_TO_RECENTS_ITEM_FADE_BETWEEN_DELAY;
+        }
+    }
+
     @Override
     public void setInsets(Rect insets) {
         mInsets = insets;
         mTaskRecyclerView.setPadding(insets.left, insets.top, insets.right, insets.bottom);
         mTaskRecyclerView.invalidateItemDecorations();
     }
+
+    /**
+     * Callback for when this view is ready for a remote animation from app to overview.
+     */
+    public interface onReadyForRemoteAnimCallback {
+
+        void onReadyForRemoteAnim();
+    }
 }
diff --git a/go/quickstep/src/com/android/quickstep/views/TaskItemView.java b/go/quickstep/src/com/android/quickstep/views/TaskItemView.java
index 6db8013..f184ad0 100644
--- a/go/quickstep/src/com/android/quickstep/views/TaskItemView.java
+++ b/go/quickstep/src/com/android/quickstep/views/TaskItemView.java
@@ -137,6 +137,14 @@
         return mThumbnailView;
     }
 
+    public View getIconView() {
+        return mIconView;
+    }
+
+    public View getLabelView() {
+        return mLabelView;
+    }
+
     /**
      * Start a new animation from the current task content to the specified new content. The caller
      * is responsible for the actual animation control via the property
diff --git a/quickstep/recents_ui_overrides/res/layout/proactive_hints_container.xml b/quickstep/recents_ui_overrides/res/layout/proactive_hints_container.xml
new file mode 100644
index 0000000..be3f17a
--- /dev/null
+++ b/quickstep/recents_ui_overrides/res/layout/proactive_hints_container.xml
@@ -0,0 +1,7 @@
+<com.android.quickstep.hints.ProactiveHintsContainer
+    xmlns:android="http://schemas.android.com/apk/res/android"
+    android:layout_width="match_parent"
+    android:layout_height="wrap_content"
+    android:layout_gravity="center_horizontal|bottom"
+    android:gravity="center_horizontal">
+</com.android.quickstep.hints.ProactiveHintsContainer>
\ No newline at end of file
diff --git a/quickstep/recents_ui_overrides/src/com/android/launcher3/uioverrides/RecentsViewStateController.java b/quickstep/recents_ui_overrides/src/com/android/launcher3/uioverrides/RecentsViewStateController.java
index 11a1885..c3a7698 100644
--- a/quickstep/recents_ui_overrides/src/com/android/launcher3/uioverrides/RecentsViewStateController.java
+++ b/quickstep/recents_ui_overrides/src/com/android/launcher3/uioverrides/RecentsViewStateController.java
@@ -31,6 +31,7 @@
 import com.android.launcher3.LauncherStateManager.AnimationConfig;
 import com.android.launcher3.anim.AnimatorSetBuilder;
 import com.android.launcher3.anim.PropertySetter;
+import com.android.quickstep.hints.ProactiveHintsContainer;
 import com.android.quickstep.views.ClearAllButton;
 import com.android.quickstep.views.LauncherRecentsView;
 import com.android.quickstep.views.RecentsView;
@@ -53,6 +54,14 @@
         if (state.overviewUi) {
             mRecentsView.updateEmptyMessage();
             mRecentsView.resetTaskVisuals();
+            mRecentsView.setHintVisibility(1f);
+        } else {
+            mRecentsView.setHintVisibility(0f);
+            ProactiveHintsContainer
+                    proactiveHintsContainer = mRecentsView.getProactiveHintsContainer();
+            if (proactiveHintsContainer != null) {
+                proactiveHintsContainer.removeAllViews();
+            }
         }
         setAlphas(PropertySetter.NO_ANIM_PROPERTY_SETTER, state.getVisibleElements(mLauncher));
     }
@@ -64,6 +73,14 @@
 
         if (!toState.overviewUi) {
             builder.addOnFinishRunnable(mRecentsView::resetTaskVisuals);
+            mRecentsView.setHintVisibility(0f);
+            builder.addOnFinishRunnable(() -> {
+                ProactiveHintsContainer
+                        proactiveHintsContainer = mRecentsView.getProactiveHintsContainer();
+                if (proactiveHintsContainer != null) {
+                    proactiveHintsContainer.removeAllViews();
+                }
+            });
         }
 
         if (toState.overviewUi) {
@@ -75,6 +92,7 @@
             updateAnim.setDuration(config.duration);
             builder.play(updateAnim);
             mRecentsView.updateEmptyMessage();
+            builder.addOnFinishRunnable(() -> mRecentsView.setHintVisibility(1f));
         }
 
         setAlphas(config.getPropertySetter(builder), toState.getVisibleElements(mLauncher));
diff --git a/quickstep/recents_ui_overrides/src/com/android/quickstep/RecentsAnimationWrapper.java b/quickstep/recents_ui_overrides/src/com/android/quickstep/RecentsAnimationWrapper.java
index 96d2dca..5eecf17 100644
--- a/quickstep/recents_ui_overrides/src/com/android/quickstep/RecentsAnimationWrapper.java
+++ b/quickstep/recents_ui_overrides/src/com/android/quickstep/RecentsAnimationWrapper.java
@@ -24,6 +24,7 @@
 import android.view.MotionEvent;
 
 import com.android.launcher3.util.Preconditions;
+import com.android.quickstep.inputconsumers.InputConsumer;
 import com.android.quickstep.util.SwipeAnimationTargetSet;
 import com.android.systemui.shared.system.InputConsumerController;
 
diff --git a/quickstep/recents_ui_overrides/src/com/android/quickstep/TaskSystemShortcut.java b/quickstep/recents_ui_overrides/src/com/android/quickstep/TaskSystemShortcut.java
index e3dcadc..2c919b3 100644
--- a/quickstep/recents_ui_overrides/src/com/android/quickstep/TaskSystemShortcut.java
+++ b/quickstep/recents_ui_overrides/src/com/android/quickstep/TaskSystemShortcut.java
@@ -16,6 +16,7 @@
 
 package com.android.quickstep;
 
+import static android.view.Display.DEFAULT_DISPLAY;
 import static com.android.launcher3.userevent.nano.LauncherLogProto.Action.Touch.TAP;
 
 import android.app.Activity;
@@ -116,21 +117,22 @@
             mHandler = new Handler(Looper.getMainLooper());
         }
 
-        protected abstract boolean isAvailable(BaseDraggingActivity activity);
+        protected abstract boolean isAvailable(BaseDraggingActivity activity, int displayId);
         protected abstract ActivityOptions makeLaunchOptions(Activity activity);
         protected abstract boolean onActivityStarted(BaseDraggingActivity activity);
 
         @Override
         public View.OnClickListener getOnClickListener(
                 BaseDraggingActivity activity, TaskView taskView) {
-            if (!isAvailable(activity)) {
-                return null;
-            }
             final Task task  = taskView.getTask();
             final int taskId = task.key.id;
+            final int displayId = task.key.displayId;
             if (!task.isDockable) {
                 return null;
             }
+            if (!isAvailable(activity, displayId)) {
+                return null;
+            }
             final RecentsView recentsView = activity.getOverviewPanel();
 
             final TaskThumbnailView thumbnailView = taskView.getThumbnail();
@@ -218,9 +220,13 @@
         }
 
         @Override
-        protected boolean isAvailable(BaseDraggingActivity activity) {
-            // Don't show menu-item if already in multi-window
-            return !activity.getDeviceProfile().isMultiWindowMode;
+        protected boolean isAvailable(BaseDraggingActivity activity, int displayId) {
+            // Don't show menu-item if already in multi-window and the task is from
+            // the secondary display.
+            // TODO(b/118266305): Temporarily disable splitscreen for secondary display while new
+            // implementation is enabled
+            return !activity.getDeviceProfile().isMultiWindowMode
+                    && displayId == DEFAULT_DISPLAY;
         }
 
         @Override
@@ -256,7 +262,7 @@
         }
 
         @Override
-        protected boolean isAvailable(BaseDraggingActivity activity) {
+        protected boolean isAvailable(BaseDraggingActivity activity, int displayId) {
             return ActivityManagerWrapper.getInstance().supportsFreeformMultiWindow(activity);
         }
 
@@ -290,10 +296,6 @@
             if (sysUiProxy == null) {
                 return null;
             }
-            if (SysUINavigationMode.getMode(activity) == SysUINavigationMode.Mode.NO_BUTTON) {
-                // TODO(b/130225926): Temporarily disable pinning while gesture nav is enabled
-                return null;
-            }
             if (!ActivityManagerWrapper.getInstance().isScreenPinningEnabled()) {
                 return null;
             }
diff --git a/quickstep/recents_ui_overrides/src/com/android/quickstep/TouchInteractionService.java b/quickstep/recents_ui_overrides/src/com/android/quickstep/TouchInteractionService.java
index a343a36..128fd45 100644
--- a/quickstep/recents_ui_overrides/src/com/android/quickstep/TouchInteractionService.java
+++ b/quickstep/recents_ui_overrides/src/com/android/quickstep/TouchInteractionService.java
@@ -35,7 +35,6 @@
 import android.content.Context;
 import android.content.Intent;
 import android.content.IntentFilter;
-import android.content.res.Resources;
 import android.graphics.Point;
 import android.graphics.RectF;
 import android.graphics.Region;
@@ -58,6 +57,7 @@
 
 import com.android.launcher3.MainThreadExecutor;
 import com.android.launcher3.R;
+import com.android.launcher3.ResourceUtils;
 import com.android.launcher3.Utilities;
 import com.android.launcher3.compat.UserManagerCompat;
 import com.android.launcher3.logging.EventLogArray;
@@ -66,6 +66,13 @@
 import com.android.launcher3.util.UiThreadHelper;
 import com.android.quickstep.SysUINavigationMode.Mode;
 import com.android.quickstep.SysUINavigationMode.NavigationModeChangeListener;
+import com.android.quickstep.inputconsumers.AccessibilityInputConsumer;
+import com.android.quickstep.inputconsumers.AssistantTouchConsumer;
+import com.android.quickstep.inputconsumers.DeviceLockedInputConsumer;
+import com.android.quickstep.inputconsumers.InputConsumer;
+import com.android.quickstep.inputconsumers.OtherActivityInputConsumer;
+import com.android.quickstep.inputconsumers.OverviewInputConsumer;
+import com.android.quickstep.inputconsumers.ScreenPinnedInputConsumer;
 import com.android.systemui.shared.recents.IOverviewProxy;
 import com.android.systemui.shared.recents.ISystemUiProxy;
 import com.android.systemui.shared.system.ActivityManagerWrapper;
@@ -90,9 +97,6 @@
     public static final LooperExecutor BACKGROUND_EXECUTOR =
             new LooperExecutor(UiThreadHelper.getBackgroundLooper());
 
-    private static final String NAVBAR_VERTICAL_SIZE = "navigation_bar_frame_height";
-    private static final String NAVBAR_HORIZONTAL_SIZE = "navigation_bar_width";
-
     public static final EventLogArray TOUCH_INTERACTION_LOG =
             new EventLogArray("touch_interaction_log", 40);
 
@@ -291,15 +295,7 @@
     }
 
     private int getNavbarSize(String resName) {
-        int frameSize;
-        Resources res = getResources();
-        int frameSizeResID = res.getIdentifier(resName, "dimen", "android");
-        if (frameSizeResID != 0) {
-            frameSize = res.getDimensionPixelSize(frameSizeResID);
-        } else {
-            frameSize = Utilities.pxFromDp(48, res.getDisplayMetrics());
-        }
-        return frameSize;
+        return ResourceUtils.getNavbarSize(resName, getResources());
     }
 
     private void initTouchBounds() {
@@ -312,20 +308,21 @@
         defaultDisplay.getRealSize(realSize);
         mSwipeTouchRegion.set(0, 0, realSize.x, realSize.y);
         if (mMode == Mode.NO_BUTTON) {
-            mSwipeTouchRegion.top = mSwipeTouchRegion.bottom - getNavbarSize(NAVBAR_VERTICAL_SIZE);
+            mSwipeTouchRegion.top = mSwipeTouchRegion.bottom - getNavbarSize(
+                    ResourceUtils.NAVBAR_VERTICAL_SIZE);
         } else {
             switch (defaultDisplay.getRotation()) {
                 case Surface.ROTATION_90:
                     mSwipeTouchRegion.left = mSwipeTouchRegion.right
-                            - getNavbarSize(NAVBAR_HORIZONTAL_SIZE);
+                            - getNavbarSize(ResourceUtils.NAVBAR_HORIZONTAL_SIZE);
                     break;
                 case Surface.ROTATION_270:
                     mSwipeTouchRegion.right = mSwipeTouchRegion.left
-                            + getNavbarSize(NAVBAR_HORIZONTAL_SIZE);
+                            + getNavbarSize(ResourceUtils.NAVBAR_HORIZONTAL_SIZE);
                     break;
                 default:
                     mSwipeTouchRegion.top = mSwipeTouchRegion.bottom
-                            - getNavbarSize(NAVBAR_VERTICAL_SIZE);
+                            - getNavbarSize(ResourceUtils.NAVBAR_VERTICAL_SIZE);
             }
         }
     }
@@ -470,6 +467,12 @@
                         mInputMonitorCompat);
             }
 
+            if (ActivityManagerWrapper.getInstance().isScreenPinningActive()) {
+                // Note: we only allow accessibility to wrap this, and it replaces the previous
+                // base input consumer (which should be NO_OP anyway since topTaskLocked == true).
+                base = new ScreenPinnedInputConsumer(this, mISystemUiProxy, activityControl);
+            }
+
             if ((mSystemUiStateFlags & SYSUI_STATE_A11Y_BUTTON_CLICKABLE) != 0) {
                 base = new AccessibilityInputConsumer(this, mISystemUiProxy,
                         (mSystemUiStateFlags & SYSUI_STATE_A11Y_BUTTON_LONG_CLICKABLE) != 0, base,
diff --git a/quickstep/recents_ui_overrides/src/com/android/quickstep/WindowTransformSwipeHandler.java b/quickstep/recents_ui_overrides/src/com/android/quickstep/WindowTransformSwipeHandler.java
index 58ae5eb..49c95f1 100644
--- a/quickstep/recents_ui_overrides/src/com/android/quickstep/WindowTransformSwipeHandler.java
+++ b/quickstep/recents_ui_overrides/src/com/android/quickstep/WindowTransformSwipeHandler.java
@@ -67,6 +67,7 @@
 import android.view.animation.Interpolator;
 
 import androidx.annotation.NonNull;
+import androidx.annotation.Nullable;
 import androidx.annotation.UiThread;
 
 import com.android.launcher3.AbstractFloatingView;
@@ -91,6 +92,8 @@
 import com.android.quickstep.ActivityControlHelper.AnimationFactory.ShelfAnimState;
 import com.android.quickstep.ActivityControlHelper.HomeAnimationFactory;
 import com.android.quickstep.SysUINavigationMode.Mode;
+import com.android.quickstep.inputconsumers.InputConsumer;
+import com.android.quickstep.inputconsumers.OverviewInputConsumer;
 import com.android.quickstep.util.ClipAnimationHelper;
 import com.android.quickstep.util.RectFSpringAnim;
 import com.android.quickstep.util.RemoteAnimationTargetSet;
@@ -166,7 +169,7 @@
     private static final int LAUNCHER_UI_STATES =
             STATE_LAUNCHER_PRESENT | STATE_LAUNCHER_DRAWN | STATE_LAUNCHER_STARTED;
 
-    enum GestureEndTarget {
+    public enum GestureEndTarget {
         HOME(1, STATE_SCALED_CONTROLLER_HOME, true, false, ContainerType.WORKSPACE, false),
 
         RECENTS(1, STATE_SCALED_CONTROLLER_RECENTS | STATE_CAPTURE_SCREENSHOT
@@ -220,8 +223,8 @@
     private final ClipAnimationHelper mClipAnimationHelper;
     private final ClipAnimationHelper.TransformParams mTransformParams;
 
-    protected Runnable mGestureEndCallback;
-    protected GestureEndTarget mGestureEndTarget;
+    private Runnable mGestureEndCallback;
+    private GestureEndTarget mGestureEndTarget;
     // Either RectFSpringAnim (if animating home) or ObjectAnimator (from mCurrentShift) otherwise
     private RunningWindowAnim mRunningWindowAnim;
     private boolean mIsShelfPeeking;
@@ -273,7 +276,7 @@
     private final long mTouchTimeMs;
     private long mLauncherFrameDrawnTime;
 
-    WindowTransformSwipeHandler(RunningTaskInfo runningTaskInfo, Context context,
+    public WindowTransformSwipeHandler(RunningTaskInfo runningTaskInfo, Context context,
             long touchTimeMs, ActivityControlHelper<T> controller, boolean continuingLastGesture,
             InputConsumerController inputConsumer) {
         mContext = context;
@@ -1125,6 +1128,13 @@
         return anim;
     }
 
+    /**
+     * @return The GestureEndTarget if the gesture has ended, else null.
+     */
+    public @Nullable GestureEndTarget getGestureEndTarget() {
+        return mGestureEndTarget;
+    }
+
     @UiThread
     private void resumeLastTask() {
         mRecentsAnimationWrapper.finish(false /* toRecents */, null);
diff --git a/quickstep/recents_ui_overrides/src/com/android/quickstep/hints/ProactiveHintsContainer.java b/quickstep/recents_ui_overrides/src/com/android/quickstep/hints/ProactiveHintsContainer.java
new file mode 100644
index 0000000..74a4851
--- /dev/null
+++ b/quickstep/recents_ui_overrides/src/com/android/quickstep/hints/ProactiveHintsContainer.java
@@ -0,0 +1,55 @@
+package com.android.quickstep.hints;
+
+import android.content.Context;
+import android.util.AttributeSet;
+import android.util.FloatProperty;
+import android.view.View;
+import android.widget.FrameLayout;
+
+public class ProactiveHintsContainer extends FrameLayout {
+
+  public static final FloatProperty<ProactiveHintsContainer> HINT_VISIBILITY =
+      new FloatProperty<ProactiveHintsContainer>("hint_visibility") {
+        @Override
+        public void setValue(ProactiveHintsContainer proactiveHintsContainer, float v) {
+          proactiveHintsContainer.setHintVisibility(v);
+        }
+
+        @Override
+        public Float get(ProactiveHintsContainer proactiveHintsContainer) {
+          return proactiveHintsContainer.mHintVisibility;
+        }
+      };
+
+  private float mHintVisibility;
+
+  public ProactiveHintsContainer(Context context) {
+    super(context);
+  }
+
+  public ProactiveHintsContainer(Context context, AttributeSet attrs) {
+    super(context, attrs);
+  }
+
+  public ProactiveHintsContainer(Context context, AttributeSet attrs, int defStyleAttr) {
+    super(context, attrs, defStyleAttr);
+  }
+
+  public ProactiveHintsContainer(Context context, AttributeSet attrs, int defStyleAttr, int defStyleRes) {
+    super(context, attrs, defStyleAttr, defStyleRes);
+  }
+
+  public void setView(View v) {
+    removeAllViews();
+    addView(v);
+  }
+
+  public void setHintVisibility(float v) {
+    if (v == 1) {
+      setVisibility(VISIBLE);
+    } else {
+      setVisibility(GONE);
+    }
+    mHintVisibility = v;
+  }
+}
diff --git a/quickstep/recents_ui_overrides/src/com/android/quickstep/AccessibilityInputConsumer.java b/quickstep/recents_ui_overrides/src/com/android/quickstep/inputconsumers/AccessibilityInputConsumer.java
similarity index 98%
rename from quickstep/recents_ui_overrides/src/com/android/quickstep/AccessibilityInputConsumer.java
rename to quickstep/recents_ui_overrides/src/com/android/quickstep/inputconsumers/AccessibilityInputConsumer.java
index 8f8cd18..f8475ca 100644
--- a/quickstep/recents_ui_overrides/src/com/android/quickstep/AccessibilityInputConsumer.java
+++ b/quickstep/recents_ui_overrides/src/com/android/quickstep/inputconsumers/AccessibilityInputConsumer.java
@@ -13,7 +13,7 @@
  * See the License for the specific language governing permissions and
  * limitations under the License.
  */
-package com.android.quickstep;
+package com.android.quickstep.inputconsumers;
 
 import static android.view.MotionEvent.ACTION_CANCEL;
 import static android.view.MotionEvent.ACTION_DOWN;
diff --git a/quickstep/recents_ui_overrides/src/com/android/quickstep/AssistantTouchConsumer.java b/quickstep/recents_ui_overrides/src/com/android/quickstep/inputconsumers/AssistantTouchConsumer.java
similarity index 73%
rename from quickstep/recents_ui_overrides/src/com/android/quickstep/AssistantTouchConsumer.java
rename to quickstep/recents_ui_overrides/src/com/android/quickstep/inputconsumers/AssistantTouchConsumer.java
index 829e478..0448fd1 100644
--- a/quickstep/recents_ui_overrides/src/com/android/quickstep/AssistantTouchConsumer.java
+++ b/quickstep/recents_ui_overrides/src/com/android/quickstep/inputconsumers/AssistantTouchConsumer.java
@@ -14,16 +14,16 @@
  * limitations under the License.
  */
 
-package com.android.quickstep;
+package com.android.quickstep.inputconsumers;
 
 import static android.view.MotionEvent.ACTION_CANCEL;
 import static android.view.MotionEvent.ACTION_DOWN;
 import static android.view.MotionEvent.ACTION_MOVE;
 import static android.view.MotionEvent.ACTION_POINTER_UP;
 import static android.view.MotionEvent.ACTION_UP;
-
 import static com.android.launcher3.userevent.nano.LauncherLogProto.Action.Direction.UPLEFT;
 import static com.android.launcher3.userevent.nano.LauncherLogProto.Action.Direction.UPRIGHT;
+import static com.android.launcher3.userevent.nano.LauncherLogProto.Action.Touch.FLING;
 import static com.android.launcher3.userevent.nano.LauncherLogProto.Action.Touch.SWIPE;
 import static com.android.launcher3.userevent.nano.LauncherLogProto.Action.Touch.SWIPE_NOOP;
 import static com.android.launcher3.userevent.nano.LauncherLogProto.ContainerType.NAVBAR;
@@ -38,11 +38,12 @@
 import android.util.Log;
 import android.view.HapticFeedbackConstants;
 import android.view.MotionEvent;
-
 import com.android.launcher3.BaseDraggingActivity;
 import com.android.launcher3.R;
 import com.android.launcher3.anim.Interpolators;
 import com.android.launcher3.logging.UserEventDispatcher;
+import com.android.launcher3.touch.SwipeDetector;
+import com.android.quickstep.ActivityControlHelper;
 import com.android.systemui.shared.recents.ISystemUiProxy;
 import com.android.systemui.shared.system.InputMonitorCompat;
 import com.android.systemui.shared.system.QuickStepContract;
@@ -50,12 +51,15 @@
 /**
  * Touch consumer for handling events to launch assistant from launcher
  */
-public class AssistantTouchConsumer extends DelegateInputConsumer {
+public class AssistantTouchConsumer extends DelegateInputConsumer
+    implements SwipeDetector.Listener {
+
     private static final String TAG = "AssistantTouchConsumer";
     private static final long RETRACT_ANIMATION_DURATION_MS = 300;
 
     private static final String INVOCATION_TYPE_KEY = "invocation_type";
     private static final int INVOCATION_TYPE_GESTURE = 1;
+    private static final int INVOCATION_TYPE_FLING = 6;
 
     private final PointF mDownPos = new PointF();
     private final PointF mLastPos = new PointF();
@@ -77,6 +81,7 @@
     private final float mSlop;
     private final ISystemUiProxy mSysUiProxy;
     private final Context mContext;
+    private final SwipeDetector mSwipeDetector;
 
     public AssistantTouchConsumer(Context context, ISystemUiProxy systemUiProxy,
             ActivityControlHelper activityControlHelper, InputConsumer delegate,
@@ -90,6 +95,8 @@
         mAngleThreshold = res.getInteger(R.integer.assistant_gesture_corner_deg_threshold);
         mSlop = QuickStepContract.getQuickStepDragSlopPx();
         mActivityControlHelper = activityControlHelper;
+        mSwipeDetector = new SwipeDetector(mContext, this, SwipeDetector.VERTICAL);
+        mSwipeDetector.setDetectableScrollConditions(SwipeDetector.DIRECTION_POSITIVE, false);
     }
 
     @Override
@@ -100,6 +107,7 @@
     @Override
     public void onMotionEvent(MotionEvent ev) {
         // TODO add logging
+        mSwipeDetector.onTouchEvent(ev);
 
         switch (ev.getActionMasked()) {
             case ACTION_DOWN: {
@@ -146,7 +154,7 @@
 
                         // Determine if angle is larger than threshold for assistant detection
                         float angle = (float) Math.toDegrees(
-                                Math.atan2(mDownPos.y - mLastPos.y, mDownPos.x - mLastPos.x));
+                            Math.atan2(mDownPos.y - mLastPos.y, mDownPos.x - mLastPos.x));
                         mDirection = angle > 90 ? UPLEFT : UPRIGHT;
                         angle = angle > 90 ? 180 - angle : angle;
 
@@ -159,7 +167,7 @@
                 } else {
                     // Movement
                     mDistance = (float) Math.hypot(mLastPos.x - mStartDragPos.x,
-                            mLastPos.y - mStartDragPos.y);
+                        mLastPos.y - mStartDragPos.y);
                     if (mDistance >= 0) {
                         final long diff = SystemClock.uptimeMillis() - mDragTime;
                         mTimeFraction = Math.min(diff * 1f / mTimeThreshold, 1);
@@ -172,18 +180,18 @@
             case ACTION_UP:
                 if (mState != STATE_DELEGATE_ACTIVE && !mLaunchedAssistant) {
                     ValueAnimator animator = ValueAnimator.ofFloat(mLastProgress, 0)
-                            .setDuration(RETRACT_ANIMATION_DURATION_MS);
+                        .setDuration(RETRACT_ANIMATION_DURATION_MS);
                     UserEventDispatcher.newInstance(mContext).logActionOnContainer(
-                            SWIPE_NOOP, mDirection, NAVBAR);
+                        SWIPE_NOOP, mDirection, NAVBAR);
                     animator.addUpdateListener(valueAnimator -> {
-                            float progress = (float) valueAnimator.getAnimatedValue();
-                            try {
+                        float progress = (float) valueAnimator.getAnimatedValue();
+                        try {
 
-                                mSysUiProxy.onAssistantProgress(progress);
-                            } catch (RemoteException e) {
-                                Log.w(TAG, "Failed to send SysUI start/send assistant progress: "
-                                        + progress, e);
-                            }
+                            mSysUiProxy.onAssistantProgress(progress);
+                        } catch (RemoteException e) {
+                            Log.w(TAG, "Failed to send SysUI start/send assistant progress: "
+                                + progress, e);
+                        }
                     });
                     animator.setInterpolator(Interpolators.DEACCEL_2);
                     animator.start();
@@ -200,38 +208,58 @@
 
     private void updateAssistantProgress() {
         if (!mLaunchedAssistant) {
-            float progress = Math.min(mDistance * 1f / mDistThreshold, 1) * mTimeFraction;
-            mLastProgress = progress;
-            try {
-                mSysUiProxy.onAssistantProgress(progress);
-                if (mDistance >= mDistThreshold && mTimeFraction >= 1) {
-                    UserEventDispatcher.newInstance(mContext).logActionOnContainer(
-                            SWIPE, mDirection, NAVBAR);
-                    Bundle args = new Bundle();
-                    args.putInt(INVOCATION_TYPE_KEY, INVOCATION_TYPE_GESTURE);
-
-                    BaseDraggingActivity launcherActivity =
-                            mActivityControlHelper.getCreatedActivity();
-                    if (launcherActivity != null) {
-                        launcherActivity.getRootView().
-                                performHapticFeedback(HapticFeedbackConstants.VIRTUAL_KEY,
-                                        HapticFeedbackConstants.FLAG_IGNORE_VIEW_SETTING);
-                    }
-
-                    mSysUiProxy.startAssistant(args);
-                    mLaunchedAssistant = true;
-                }
-            } catch (RemoteException e) {
-                Log.w(TAG, "Failed to send SysUI start/send assistant progress: " + progress, e);
-            }
+            mLastProgress = Math.min(mDistance * 1f / mDistThreshold, 1) * mTimeFraction;
+            updateAssistant(SWIPE);
         }
     }
 
-    static boolean withinTouchRegion(Context context, MotionEvent ev) {
+    private void updateAssistant(int gestureType) {
+        try {
+            mSysUiProxy.onAssistantProgress(mLastProgress);
+            if (gestureType == FLING || (mDistance >= mDistThreshold && mTimeFraction >= 1)) {
+                UserEventDispatcher.newInstance(mContext)
+                    .logActionOnContainer(gestureType, mDirection, NAVBAR);
+                Bundle args = new Bundle();
+                args.putInt(INVOCATION_TYPE_KEY, INVOCATION_TYPE_GESTURE);
+
+                BaseDraggingActivity launcherActivity = mActivityControlHelper.getCreatedActivity();
+                if (launcherActivity != null) {
+                    launcherActivity.getRootView().performHapticFeedback(
+                        13, // HapticFeedbackConstants.GESTURE_END
+                        HapticFeedbackConstants.FLAG_IGNORE_VIEW_SETTING);
+                }
+
+                mSysUiProxy.startAssistant(args);
+                mLaunchedAssistant = true;
+            }
+        } catch (RemoteException e) {
+            Log.w(TAG, "Failed to send SysUI start/send assistant progress: " + mLastProgress, e);
+        }
+    }
+
+    public static boolean withinTouchRegion(Context context, MotionEvent ev) {
         final Resources res = context.getResources();
         final int width = res.getDisplayMetrics().widthPixels;
         final int height = res.getDisplayMetrics().heightPixels;
         final int size = res.getDimensionPixelSize(R.dimen.gestures_assistant_size);
         return (ev.getX() > width - size || ev.getX() < size) && ev.getY() > height - size;
     }
+
+    @Override
+    public void onDragStart(boolean start) {
+        // do nothing
+    }
+
+    @Override
+    public boolean onDrag(float displacement) {
+        return false;
+    }
+
+    @Override
+    public void onDragEnd(float velocity, boolean fling) {
+        if (fling) {
+            mLastProgress = 1;
+            updateAssistant(FLING);
+        }
+    }
 }
diff --git a/quickstep/recents_ui_overrides/src/com/android/quickstep/DelegateInputConsumer.java b/quickstep/recents_ui_overrides/src/com/android/quickstep/inputconsumers/DelegateInputConsumer.java
similarity index 96%
rename from quickstep/recents_ui_overrides/src/com/android/quickstep/DelegateInputConsumer.java
rename to quickstep/recents_ui_overrides/src/com/android/quickstep/inputconsumers/DelegateInputConsumer.java
index d36162f..311ddd2 100644
--- a/quickstep/recents_ui_overrides/src/com/android/quickstep/DelegateInputConsumer.java
+++ b/quickstep/recents_ui_overrides/src/com/android/quickstep/inputconsumers/DelegateInputConsumer.java
@@ -1,4 +1,4 @@
-package com.android.quickstep;
+package com.android.quickstep.inputconsumers;
 
 import android.view.MotionEvent;
 
diff --git a/quickstep/recents_ui_overrides/src/com/android/quickstep/DeviceLockedInputConsumer.java b/quickstep/recents_ui_overrides/src/com/android/quickstep/inputconsumers/DeviceLockedInputConsumer.java
similarity index 97%
rename from quickstep/recents_ui_overrides/src/com/android/quickstep/DeviceLockedInputConsumer.java
rename to quickstep/recents_ui_overrides/src/com/android/quickstep/inputconsumers/DeviceLockedInputConsumer.java
index 7fd09f7..b1d175d 100644
--- a/quickstep/recents_ui_overrides/src/com/android/quickstep/DeviceLockedInputConsumer.java
+++ b/quickstep/recents_ui_overrides/src/com/android/quickstep/inputconsumers/DeviceLockedInputConsumer.java
@@ -13,7 +13,7 @@
  * See the License for the specific language governing permissions and
  * limitations under the License.
  */
-package com.android.quickstep;
+package com.android.quickstep.inputconsumers;
 
 import android.content.Context;
 import android.content.Intent;
diff --git a/quickstep/recents_ui_overrides/src/com/android/quickstep/InputConsumer.java b/quickstep/recents_ui_overrides/src/com/android/quickstep/inputconsumers/InputConsumer.java
similarity index 95%
rename from quickstep/recents_ui_overrides/src/com/android/quickstep/InputConsumer.java
rename to quickstep/recents_ui_overrides/src/com/android/quickstep/inputconsumers/InputConsumer.java
index 37b7288..2e8880d 100644
--- a/quickstep/recents_ui_overrides/src/com/android/quickstep/InputConsumer.java
+++ b/quickstep/recents_ui_overrides/src/com/android/quickstep/inputconsumers/InputConsumer.java
@@ -13,7 +13,7 @@
  * See the License for the specific language governing permissions and
  * limitations under the License.
  */
-package com.android.quickstep;
+package com.android.quickstep.inputconsumers;
 
 import android.annotation.TargetApi;
 import android.os.Build;
@@ -30,6 +30,7 @@
     int TYPE_ASSISTANT = 1 << 3;
     int TYPE_DEVICE_LOCKED = 1 << 4;
     int TYPE_ACCESSIBILITY = 1 << 5;
+    int TYPE_SCREEN_PINNED = 1 << 6;
 
     InputConsumer NO_OP = () -> TYPE_NO_OP;
 
diff --git a/quickstep/recents_ui_overrides/src/com/android/quickstep/OtherActivityInputConsumer.java b/quickstep/recents_ui_overrides/src/com/android/quickstep/inputconsumers/OtherActivityInputConsumer.java
similarity index 97%
rename from quickstep/recents_ui_overrides/src/com/android/quickstep/OtherActivityInputConsumer.java
rename to quickstep/recents_ui_overrides/src/com/android/quickstep/inputconsumers/OtherActivityInputConsumer.java
index db377b0..e862fa6 100644
--- a/quickstep/recents_ui_overrides/src/com/android/quickstep/OtherActivityInputConsumer.java
+++ b/quickstep/recents_ui_overrides/src/com/android/quickstep/inputconsumers/OtherActivityInputConsumer.java
@@ -13,7 +13,7 @@
  * See the License for the specific language governing permissions and
  * limitations under the License.
  */
-package com.android.quickstep;
+package com.android.quickstep.inputconsumers;
 
 import static android.view.MotionEvent.ACTION_CANCEL;
 import static android.view.MotionEvent.ACTION_DOWN;
@@ -50,7 +50,13 @@
 import com.android.launcher3.util.Preconditions;
 import com.android.launcher3.util.RaceConditionTracker;
 import com.android.launcher3.util.TraceHelper;
+import com.android.quickstep.ActivityControlHelper;
+import com.android.quickstep.OverviewCallbacks;
+import com.android.quickstep.RecentsModel;
+import com.android.quickstep.SwipeSharedState;
+import com.android.quickstep.SysUINavigationMode;
 import com.android.quickstep.SysUINavigationMode.Mode;
+import com.android.quickstep.WindowTransformSwipeHandler;
 import com.android.quickstep.WindowTransformSwipeHandler.GestureEndTarget;
 import com.android.quickstep.util.CachedEventDispatcher;
 import com.android.quickstep.util.MotionPauseDetector;
@@ -376,7 +382,7 @@
             // The consumer is being switched while we are active. Set up the shared state to be
             // used by the next animation
             removeListener();
-            GestureEndTarget endTarget = mInteractionHandler.mGestureEndTarget;
+            GestureEndTarget endTarget = mInteractionHandler.getGestureEndTarget();
             mSwipeSharedState.canGestureBeContinued = endTarget != null && endTarget.canBeContinued;
             mSwipeSharedState.goingToLauncher = endTarget != null && endTarget.isLauncher;
             if (mSwipeSharedState.canGestureBeContinued) {
diff --git a/quickstep/recents_ui_overrides/src/com/android/quickstep/OverviewInputConsumer.java b/quickstep/recents_ui_overrides/src/com/android/quickstep/inputconsumers/OverviewInputConsumer.java
similarity index 96%
rename from quickstep/recents_ui_overrides/src/com/android/quickstep/OverviewInputConsumer.java
rename to quickstep/recents_ui_overrides/src/com/android/quickstep/inputconsumers/OverviewInputConsumer.java
index bafc367..bab3c71 100644
--- a/quickstep/recents_ui_overrides/src/com/android/quickstep/OverviewInputConsumer.java
+++ b/quickstep/recents_ui_overrides/src/com/android/quickstep/inputconsumers/OverviewInputConsumer.java
@@ -13,7 +13,7 @@
  * See the License for the specific language governing permissions and
  * limitations under the License.
  */
-package com.android.quickstep;
+package com.android.quickstep.inputconsumers;
 
 import static com.android.launcher3.config.FeatureFlags.ENABLE_QUICKSTEP_LIVE_TILE;
 import static com.android.quickstep.TouchInteractionService.TOUCH_INTERACTION_LOG;
@@ -27,6 +27,8 @@
 import com.android.launcher3.BaseDraggingActivity;
 import com.android.launcher3.Utilities;
 import com.android.launcher3.views.BaseDragLayer;
+import com.android.quickstep.ActivityControlHelper;
+import com.android.quickstep.OverviewCallbacks;
 import com.android.systemui.shared.system.ActivityManagerWrapper;
 import com.android.systemui.shared.system.InputMonitorCompat;
 
diff --git a/quickstep/recents_ui_overrides/src/com/android/quickstep/inputconsumers/ScreenPinnedInputConsumer.java b/quickstep/recents_ui_overrides/src/com/android/quickstep/inputconsumers/ScreenPinnedInputConsumer.java
new file mode 100644
index 0000000..a0e20f2
--- /dev/null
+++ b/quickstep/recents_ui_overrides/src/com/android/quickstep/inputconsumers/ScreenPinnedInputConsumer.java
@@ -0,0 +1,88 @@
+/*
+ * 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.quickstep.inputconsumers;
+
+import android.content.Context;
+import android.os.RemoteException;
+import android.util.Log;
+import android.view.HapticFeedbackConstants;
+import android.view.MotionEvent;
+
+import com.android.launcher3.BaseDraggingActivity;
+import com.android.launcher3.R;
+import com.android.quickstep.ActivityControlHelper;
+import com.android.quickstep.util.MotionPauseDetector;
+import com.android.systemui.shared.recents.ISystemUiProxy;
+
+/**
+ * An input consumer that detects swipe up and hold to exit screen pinning mode.
+ */
+public class ScreenPinnedInputConsumer implements InputConsumer {
+
+    private static final String TAG = "ScreenPinnedConsumer";
+
+    private final float mMotionPauseMinDisplacement;
+    private final MotionPauseDetector mMotionPauseDetector;
+
+    private float mTouchDownY;
+
+    public ScreenPinnedInputConsumer(Context context, ISystemUiProxy sysuiProxy,
+            ActivityControlHelper activityControl) {
+        mMotionPauseMinDisplacement = context.getResources().getDimension(
+                R.dimen.motion_pause_detector_min_displacement_from_app);
+        mMotionPauseDetector = new MotionPauseDetector(context, true /* makePauseHarderToTrigger*/);
+        mMotionPauseDetector.setOnMotionPauseListener(isPaused -> {
+            if (isPaused) {
+                try {
+                    sysuiProxy.stopScreenPinning();
+                    BaseDraggingActivity launcherActivity = activityControl.getCreatedActivity();
+                    if (launcherActivity != null) {
+                        launcherActivity.getRootView().performHapticFeedback(
+                                HapticFeedbackConstants.LONG_PRESS,
+                                HapticFeedbackConstants.FLAG_IGNORE_VIEW_SETTING);
+                    }
+                    mMotionPauseDetector.clear();
+                } catch (RemoteException e) {
+                    Log.e(TAG, "Unable to stop screen pinning ", e);
+                }
+            }
+        });
+    }
+
+    @Override
+    public int getType() {
+        return TYPE_SCREEN_PINNED;
+    }
+
+    @Override
+    public void onMotionEvent(MotionEvent ev) {
+        float y = ev.getY();
+        switch (ev.getAction()) {
+            case MotionEvent.ACTION_DOWN:
+                mTouchDownY = y;
+                break;
+            case MotionEvent.ACTION_MOVE:
+                float displacement = mTouchDownY - y;
+                mMotionPauseDetector.setDisallowPause(displacement < mMotionPauseMinDisplacement);
+                mMotionPauseDetector.addPosition(y, ev.getEventTime());
+                break;
+            case MotionEvent.ACTION_CANCEL:
+            case MotionEvent.ACTION_UP:
+                mMotionPauseDetector.clear();
+                break;
+        }
+    }
+}
diff --git a/quickstep/recents_ui_overrides/src/com/android/quickstep/views/LauncherRecentsView.java b/quickstep/recents_ui_overrides/src/com/android/quickstep/views/LauncherRecentsView.java
index d6f2235..bdac750 100644
--- a/quickstep/recents_ui_overrides/src/com/android/quickstep/views/LauncherRecentsView.java
+++ b/quickstep/recents_ui_overrides/src/com/android/quickstep/views/LauncherRecentsView.java
@@ -34,6 +34,8 @@
 import android.util.AttributeSet;
 import android.view.View;
 
+import androidx.annotation.Nullable;
+
 import com.android.launcher3.DeviceProfile;
 import com.android.launcher3.Launcher;
 import com.android.launcher3.LauncherState;
@@ -41,8 +43,11 @@
 import com.android.launcher3.anim.Interpolators;
 import com.android.launcher3.appprediction.PredictionUiStateManager;
 import com.android.launcher3.appprediction.PredictionUiStateManager.Client;
+import com.android.launcher3.util.PendingAnimation;
+import com.android.launcher3.views.BaseDragLayer;
 import com.android.launcher3.views.ScrimView;
 import com.android.quickstep.SysUINavigationMode;
+import com.android.quickstep.hints.ProactiveHintsContainer;
 import com.android.quickstep.util.ClipAnimationHelper;
 import com.android.quickstep.util.ClipAnimationHelper.TransformParams;
 import com.android.quickstep.util.LayoutUtils;
@@ -54,6 +59,8 @@
 public class LauncherRecentsView extends RecentsView<Launcher> {
 
     private final TransformParams mTransformParams = new TransformParams();
+    private final int mChipOverhang;
+    @Nullable private ProactiveHintsContainer mProactiveHintsContainer;
 
     public LauncherRecentsView(Context context) {
         this(context, null);
@@ -66,6 +73,16 @@
     public LauncherRecentsView(Context context, AttributeSet attrs, int defStyleAttr) {
         super(context, attrs, defStyleAttr);
         setContentAlpha(0);
+        mChipOverhang = (int) context.getResources().getDimension(R.dimen.chip_hint_overhang);
+    }
+
+    @Override
+    protected void onAttachedToWindow() {
+        super.onAttachedToWindow();
+        View hintContainer = mActivity.findViewById(R.id.hints);
+        mProactiveHintsContainer =
+                hintContainer instanceof ProactiveHintsContainer
+                        ? (ProactiveHintsContainer) hintContainer : null;
     }
 
     @Override
@@ -84,6 +101,11 @@
         }
     }
 
+    @Nullable
+    public ProactiveHintsContainer getProactiveHintsContainer() {
+        return mProactiveHintsContainer;
+    }
+
     @Override
     public void draw(Canvas canvas) {
         maybeDrawEmptyMessage(canvas);
@@ -137,6 +159,48 @@
     @Override
     protected void getTaskSize(DeviceProfile dp, Rect outRect) {
         LayoutUtils.calculateLauncherTaskSize(getContext(), dp, outRect);
+        if (mProactiveHintsContainer != null) {
+            BaseDragLayer.LayoutParams params = (BaseDragLayer.LayoutParams) mProactiveHintsContainer.getLayoutParams();
+            params.bottomMargin = getHeight() - outRect.bottom - mChipOverhang;
+            params.width = outRect.width();
+        }
+    }
+
+    @Override
+    public PendingAnimation createTaskLauncherAnimation(TaskView tv, long duration) {
+        PendingAnimation anim = super.createTaskLauncherAnimation(tv, duration);
+
+        if (mProactiveHintsContainer != null) {
+            anim.anim.play(ObjectAnimator.ofFloat(
+                    mProactiveHintsContainer, ProactiveHintsContainer.HINT_VISIBILITY, 0));
+        }
+
+        return anim;
+    }
+
+    @Override
+    public PendingAnimation createTaskDismissAnimation(TaskView taskView, boolean animateTaskView,
+            boolean shouldRemoveTask, long duration) {
+        PendingAnimation anim = super.createTaskDismissAnimation(taskView, animateTaskView,
+                shouldRemoveTask, duration);
+
+        if (mProactiveHintsContainer != null) {
+            anim.anim.play(ObjectAnimator.ofFloat(
+                    mProactiveHintsContainer, ProactiveHintsContainer.HINT_VISIBILITY, 0));
+            anim.addEndListener(onEndListener -> {
+                if (!onEndListener.isSuccess) {
+                    mProactiveHintsContainer.setHintVisibility(1);
+                }
+            });
+        }
+
+        return anim;
+    }
+
+    public void setHintVisibility(float v) {
+        if (mProactiveHintsContainer != null) {
+            mProactiveHintsContainer.setHintVisibility(v);
+        }
     }
 
     @Override
diff --git a/quickstep/res/values-af/strings.xml b/quickstep/res/values-af/strings.xml
index 88954b2..64b8e2c 100644
--- a/quickstep/res/values-af/strings.xml
+++ b/quickstep/res/values-af/strings.xml
@@ -31,4 +31,7 @@
     <string name="task_contents_description_with_remaining_time" msgid="4479688746574672685">"<xliff:g id="TASK_DESCRIPTION">%1$s</xliff:g>, <xliff:g id="REMAINING_TIME">%2$s</xliff:g>"</string>
     <string name="shorter_duration_less_than_one_minute" msgid="4722015666335015336">"&lt; 1 minuut"</string>
     <string name="time_left_for_app" msgid="3111996412933644358">"<xliff:g id="TIME">%1$s</xliff:g> oor vandag"</string>
+    <string name="title_app_suggestions" msgid="4185902664111965088">"Programvoorstelle"</string>
+    <string name="all_apps_label" msgid="8542784161730910663">"Alle programme"</string>
+    <string name="all_apps_prediction_tip" msgid="2672336544844936186">"Jou voorspelde programme"</string>
 </resources>
diff --git a/quickstep/res/values-am/strings.xml b/quickstep/res/values-am/strings.xml
index 34fb3be..3daa922 100644
--- a/quickstep/res/values-am/strings.xml
+++ b/quickstep/res/values-am/strings.xml
@@ -31,4 +31,7 @@
     <string name="task_contents_description_with_remaining_time" msgid="4479688746574672685">"<xliff:g id="TASK_DESCRIPTION">%1$s</xliff:g>፣ <xliff:g id="REMAINING_TIME">%2$s</xliff:g>"</string>
     <string name="shorter_duration_less_than_one_minute" msgid="4722015666335015336">"&lt; 1 ደቂቃ"</string>
     <string name="time_left_for_app" msgid="3111996412933644358">"ዛሬ <xliff:g id="TIME">%1$s</xliff:g> ቀርቷል"</string>
+    <string name="title_app_suggestions" msgid="4185902664111965088">"የመተግበሪያ ጥቆማዎች"</string>
+    <string name="all_apps_label" msgid="8542784161730910663">"ሁሉም መተግበሪያዎች"</string>
+    <string name="all_apps_prediction_tip" msgid="2672336544844936186">"የእርስዎ የሚገመቱ መተግበሪያዎች"</string>
 </resources>
diff --git a/quickstep/res/values-ar/strings.xml b/quickstep/res/values-ar/strings.xml
index ebdcf73..73c7c5c 100644
--- a/quickstep/res/values-ar/strings.xml
+++ b/quickstep/res/values-ar/strings.xml
@@ -31,4 +31,7 @@
     <string name="task_contents_description_with_remaining_time" msgid="4479688746574672685">"<xliff:g id="TASK_DESCRIPTION">%1$s</xliff:g>، <xliff:g id="REMAINING_TIME">%2$s</xliff:g>"</string>
     <string name="shorter_duration_less_than_one_minute" msgid="4722015666335015336">"أقل من دقيقة"</string>
     <string name="time_left_for_app" msgid="3111996412933644358">"يتبقى اليوم <xliff:g id="TIME">%1$s</xliff:g>."</string>
+    <string name="title_app_suggestions" msgid="4185902664111965088">"اقتراحات التطبيقات"</string>
+    <string name="all_apps_label" msgid="8542784161730910663">"جميع التطبيقات"</string>
+    <string name="all_apps_prediction_tip" msgid="2672336544844936186">"تطبيقاتك المتوقّعة"</string>
 </resources>
diff --git a/quickstep/res/values-az/strings.xml b/quickstep/res/values-az/strings.xml
index 02312f4..aa8fa53 100644
--- a/quickstep/res/values-az/strings.xml
+++ b/quickstep/res/values-az/strings.xml
@@ -31,4 +31,7 @@
     <string name="task_contents_description_with_remaining_time" msgid="4479688746574672685">"<xliff:g id="TASK_DESCRIPTION">%1$s</xliff:g>, <xliff:g id="REMAINING_TIME">%2$s</xliff:g>"</string>
     <string name="shorter_duration_less_than_one_minute" msgid="4722015666335015336">"&lt; 1 dəq"</string>
     <string name="time_left_for_app" msgid="3111996412933644358">"Bu gün <xliff:g id="TIME">%1$s</xliff:g> qaldı"</string>
+    <string name="title_app_suggestions" msgid="4185902664111965088">"Tətbiq təklifləri"</string>
+    <string name="all_apps_label" msgid="8542784161730910663">"Bütün tətbiqlər"</string>
+    <string name="all_apps_prediction_tip" msgid="2672336544844936186">"Təklif edilən tətbiqlər"</string>
 </resources>
diff --git a/quickstep/res/values-b+sr+Latn/strings.xml b/quickstep/res/values-b+sr+Latn/strings.xml
index baab4a1..fbbe9d2 100644
--- a/quickstep/res/values-b+sr+Latn/strings.xml
+++ b/quickstep/res/values-b+sr+Latn/strings.xml
@@ -31,4 +31,7 @@
     <string name="task_contents_description_with_remaining_time" msgid="4479688746574672685">"<xliff:g id="TASK_DESCRIPTION">%1$s</xliff:g>, <xliff:g id="REMAINING_TIME">%2$s</xliff:g>"</string>
     <string name="shorter_duration_less_than_one_minute" msgid="4722015666335015336">"&lt; 1 min"</string>
     <string name="time_left_for_app" msgid="3111996412933644358">"Još <xliff:g id="TIME">%1$s</xliff:g> danas"</string>
+    <string name="title_app_suggestions" msgid="4185902664111965088">"Predlozi aplikacija"</string>
+    <string name="all_apps_label" msgid="8542784161730910663">"Sve aplikacije"</string>
+    <string name="all_apps_prediction_tip" msgid="2672336544844936186">"Predviđene aplikacije"</string>
 </resources>
diff --git a/quickstep/res/values-be/strings.xml b/quickstep/res/values-be/strings.xml
index b28f377..c4a2772 100644
--- a/quickstep/res/values-be/strings.xml
+++ b/quickstep/res/values-be/strings.xml
@@ -31,4 +31,7 @@
     <string name="task_contents_description_with_remaining_time" msgid="4479688746574672685">"<xliff:g id="TASK_DESCRIPTION">%1$s</xliff:g>, <xliff:g id="REMAINING_TIME">%2$s</xliff:g>"</string>
     <string name="shorter_duration_less_than_one_minute" msgid="4722015666335015336">"&lt; 1 хв"</string>
     <string name="time_left_for_app" msgid="3111996412933644358">"Сёння засталося <xliff:g id="TIME">%1$s</xliff:g>"</string>
+    <string name="title_app_suggestions" msgid="4185902664111965088">"Прапановы праграм"</string>
+    <string name="all_apps_label" msgid="8542784161730910663">"Усе праграмы"</string>
+    <string name="all_apps_prediction_tip" msgid="2672336544844936186">"Вашы праграмы з падказак"</string>
 </resources>
diff --git a/quickstep/res/values-bg/strings.xml b/quickstep/res/values-bg/strings.xml
index 0475c0d..9e8c54a 100644
--- a/quickstep/res/values-bg/strings.xml
+++ b/quickstep/res/values-bg/strings.xml
@@ -31,4 +31,7 @@
     <string name="task_contents_description_with_remaining_time" msgid="4479688746574672685">"<xliff:g id="TASK_DESCRIPTION">%1$s</xliff:g>, <xliff:g id="REMAINING_TIME">%2$s</xliff:g>"</string>
     <string name="shorter_duration_less_than_one_minute" msgid="4722015666335015336">"&lt; 1 мин"</string>
     <string name="time_left_for_app" msgid="3111996412933644358">"Оставащо време днес: <xliff:g id="TIME">%1$s</xliff:g>"</string>
+    <string name="title_app_suggestions" msgid="4185902664111965088">"Предложения за приложения"</string>
+    <string name="all_apps_label" msgid="8542784161730910663">"Всички приложения"</string>
+    <string name="all_apps_prediction_tip" msgid="2672336544844936186">"Предвидени приложения"</string>
 </resources>
diff --git a/quickstep/res/values-bn/strings.xml b/quickstep/res/values-bn/strings.xml
index e6764e0..57f92e5 100644
--- a/quickstep/res/values-bn/strings.xml
+++ b/quickstep/res/values-bn/strings.xml
@@ -31,4 +31,7 @@
     <string name="task_contents_description_with_remaining_time" msgid="4479688746574672685">"<xliff:g id="TASK_DESCRIPTION">%1$s</xliff:g>, <xliff:g id="REMAINING_TIME">%2$s</xliff:g>"</string>
     <string name="shorter_duration_less_than_one_minute" msgid="4722015666335015336">"&lt; ১ মি."</string>
     <string name="time_left_for_app" msgid="3111996412933644358">"আজকে <xliff:g id="TIME">%1$s</xliff:g> বাকি আছে"</string>
+    <string name="title_app_suggestions" msgid="4185902664111965088">"অ্যাপের সাজেশন"</string>
+    <string name="all_apps_label" msgid="8542784161730910663">"সব অ্যাপ"</string>
+    <string name="all_apps_prediction_tip" msgid="2672336544844936186">"আপনার প্রয়োজন হতে পারে এমন অ্যাপ"</string>
 </resources>
diff --git a/quickstep/res/values-bs/strings.xml b/quickstep/res/values-bs/strings.xml
index 77b4c46..7968f7c 100644
--- a/quickstep/res/values-bs/strings.xml
+++ b/quickstep/res/values-bs/strings.xml
@@ -31,4 +31,7 @@
     <string name="task_contents_description_with_remaining_time" msgid="4479688746574672685">"<xliff:g id="TASK_DESCRIPTION">%1$s</xliff:g>, <xliff:g id="REMAINING_TIME">%2$s</xliff:g>"</string>
     <string name="shorter_duration_less_than_one_minute" msgid="4722015666335015336">"&lt; 1 min"</string>
     <string name="time_left_for_app" msgid="3111996412933644358">"Preostalo vrijeme: <xliff:g id="TIME">%1$s</xliff:g>"</string>
+    <string name="title_app_suggestions" msgid="4185902664111965088">"Prijedlozi za aplikacije"</string>
+    <string name="all_apps_label" msgid="8542784161730910663">"Sve aplikacije"</string>
+    <string name="all_apps_prediction_tip" msgid="2672336544844936186">"Predviđene aplikacije"</string>
 </resources>
diff --git a/quickstep/res/values-ca/strings.xml b/quickstep/res/values-ca/strings.xml
index 484f445..6420aa8 100644
--- a/quickstep/res/values-ca/strings.xml
+++ b/quickstep/res/values-ca/strings.xml
@@ -31,4 +31,7 @@
     <string name="task_contents_description_with_remaining_time" msgid="4479688746574672685">"<xliff:g id="TASK_DESCRIPTION">%1$s</xliff:g>; <xliff:g id="REMAINING_TIME">%2$s</xliff:g>"</string>
     <string name="shorter_duration_less_than_one_minute" msgid="4722015666335015336">"&lt; 1 minut"</string>
     <string name="time_left_for_app" msgid="3111996412933644358">"temps restant avui: <xliff:g id="TIME">%1$s</xliff:g>"</string>
+    <string name="title_app_suggestions" msgid="4185902664111965088">"Suggeriments d\'aplicacions"</string>
+    <string name="all_apps_label" msgid="8542784161730910663">"Totes les aplicacions"</string>
+    <string name="all_apps_prediction_tip" msgid="2672336544844936186">"Prediccions d\'aplicacions"</string>
 </resources>
diff --git a/quickstep/res/values-cs/strings.xml b/quickstep/res/values-cs/strings.xml
index a698d49..194ff87 100644
--- a/quickstep/res/values-cs/strings.xml
+++ b/quickstep/res/values-cs/strings.xml
@@ -31,4 +31,7 @@
     <string name="task_contents_description_with_remaining_time" msgid="4479688746574672685">"<xliff:g id="TASK_DESCRIPTION">%1$s</xliff:g>, <xliff:g id="REMAINING_TIME">%2$s</xliff:g>"</string>
     <string name="shorter_duration_less_than_one_minute" msgid="4722015666335015336">"&lt; 1 minuta"</string>
     <string name="time_left_for_app" msgid="3111996412933644358">"dnes zbývá: <xliff:g id="TIME">%1$s</xliff:g>"</string>
+    <string name="title_app_suggestions" msgid="4185902664111965088">"Návrhy aplikací"</string>
+    <string name="all_apps_label" msgid="8542784161730910663">"Všechny aplikace"</string>
+    <string name="all_apps_prediction_tip" msgid="2672336544844936186">"Vaše předpovídané aplikace"</string>
 </resources>
diff --git a/quickstep/res/values-da/strings.xml b/quickstep/res/values-da/strings.xml
index b3e8524..b43a76e 100644
--- a/quickstep/res/values-da/strings.xml
+++ b/quickstep/res/values-da/strings.xml
@@ -31,4 +31,7 @@
     <string name="task_contents_description_with_remaining_time" msgid="4479688746574672685">"<xliff:g id="TASK_DESCRIPTION">%1$s</xliff:g>, <xliff:g id="REMAINING_TIME">%2$s</xliff:g>"</string>
     <string name="shorter_duration_less_than_one_minute" msgid="4722015666335015336">"&lt; 1 min"</string>
     <string name="time_left_for_app" msgid="3111996412933644358">"<xliff:g id="TIME">%1$s</xliff:g> tilbage i dag"</string>
+    <string name="title_app_suggestions" msgid="4185902664111965088">"Appforslag"</string>
+    <string name="all_apps_label" msgid="8542784161730910663">"Alle apps"</string>
+    <string name="all_apps_prediction_tip" msgid="2672336544844936186">"Dine foreslåede apps"</string>
 </resources>
diff --git a/quickstep/res/values-de/strings.xml b/quickstep/res/values-de/strings.xml
index 10e4fd7..7f4e56d 100644
--- a/quickstep/res/values-de/strings.xml
+++ b/quickstep/res/values-de/strings.xml
@@ -31,4 +31,7 @@
     <string name="task_contents_description_with_remaining_time" msgid="4479688746574672685">"<xliff:g id="TASK_DESCRIPTION">%1$s</xliff:g>, <xliff:g id="REMAINING_TIME">%2$s</xliff:g>"</string>
     <string name="shorter_duration_less_than_one_minute" msgid="4722015666335015336">"&lt; 1 min"</string>
     <string name="time_left_for_app" msgid="3111996412933644358">"Heute noch <xliff:g id="TIME">%1$s</xliff:g>"</string>
+    <string name="title_app_suggestions" msgid="4185902664111965088">"App-Vorschläge"</string>
+    <string name="all_apps_label" msgid="8542784161730910663">"Alle Apps"</string>
+    <string name="all_apps_prediction_tip" msgid="2672336544844936186">"App-Vorschläge für dich"</string>
 </resources>
diff --git a/quickstep/res/values-el/strings.xml b/quickstep/res/values-el/strings.xml
index 6ef1e94..87268df 100644
--- a/quickstep/res/values-el/strings.xml
+++ b/quickstep/res/values-el/strings.xml
@@ -31,4 +31,7 @@
     <string name="task_contents_description_with_remaining_time" msgid="4479688746574672685">"<xliff:g id="TASK_DESCRIPTION">%1$s</xliff:g>, <xliff:g id="REMAINING_TIME">%2$s</xliff:g>"</string>
     <string name="shorter_duration_less_than_one_minute" msgid="4722015666335015336">"&lt; 1 λ."</string>
     <string name="time_left_for_app" msgid="3111996412933644358">"Απομένουν <xliff:g id="TIME">%1$s</xliff:g> σήμερα"</string>
+    <string name="title_app_suggestions" msgid="4185902664111965088">"Προτάσεις εφαρμογών"</string>
+    <string name="all_apps_label" msgid="8542784161730910663">"Όλες οι εφαρμογές"</string>
+    <string name="all_apps_prediction_tip" msgid="2672336544844936186">"Προβλέψεις εφαρμογών"</string>
 </resources>
diff --git a/quickstep/res/values-en-rAU/strings.xml b/quickstep/res/values-en-rAU/strings.xml
index d640b63..2d1418e 100644
--- a/quickstep/res/values-en-rAU/strings.xml
+++ b/quickstep/res/values-en-rAU/strings.xml
@@ -31,4 +31,7 @@
     <string name="task_contents_description_with_remaining_time" msgid="4479688746574672685">"<xliff:g id="TASK_DESCRIPTION">%1$s</xliff:g>, <xliff:g id="REMAINING_TIME">%2$s</xliff:g>"</string>
     <string name="shorter_duration_less_than_one_minute" msgid="4722015666335015336">"&lt; 1 minute"</string>
     <string name="time_left_for_app" msgid="3111996412933644358">"<xliff:g id="TIME">%1$s</xliff:g> left today"</string>
+    <string name="title_app_suggestions" msgid="4185902664111965088">"App suggestions"</string>
+    <string name="all_apps_label" msgid="8542784161730910663">"All apps"</string>
+    <string name="all_apps_prediction_tip" msgid="2672336544844936186">"Your predicted apps"</string>
 </resources>
diff --git a/quickstep/res/values-en-rGB/strings.xml b/quickstep/res/values-en-rGB/strings.xml
index d640b63..2d1418e 100644
--- a/quickstep/res/values-en-rGB/strings.xml
+++ b/quickstep/res/values-en-rGB/strings.xml
@@ -31,4 +31,7 @@
     <string name="task_contents_description_with_remaining_time" msgid="4479688746574672685">"<xliff:g id="TASK_DESCRIPTION">%1$s</xliff:g>, <xliff:g id="REMAINING_TIME">%2$s</xliff:g>"</string>
     <string name="shorter_duration_less_than_one_minute" msgid="4722015666335015336">"&lt; 1 minute"</string>
     <string name="time_left_for_app" msgid="3111996412933644358">"<xliff:g id="TIME">%1$s</xliff:g> left today"</string>
+    <string name="title_app_suggestions" msgid="4185902664111965088">"App suggestions"</string>
+    <string name="all_apps_label" msgid="8542784161730910663">"All apps"</string>
+    <string name="all_apps_prediction_tip" msgid="2672336544844936186">"Your predicted apps"</string>
 </resources>
diff --git a/quickstep/res/values-en-rIN/strings.xml b/quickstep/res/values-en-rIN/strings.xml
index d640b63..2d1418e 100644
--- a/quickstep/res/values-en-rIN/strings.xml
+++ b/quickstep/res/values-en-rIN/strings.xml
@@ -31,4 +31,7 @@
     <string name="task_contents_description_with_remaining_time" msgid="4479688746574672685">"<xliff:g id="TASK_DESCRIPTION">%1$s</xliff:g>, <xliff:g id="REMAINING_TIME">%2$s</xliff:g>"</string>
     <string name="shorter_duration_less_than_one_minute" msgid="4722015666335015336">"&lt; 1 minute"</string>
     <string name="time_left_for_app" msgid="3111996412933644358">"<xliff:g id="TIME">%1$s</xliff:g> left today"</string>
+    <string name="title_app_suggestions" msgid="4185902664111965088">"App suggestions"</string>
+    <string name="all_apps_label" msgid="8542784161730910663">"All apps"</string>
+    <string name="all_apps_prediction_tip" msgid="2672336544844936186">"Your predicted apps"</string>
 </resources>
diff --git a/quickstep/res/values-es-rUS/strings.xml b/quickstep/res/values-es-rUS/strings.xml
index c93e8fc..5f5d0bd 100644
--- a/quickstep/res/values-es-rUS/strings.xml
+++ b/quickstep/res/values-es-rUS/strings.xml
@@ -31,4 +31,7 @@
     <string name="task_contents_description_with_remaining_time" msgid="4479688746574672685">"<xliff:g id="TASK_DESCRIPTION">%1$s</xliff:g> (<xliff:g id="REMAINING_TIME">%2$s</xliff:g>)"</string>
     <string name="shorter_duration_less_than_one_minute" msgid="4722015666335015336">"&lt; 1 minuto"</string>
     <string name="time_left_for_app" msgid="3111996412933644358">"Tiempo restante: <xliff:g id="TIME">%1$s</xliff:g>"</string>
+    <string name="title_app_suggestions" msgid="4185902664111965088">"Sugerencias de apps"</string>
+    <string name="all_apps_label" msgid="8542784161730910663">"Todas las apps"</string>
+    <string name="all_apps_prediction_tip" msgid="2672336544844936186">"Predicción de tus apps"</string>
 </resources>
diff --git a/quickstep/res/values-es/strings.xml b/quickstep/res/values-es/strings.xml
index 3a588e5..329286b 100644
--- a/quickstep/res/values-es/strings.xml
+++ b/quickstep/res/values-es/strings.xml
@@ -31,4 +31,7 @@
     <string name="task_contents_description_with_remaining_time" msgid="4479688746574672685">"<xliff:g id="TASK_DESCRIPTION">%1$s</xliff:g> (<xliff:g id="REMAINING_TIME">%2$s</xliff:g>)"</string>
     <string name="shorter_duration_less_than_one_minute" msgid="4722015666335015336">"&lt;1 minuto"</string>
     <string name="time_left_for_app" msgid="3111996412933644358">"tiempo restante: <xliff:g id="TIME">%1$s</xliff:g>"</string>
+    <string name="title_app_suggestions" msgid="4185902664111965088">"Sugerencias de aplicaciones"</string>
+    <string name="all_apps_label" msgid="8542784161730910663">"Todas las aplicaciones"</string>
+    <string name="all_apps_prediction_tip" msgid="2672336544844936186">"Predicción de aplicaciones"</string>
 </resources>
diff --git a/quickstep/res/values-et/strings.xml b/quickstep/res/values-et/strings.xml
index 7032765..0577b0f 100644
--- a/quickstep/res/values-et/strings.xml
+++ b/quickstep/res/values-et/strings.xml
@@ -31,4 +31,7 @@
     <string name="task_contents_description_with_remaining_time" msgid="4479688746574672685">"<xliff:g id="TASK_DESCRIPTION">%1$s</xliff:g> <xliff:g id="REMAINING_TIME">%2$s</xliff:g>"</string>
     <string name="shorter_duration_less_than_one_minute" msgid="4722015666335015336">"&lt; 1 minut"</string>
     <string name="time_left_for_app" msgid="3111996412933644358">"Tääna jäänud <xliff:g id="TIME">%1$s</xliff:g>"</string>
+    <string name="title_app_suggestions" msgid="4185902664111965088">"Rakenduste soovitused"</string>
+    <string name="all_apps_label" msgid="8542784161730910663">"Kõik rakendused"</string>
+    <string name="all_apps_prediction_tip" msgid="2672336544844936186">"Teie ennustatud rakendused"</string>
 </resources>
diff --git a/quickstep/res/values-eu/strings.xml b/quickstep/res/values-eu/strings.xml
index 66e08b9..c2d149e 100644
--- a/quickstep/res/values-eu/strings.xml
+++ b/quickstep/res/values-eu/strings.xml
@@ -31,4 +31,7 @@
     <string name="task_contents_description_with_remaining_time" msgid="4479688746574672685">"<xliff:g id="TASK_DESCRIPTION">%1$s</xliff:g> (<xliff:g id="REMAINING_TIME">%2$s</xliff:g>)"</string>
     <string name="shorter_duration_less_than_one_minute" msgid="4722015666335015336">"&lt; 1 min"</string>
     <string name="time_left_for_app" msgid="3111996412933644358">"<xliff:g id="TIME">%1$s</xliff:g> gelditzen dira gaur"</string>
+    <string name="title_app_suggestions" msgid="4185902664111965088">"Iradokitako aplikazioak"</string>
+    <string name="all_apps_label" msgid="8542784161730910663">"Aplikazio guztiak"</string>
+    <string name="all_apps_prediction_tip" msgid="2672336544844936186">"Lagungarri izan dakizkizukeen aplikazioak"</string>
 </resources>
diff --git a/quickstep/res/values-fa/strings.xml b/quickstep/res/values-fa/strings.xml
index 112d04c..cc26695 100644
--- a/quickstep/res/values-fa/strings.xml
+++ b/quickstep/res/values-fa/strings.xml
@@ -31,4 +31,7 @@
     <string name="task_contents_description_with_remaining_time" msgid="4479688746574672685">"<xliff:g id="TASK_DESCRIPTION">%1$s</xliff:g>، <xliff:g id="REMAINING_TIME">%2$s</xliff:g>"</string>
     <string name="shorter_duration_less_than_one_minute" msgid="4722015666335015336">"&lt; ۱ دقیقه"</string>
     <string name="time_left_for_app" msgid="3111996412933644358">"<xliff:g id="TIME">%1$s</xliff:g> باقی‌مانده برای امروز"</string>
+    <string name="title_app_suggestions" msgid="4185902664111965088">"برنامه‌های پیشنهادی"</string>
+    <string name="all_apps_label" msgid="8542784161730910663">"همه برنامه‌ها"</string>
+    <string name="all_apps_prediction_tip" msgid="2672336544844936186">"برنامه‌های پیش‌بینی‌شده"</string>
 </resources>
diff --git a/quickstep/res/values-fi/strings.xml b/quickstep/res/values-fi/strings.xml
index 6a0a359..f43433e 100644
--- a/quickstep/res/values-fi/strings.xml
+++ b/quickstep/res/values-fi/strings.xml
@@ -31,4 +31,7 @@
     <string name="task_contents_description_with_remaining_time" msgid="4479688746574672685">"<xliff:g id="TASK_DESCRIPTION">%1$s</xliff:g>, <xliff:g id="REMAINING_TIME">%2$s</xliff:g>"</string>
     <string name="shorter_duration_less_than_one_minute" msgid="4722015666335015336">"&lt; 1 min"</string>
     <string name="time_left_for_app" msgid="3111996412933644358">"<xliff:g id="TIME">%1$s</xliff:g> jäljellä tänään"</string>
+    <string name="title_app_suggestions" msgid="4185902664111965088">"Sovellusehdotukset"</string>
+    <string name="all_apps_label" msgid="8542784161730910663">"Kaikki sovellukset"</string>
+    <string name="all_apps_prediction_tip" msgid="2672336544844936186">"Sovellusennusteet"</string>
 </resources>
diff --git a/quickstep/res/values-fr-rCA/strings.xml b/quickstep/res/values-fr-rCA/strings.xml
index 248a5da..a9a1cff 100644
--- a/quickstep/res/values-fr-rCA/strings.xml
+++ b/quickstep/res/values-fr-rCA/strings.xml
@@ -31,4 +31,7 @@
     <string name="task_contents_description_with_remaining_time" msgid="4479688746574672685">"<xliff:g id="TASK_DESCRIPTION">%1$s</xliff:g> : <xliff:g id="REMAINING_TIME">%2$s</xliff:g>"</string>
     <string name="shorter_duration_less_than_one_minute" msgid="4722015666335015336">"&lt; 1 min"</string>
     <string name="time_left_for_app" msgid="3111996412933644358">"Il reste <xliff:g id="TIME">%1$s</xliff:g> aujourd\'hui"</string>
+    <string name="title_app_suggestions" msgid="4185902664111965088">"Suggestions d\'applications"</string>
+    <string name="all_apps_label" msgid="8542784161730910663">"Toutes les applications"</string>
+    <string name="all_apps_prediction_tip" msgid="2672336544844936186">"Vos prédictions d\'applications"</string>
 </resources>
diff --git a/quickstep/res/values-fr/strings.xml b/quickstep/res/values-fr/strings.xml
index 338d9ba..5394f49 100644
--- a/quickstep/res/values-fr/strings.xml
+++ b/quickstep/res/values-fr/strings.xml
@@ -31,4 +31,7 @@
     <string name="task_contents_description_with_remaining_time" msgid="4479688746574672685">"<xliff:g id="TASK_DESCRIPTION">%1$s</xliff:g>, <xliff:g id="REMAINING_TIME">%2$s</xliff:g>"</string>
     <string name="shorter_duration_less_than_one_minute" msgid="4722015666335015336">"&lt; 1 min"</string>
     <string name="time_left_for_app" msgid="3111996412933644358">"Encore <xliff:g id="TIME">%1$s</xliff:g> aujourd\'hui"</string>
+    <string name="title_app_suggestions" msgid="4185902664111965088">"Suggestions d\'applications"</string>
+    <string name="all_apps_label" msgid="8542784161730910663">"Toutes les applications"</string>
+    <string name="all_apps_prediction_tip" msgid="2672336544844936186">"Vos applications prévues"</string>
 </resources>
diff --git a/quickstep/res/values-gl/strings.xml b/quickstep/res/values-gl/strings.xml
index d6ddf3c..c6698bb 100644
--- a/quickstep/res/values-gl/strings.xml
+++ b/quickstep/res/values-gl/strings.xml
@@ -31,4 +31,7 @@
     <string name="task_contents_description_with_remaining_time" msgid="4479688746574672685">"<xliff:g id="TASK_DESCRIPTION">%1$s</xliff:g> (<xliff:g id="REMAINING_TIME">%2$s</xliff:g>)"</string>
     <string name="shorter_duration_less_than_one_minute" msgid="4722015666335015336">"&lt;1 min"</string>
     <string name="time_left_for_app" msgid="3111996412933644358">"Tempo restante hoxe <xliff:g id="TIME">%1$s</xliff:g>"</string>
+    <string name="title_app_suggestions" msgid="4185902664111965088">"Suxestións de aplicacións"</string>
+    <string name="all_apps_label" msgid="8542784161730910663">"Todas as aplicacións"</string>
+    <string name="all_apps_prediction_tip" msgid="2672336544844936186">"As túas aplicacións preditas"</string>
 </resources>
diff --git a/quickstep/res/values-gu/strings.xml b/quickstep/res/values-gu/strings.xml
index 4493e3b..660ad87 100644
--- a/quickstep/res/values-gu/strings.xml
+++ b/quickstep/res/values-gu/strings.xml
@@ -31,4 +31,7 @@
     <string name="task_contents_description_with_remaining_time" msgid="4479688746574672685">"<xliff:g id="TASK_DESCRIPTION">%1$s</xliff:g>, <xliff:g id="REMAINING_TIME">%2$s</xliff:g>"</string>
     <string name="shorter_duration_less_than_one_minute" msgid="4722015666335015336">"&lt; 1 મિનિટ"</string>
     <string name="time_left_for_app" msgid="3111996412933644358">"<xliff:g id="TIME">%1$s</xliff:g> આજે બાકી"</string>
+    <string name="title_app_suggestions" msgid="4185902664111965088">"ઍપ સૂચનો"</string>
+    <string name="all_apps_label" msgid="8542784161730910663">"બધી ઍપ"</string>
+    <string name="all_apps_prediction_tip" msgid="2672336544844936186">"તમારી પૂર્વાનુમાનિત ઍપ"</string>
 </resources>
diff --git a/quickstep/res/values-hi/strings.xml b/quickstep/res/values-hi/strings.xml
index 3c53cce..0467af4 100644
--- a/quickstep/res/values-hi/strings.xml
+++ b/quickstep/res/values-hi/strings.xml
@@ -31,4 +31,7 @@
     <string name="task_contents_description_with_remaining_time" msgid="4479688746574672685">"<xliff:g id="TASK_DESCRIPTION">%1$s</xliff:g>, <xliff:g id="REMAINING_TIME">%2$s</xliff:g>"</string>
     <string name="shorter_duration_less_than_one_minute" msgid="4722015666335015336">"&lt;1 मिनट"</string>
     <string name="time_left_for_app" msgid="3111996412933644358">"आज <xliff:g id="TIME">%1$s</xliff:g> और चलेगा"</string>
+    <string name="title_app_suggestions" msgid="4185902664111965088">"ऐप्लिकेशन के सुझाव"</string>
+    <string name="all_apps_label" msgid="8542784161730910663">"सभी ऐप्लिकेशन"</string>
+    <string name="all_apps_prediction_tip" msgid="2672336544844936186">"आपके काम के ऐप्लिकेशन"</string>
 </resources>
diff --git a/quickstep/res/values-hr/strings.xml b/quickstep/res/values-hr/strings.xml
index 103710f..ab56e57 100644
--- a/quickstep/res/values-hr/strings.xml
+++ b/quickstep/res/values-hr/strings.xml
@@ -31,4 +31,7 @@
     <string name="task_contents_description_with_remaining_time" msgid="4479688746574672685">"<xliff:g id="TASK_DESCRIPTION">%1$s</xliff:g>, <xliff:g id="REMAINING_TIME">%2$s</xliff:g>"</string>
     <string name="shorter_duration_less_than_one_minute" msgid="4722015666335015336">"&lt; 1 min"</string>
     <string name="time_left_for_app" msgid="3111996412933644358">"Još <xliff:g id="TIME">%1$s</xliff:g> danas"</string>
+    <string name="title_app_suggestions" msgid="4185902664111965088">"Predložene aplikacije"</string>
+    <string name="all_apps_label" msgid="8542784161730910663">"Sve aplikacije"</string>
+    <string name="all_apps_prediction_tip" msgid="2672336544844936186">"Vaše predviđene aplikacije"</string>
 </resources>
diff --git a/quickstep/res/values-hu/strings.xml b/quickstep/res/values-hu/strings.xml
index 22b2380..dec6ea0 100644
--- a/quickstep/res/values-hu/strings.xml
+++ b/quickstep/res/values-hu/strings.xml
@@ -31,4 +31,7 @@
     <string name="task_contents_description_with_remaining_time" msgid="4479688746574672685">"<xliff:g id="TASK_DESCRIPTION">%1$s</xliff:g>, <xliff:g id="REMAINING_TIME">%2$s</xliff:g>"</string>
     <string name="shorter_duration_less_than_one_minute" msgid="4722015666335015336">"&lt; 1 perc"</string>
     <string name="time_left_for_app" msgid="3111996412933644358">"Ma még <xliff:g id="TIME">%1$s</xliff:g> van hátra"</string>
+    <string name="title_app_suggestions" msgid="4185902664111965088">"Alkalmazásjavaslatok"</string>
+    <string name="all_apps_label" msgid="8542784161730910663">"Az összes alkalmazás"</string>
+    <string name="all_apps_prediction_tip" msgid="2672336544844936186">"Várható alkalmazások"</string>
 </resources>
diff --git a/quickstep/res/values-hy/strings.xml b/quickstep/res/values-hy/strings.xml
index 910265a..1656a14 100644
--- a/quickstep/res/values-hy/strings.xml
+++ b/quickstep/res/values-hy/strings.xml
@@ -31,4 +31,7 @@
     <string name="task_contents_description_with_remaining_time" msgid="4479688746574672685">"<xliff:g id="TASK_DESCRIPTION">%1$s</xliff:g>, <xliff:g id="REMAINING_TIME">%2$s</xliff:g>"</string>
     <string name="shorter_duration_less_than_one_minute" msgid="4722015666335015336">"&lt; 1 ր"</string>
     <string name="time_left_for_app" msgid="3111996412933644358">"Այսօր մնացել է՝ <xliff:g id="TIME">%1$s</xliff:g>"</string>
+    <string name="title_app_suggestions" msgid="4185902664111965088">"Առաջարկվող հավելվածներ"</string>
+    <string name="all_apps_label" msgid="8542784161730910663">"Բոլոր հավելվածները"</string>
+    <string name="all_apps_prediction_tip" msgid="2672336544844936186">"Ձեր կանխատեսված հավելվածները"</string>
 </resources>
diff --git a/quickstep/res/values-in/strings.xml b/quickstep/res/values-in/strings.xml
index a7749df..6824d16 100644
--- a/quickstep/res/values-in/strings.xml
+++ b/quickstep/res/values-in/strings.xml
@@ -31,4 +31,7 @@
     <string name="task_contents_description_with_remaining_time" msgid="4479688746574672685">"<xliff:g id="TASK_DESCRIPTION">%1$s</xliff:g>, <xliff:g id="REMAINING_TIME">%2$s</xliff:g>"</string>
     <string name="shorter_duration_less_than_one_minute" msgid="4722015666335015336">"&lt; 1 menit"</string>
     <string name="time_left_for_app" msgid="3111996412933644358">"<xliff:g id="TIME">%1$s</xliff:g> tersisa hari ini"</string>
+    <string name="title_app_suggestions" msgid="4185902664111965088">"Saran aplikasi"</string>
+    <string name="all_apps_label" msgid="8542784161730910663">"Semua aplikasi"</string>
+    <string name="all_apps_prediction_tip" msgid="2672336544844936186">"Aplikasi yang diprediksi"</string>
 </resources>
diff --git a/quickstep/res/values-is/strings.xml b/quickstep/res/values-is/strings.xml
index ba0c672..f60a2c6 100644
--- a/quickstep/res/values-is/strings.xml
+++ b/quickstep/res/values-is/strings.xml
@@ -31,4 +31,7 @@
     <string name="task_contents_description_with_remaining_time" msgid="4479688746574672685">"<xliff:g id="TASK_DESCRIPTION">%1$s</xliff:g>, <xliff:g id="REMAINING_TIME">%2$s</xliff:g>"</string>
     <string name="shorter_duration_less_than_one_minute" msgid="4722015666335015336">"&lt; 1 mín."</string>
     <string name="time_left_for_app" msgid="3111996412933644358">"<xliff:g id="TIME">%1$s</xliff:g> eftir í dag"</string>
+    <string name="title_app_suggestions" msgid="4185902664111965088">"Tillögur að forritum"</string>
+    <string name="all_apps_label" msgid="8542784161730910663">"Öll forrit"</string>
+    <string name="all_apps_prediction_tip" msgid="2672336544844936186">"Spáð forrit"</string>
 </resources>
diff --git a/quickstep/res/values-it/strings.xml b/quickstep/res/values-it/strings.xml
index 746443e..559fdb4 100644
--- a/quickstep/res/values-it/strings.xml
+++ b/quickstep/res/values-it/strings.xml
@@ -31,4 +31,7 @@
     <string name="task_contents_description_with_remaining_time" msgid="4479688746574672685">"<xliff:g id="TASK_DESCRIPTION">%1$s</xliff:g>, <xliff:g id="REMAINING_TIME">%2$s</xliff:g>"</string>
     <string name="shorter_duration_less_than_one_minute" msgid="4722015666335015336">"&lt; 1 min"</string>
     <string name="time_left_for_app" msgid="3111996412933644358">"Rimanente oggi: <xliff:g id="TIME">%1$s</xliff:g>"</string>
+    <string name="title_app_suggestions" msgid="4185902664111965088">"App suggerite"</string>
+    <string name="all_apps_label" msgid="8542784161730910663">"Tutte le app"</string>
+    <string name="all_apps_prediction_tip" msgid="2672336544844936186">"Le app previste"</string>
 </resources>
diff --git a/quickstep/res/values-iw/strings.xml b/quickstep/res/values-iw/strings.xml
index 96a8adc..58cab4e 100644
--- a/quickstep/res/values-iw/strings.xml
+++ b/quickstep/res/values-iw/strings.xml
@@ -31,4 +31,7 @@
     <string name="task_contents_description_with_remaining_time" msgid="4479688746574672685">"<xliff:g id="TASK_DESCRIPTION">%1$s</xliff:g>, <xliff:g id="REMAINING_TIME">%2$s</xliff:g>"</string>
     <string name="shorter_duration_less_than_one_minute" msgid="4722015666335015336">"‏&lt; דקה"</string>
     <string name="time_left_for_app" msgid="3111996412933644358">"הזמן שנותר להיום: <xliff:g id="TIME">%1$s</xliff:g>"</string>
+    <string name="title_app_suggestions" msgid="4185902664111965088">"הצעות לאפליקציות"</string>
+    <string name="all_apps_label" msgid="8542784161730910663">"כל האפליקציות"</string>
+    <string name="all_apps_prediction_tip" msgid="2672336544844936186">"האפליקציות החזויות שלך"</string>
 </resources>
diff --git a/quickstep/res/values-ja/strings.xml b/quickstep/res/values-ja/strings.xml
index 5484ae1..d3fecde 100644
--- a/quickstep/res/values-ja/strings.xml
+++ b/quickstep/res/values-ja/strings.xml
@@ -31,4 +31,7 @@
     <string name="task_contents_description_with_remaining_time" msgid="4479688746574672685">"<xliff:g id="TASK_DESCRIPTION">%1$s</xliff:g>、<xliff:g id="REMAINING_TIME">%2$s</xliff:g>"</string>
     <string name="shorter_duration_less_than_one_minute" msgid="4722015666335015336">"1 分未満"</string>
     <string name="time_left_for_app" msgid="3111996412933644358">"今日はあと <xliff:g id="TIME">%1$s</xliff:g>です"</string>
+    <string name="title_app_suggestions" msgid="4185902664111965088">"アプリの候補"</string>
+    <string name="all_apps_label" msgid="8542784161730910663">"すべてのアプリ"</string>
+    <string name="all_apps_prediction_tip" msgid="2672336544844936186">"予測されたアプリ"</string>
 </resources>
diff --git a/quickstep/res/values-ka/strings.xml b/quickstep/res/values-ka/strings.xml
index 9218fb8..67b03a7 100644
--- a/quickstep/res/values-ka/strings.xml
+++ b/quickstep/res/values-ka/strings.xml
@@ -31,4 +31,7 @@
     <string name="task_contents_description_with_remaining_time" msgid="4479688746574672685">"<xliff:g id="TASK_DESCRIPTION">%1$s</xliff:g>, <xliff:g id="REMAINING_TIME">%2$s</xliff:g>"</string>
     <string name="shorter_duration_less_than_one_minute" msgid="4722015666335015336">"&lt; 1 წუთი"</string>
     <string name="time_left_for_app" msgid="3111996412933644358">"დღეს დარჩენილია <xliff:g id="TIME">%1$s</xliff:g>"</string>
+    <string name="title_app_suggestions" msgid="4185902664111965088">"აპების შემოთავაზებები"</string>
+    <string name="all_apps_label" msgid="8542784161730910663">"ყველა აპი"</string>
+    <string name="all_apps_prediction_tip" msgid="2672336544844936186">"თქვენი პროგნოზირებული აპები"</string>
 </resources>
diff --git a/quickstep/res/values-kk/strings.xml b/quickstep/res/values-kk/strings.xml
index 0766150..a9fcbed 100644
--- a/quickstep/res/values-kk/strings.xml
+++ b/quickstep/res/values-kk/strings.xml
@@ -31,4 +31,7 @@
     <string name="task_contents_description_with_remaining_time" msgid="4479688746574672685">"<xliff:g id="TASK_DESCRIPTION">%1$s</xliff:g>, <xliff:g id="REMAINING_TIME">%2$s</xliff:g>"</string>
     <string name="shorter_duration_less_than_one_minute" msgid="4722015666335015336">"&lt; 1 мин"</string>
     <string name="time_left_for_app" msgid="3111996412933644358">"Бүгін <xliff:g id="TIME">%1$s</xliff:g> қалды"</string>
+    <string name="title_app_suggestions" msgid="4185902664111965088">"Қолданба ұсыныстары"</string>
+    <string name="all_apps_label" msgid="8542784161730910663">"Барлық қолданбалар"</string>
+    <string name="all_apps_prediction_tip" msgid="2672336544844936186">"Ұсынылатын қолданбалар"</string>
 </resources>
diff --git a/quickstep/res/values-km/strings.xml b/quickstep/res/values-km/strings.xml
index 8737ae8..c422041 100644
--- a/quickstep/res/values-km/strings.xml
+++ b/quickstep/res/values-km/strings.xml
@@ -31,4 +31,7 @@
     <string name="task_contents_description_with_remaining_time" msgid="4479688746574672685">"<xliff:g id="TASK_DESCRIPTION">%1$s</xliff:g>, <xliff:g id="REMAINING_TIME">%2$s</xliff:g>"</string>
     <string name="shorter_duration_less_than_one_minute" msgid="4722015666335015336">"&lt; 1 នាទី"</string>
     <string name="time_left_for_app" msgid="3111996412933644358">"នៅសល់ <xliff:g id="TIME">%1$s</xliff:g> ទៀត​នៅថ្ងៃនេះ"</string>
+    <string name="title_app_suggestions" msgid="4185902664111965088">"ការណែនាំកម្មវិធី"</string>
+    <string name="all_apps_label" msgid="8542784161730910663">"កម្មវិធី​ទាំងអស់"</string>
+    <string name="all_apps_prediction_tip" msgid="2672336544844936186">"កម្មវិធី​ដែលបាន​ព្យាករ​របស់អ្នក"</string>
 </resources>
diff --git a/quickstep/res/values-kn/strings.xml b/quickstep/res/values-kn/strings.xml
index 099957c..5278261 100644
--- a/quickstep/res/values-kn/strings.xml
+++ b/quickstep/res/values-kn/strings.xml
@@ -31,4 +31,7 @@
     <string name="task_contents_description_with_remaining_time" msgid="4479688746574672685">"<xliff:g id="TASK_DESCRIPTION">%1$s</xliff:g>, <xliff:g id="REMAINING_TIME">%2$s</xliff:g>"</string>
     <string name="shorter_duration_less_than_one_minute" msgid="4722015666335015336">"&lt; 1 ನಿ"</string>
     <string name="time_left_for_app" msgid="3111996412933644358">"ಇಂದು <xliff:g id="TIME">%1$s</xliff:g> ಸಮಯ ಉಳಿದಿದೆ"</string>
+    <string name="title_app_suggestions" msgid="4185902664111965088">"ಆ್ಯಪ್ ಸಲಹೆಗಳು"</string>
+    <string name="all_apps_label" msgid="8542784161730910663">"ಎಲ್ಲಾ ಆ್ಯಪ್‌ಗಳು"</string>
+    <string name="all_apps_prediction_tip" msgid="2672336544844936186">"ನಿಮ್ಮ ಸಂಭವನೀಯ ಆ್ಯಪ್‌ಗಳು"</string>
 </resources>
diff --git a/quickstep/res/values-ko/strings.xml b/quickstep/res/values-ko/strings.xml
index 9543e79..7a8e6a1 100644
--- a/quickstep/res/values-ko/strings.xml
+++ b/quickstep/res/values-ko/strings.xml
@@ -31,4 +31,7 @@
     <string name="task_contents_description_with_remaining_time" msgid="4479688746574672685">"<xliff:g id="TASK_DESCRIPTION">%1$s</xliff:g>, <xliff:g id="REMAINING_TIME">%2$s</xliff:g>"</string>
     <string name="shorter_duration_less_than_one_minute" msgid="4722015666335015336">"&lt; 1분"</string>
     <string name="time_left_for_app" msgid="3111996412933644358">"오늘 <xliff:g id="TIME">%1$s</xliff:g> 남음"</string>
+    <string name="title_app_suggestions" msgid="4185902664111965088">"앱 추천"</string>
+    <string name="all_apps_label" msgid="8542784161730910663">"모든 앱"</string>
+    <string name="all_apps_prediction_tip" msgid="2672336544844936186">"추천 앱"</string>
 </resources>
diff --git a/quickstep/res/values-ky/strings.xml b/quickstep/res/values-ky/strings.xml
index d1d2d20..4018e57 100644
--- a/quickstep/res/values-ky/strings.xml
+++ b/quickstep/res/values-ky/strings.xml
@@ -31,4 +31,7 @@
     <string name="task_contents_description_with_remaining_time" msgid="4479688746574672685">"<xliff:g id="TASK_DESCRIPTION">%1$s</xliff:g>, <xliff:g id="REMAINING_TIME">%2$s</xliff:g>"</string>
     <string name="shorter_duration_less_than_one_minute" msgid="4722015666335015336">"&lt; 1 мүнөт"</string>
     <string name="time_left_for_app" msgid="3111996412933644358">"Бүгүн <xliff:g id="TIME">%1$s</xliff:g> мүнөт калды"</string>
+    <string name="title_app_suggestions" msgid="4185902664111965088">"Колдонмо сунуштары"</string>
+    <string name="all_apps_label" msgid="8542784161730910663">"Бардык колдонмолор"</string>
+    <string name="all_apps_prediction_tip" msgid="2672336544844936186">"Божомолдонгон колдонмолоруңуз"</string>
 </resources>
diff --git a/quickstep/res/values-lo/strings.xml b/quickstep/res/values-lo/strings.xml
index aba4156..e406b70 100644
--- a/quickstep/res/values-lo/strings.xml
+++ b/quickstep/res/values-lo/strings.xml
@@ -31,4 +31,7 @@
     <string name="task_contents_description_with_remaining_time" msgid="4479688746574672685">"<xliff:g id="TASK_DESCRIPTION">%1$s</xliff:g>, <xliff:g id="REMAINING_TIME">%2$s</xliff:g>"</string>
     <string name="shorter_duration_less_than_one_minute" msgid="4722015666335015336">"&lt; 1 ນາທີ"</string>
     <string name="time_left_for_app" msgid="3111996412933644358">"ເຫຼືອ <xliff:g id="TIME">%1$s</xliff:g> ມື້ນີ້"</string>
+    <string name="title_app_suggestions" msgid="4185902664111965088">"ການແນະນຳແອັບ"</string>
+    <string name="all_apps_label" msgid="8542784161730910663">"ແອັບທັງໝົດ"</string>
+    <string name="all_apps_prediction_tip" msgid="2672336544844936186">"ແອັບທີ່ຄາດເດົາໄວ້ແລ້ວຂອງທ່ານ"</string>
 </resources>
diff --git a/quickstep/res/values-lt/strings.xml b/quickstep/res/values-lt/strings.xml
index 933b3f0..ed1fc37 100644
--- a/quickstep/res/values-lt/strings.xml
+++ b/quickstep/res/values-lt/strings.xml
@@ -31,4 +31,7 @@
     <string name="task_contents_description_with_remaining_time" msgid="4479688746574672685">"<xliff:g id="TASK_DESCRIPTION">%1$s</xliff:g>, <xliff:g id="REMAINING_TIME">%2$s</xliff:g>"</string>
     <string name="shorter_duration_less_than_one_minute" msgid="4722015666335015336">"&lt; 1 min."</string>
     <string name="time_left_for_app" msgid="3111996412933644358">"Šiandien liko: <xliff:g id="TIME">%1$s</xliff:g>"</string>
+    <string name="title_app_suggestions" msgid="4185902664111965088">"Programų pasiūlymai"</string>
+    <string name="all_apps_label" msgid="8542784161730910663">"Visos programos"</string>
+    <string name="all_apps_prediction_tip" msgid="2672336544844936186">"Numatomos programos"</string>
 </resources>
diff --git a/quickstep/res/values-lv/strings.xml b/quickstep/res/values-lv/strings.xml
index 1e2ed00..85ce0e0 100644
--- a/quickstep/res/values-lv/strings.xml
+++ b/quickstep/res/values-lv/strings.xml
@@ -31,4 +31,7 @@
     <string name="task_contents_description_with_remaining_time" msgid="4479688746574672685">"<xliff:g id="TASK_DESCRIPTION">%1$s</xliff:g>, <xliff:g id="REMAINING_TIME">%2$s</xliff:g>"</string>
     <string name="shorter_duration_less_than_one_minute" msgid="4722015666335015336">"&lt;1 minūte"</string>
     <string name="time_left_for_app" msgid="3111996412933644358">"Šodien atlicis: <xliff:g id="TIME">%1$s</xliff:g>"</string>
+    <string name="title_app_suggestions" msgid="4185902664111965088">"Ieteicamās lietotnes"</string>
+    <string name="all_apps_label" msgid="8542784161730910663">"Visas lietotnes"</string>
+    <string name="all_apps_prediction_tip" msgid="2672336544844936186">"Jūsu prognozētās lietotnes"</string>
 </resources>
diff --git a/quickstep/res/values-mk/strings.xml b/quickstep/res/values-mk/strings.xml
index 7a6c094..9f11521 100644
--- a/quickstep/res/values-mk/strings.xml
+++ b/quickstep/res/values-mk/strings.xml
@@ -31,4 +31,7 @@
     <string name="task_contents_description_with_remaining_time" msgid="4479688746574672685">"<xliff:g id="TASK_DESCRIPTION">%1$s</xliff:g>, <xliff:g id="REMAINING_TIME">%2$s</xliff:g>"</string>
     <string name="shorter_duration_less_than_one_minute" msgid="4722015666335015336">"&lt; 1 минута"</string>
     <string name="time_left_for_app" msgid="3111996412933644358">"Уште <xliff:g id="TIME">%1$s</xliff:g> за денес"</string>
+    <string name="title_app_suggestions" msgid="4185902664111965088">"Предлози за апликации"</string>
+    <string name="all_apps_label" msgid="8542784161730910663">"Сите апликации"</string>
+    <string name="all_apps_prediction_tip" msgid="2672336544844936186">"Вашите предвидени апликации"</string>
 </resources>
diff --git a/quickstep/res/values-ml/strings.xml b/quickstep/res/values-ml/strings.xml
index b5eac1d..2e02e80 100644
--- a/quickstep/res/values-ml/strings.xml
+++ b/quickstep/res/values-ml/strings.xml
@@ -31,4 +31,7 @@
     <string name="task_contents_description_with_remaining_time" msgid="4479688746574672685">"<xliff:g id="TASK_DESCRIPTION">%1$s</xliff:g>, <xliff:g id="REMAINING_TIME">%2$s</xliff:g>"</string>
     <string name="shorter_duration_less_than_one_minute" msgid="4722015666335015336">"&lt; 1 മിനിറ്റ്"</string>
     <string name="time_left_for_app" msgid="3111996412933644358">"ഇന്ന് <xliff:g id="TIME">%1$s</xliff:g> ശേഷിക്കുന്നു"</string>
+    <string name="title_app_suggestions" msgid="4185902664111965088">"ആപ്പ് നിർദ്ദേശങ്ങൾ"</string>
+    <string name="all_apps_label" msgid="8542784161730910663">"എല്ലാ ആപ്പുകളും"</string>
+    <string name="all_apps_prediction_tip" msgid="2672336544844936186">"നിങ്ങളുടെ പ്രവചിക്കപ്പെട്ട ആപ്പുകൾ"</string>
 </resources>
diff --git a/quickstep/res/values-mn/strings.xml b/quickstep/res/values-mn/strings.xml
index a105ef1..5de8602 100644
--- a/quickstep/res/values-mn/strings.xml
+++ b/quickstep/res/values-mn/strings.xml
@@ -31,4 +31,7 @@
     <string name="task_contents_description_with_remaining_time" msgid="4479688746574672685">"<xliff:g id="TASK_DESCRIPTION">%1$s</xliff:g>, <xliff:g id="REMAINING_TIME">%2$s</xliff:g>"</string>
     <string name="shorter_duration_less_than_one_minute" msgid="4722015666335015336">"&lt; 1 минут"</string>
     <string name="time_left_for_app" msgid="3111996412933644358">"Өнөөдөр <xliff:g id="TIME">%1$s</xliff:g> үлдсэн"</string>
+    <string name="title_app_suggestions" msgid="4185902664111965088">"Аппын зөвлөмж"</string>
+    <string name="all_apps_label" msgid="8542784161730910663">"Бүх апп"</string>
+    <string name="all_apps_prediction_tip" msgid="2672336544844936186">"Таны таамагласан аппууд"</string>
 </resources>
diff --git a/quickstep/res/values-mr/strings.xml b/quickstep/res/values-mr/strings.xml
index bf725e3..1ca558a 100644
--- a/quickstep/res/values-mr/strings.xml
+++ b/quickstep/res/values-mr/strings.xml
@@ -31,4 +31,7 @@
     <string name="task_contents_description_with_remaining_time" msgid="4479688746574672685">"<xliff:g id="TASK_DESCRIPTION">%1$s</xliff:g>, <xliff:g id="REMAINING_TIME">%2$s</xliff:g>"</string>
     <string name="shorter_duration_less_than_one_minute" msgid="4722015666335015336">"१मिहून कमी"</string>
     <string name="time_left_for_app" msgid="3111996412933644358">"आज <xliff:g id="TIME">%1$s</xliff:g>शिल्लक आहे"</string>
+    <string name="title_app_suggestions" msgid="4185902664111965088">"अ‍ॅप सूचना"</string>
+    <string name="all_apps_label" msgid="8542784161730910663">"सर्व अ‍ॅप्स"</string>
+    <string name="all_apps_prediction_tip" msgid="2672336544844936186">"तुमची पूर्वानुमानीत अ‍ॅप्स"</string>
 </resources>
diff --git a/quickstep/res/values-ms/strings.xml b/quickstep/res/values-ms/strings.xml
index 2e3f236..2542963 100644
--- a/quickstep/res/values-ms/strings.xml
+++ b/quickstep/res/values-ms/strings.xml
@@ -31,4 +31,7 @@
     <string name="task_contents_description_with_remaining_time" msgid="4479688746574672685">"<xliff:g id="TASK_DESCRIPTION">%1$s</xliff:g>, <xliff:g id="REMAINING_TIME">%2$s</xliff:g>"</string>
     <string name="shorter_duration_less_than_one_minute" msgid="4722015666335015336">"&lt; 1 minit"</string>
     <string name="time_left_for_app" msgid="3111996412933644358">"<xliff:g id="TIME">%1$s</xliff:g> lagi hari ini"</string>
+    <string name="title_app_suggestions" msgid="4185902664111965088">"Cadangan apl"</string>
+    <string name="all_apps_label" msgid="8542784161730910663">"Semua apl"</string>
+    <string name="all_apps_prediction_tip" msgid="2672336544844936186">"Apl ramalan anda"</string>
 </resources>
diff --git a/quickstep/res/values-my/strings.xml b/quickstep/res/values-my/strings.xml
index 7b93125..7683e05 100644
--- a/quickstep/res/values-my/strings.xml
+++ b/quickstep/res/values-my/strings.xml
@@ -31,4 +31,7 @@
     <string name="task_contents_description_with_remaining_time" msgid="4479688746574672685">"<xliff:g id="TASK_DESCRIPTION">%1$s</xliff:g>၊ <xliff:g id="REMAINING_TIME">%2$s</xliff:g>"</string>
     <string name="shorter_duration_less_than_one_minute" msgid="4722015666335015336">"&lt; ၁ မိနစ်"</string>
     <string name="time_left_for_app" msgid="3111996412933644358">"ယနေ့ <xliff:g id="TIME">%1$s</xliff:g> ခု ကျန်သည်"</string>
+    <string name="title_app_suggestions" msgid="4185902664111965088">"အက်ပ်အကြံပြုချက်များ"</string>
+    <string name="all_apps_label" msgid="8542784161730910663">"အက်ပ်အားလုံး"</string>
+    <string name="all_apps_prediction_tip" msgid="2672336544844936186">"သင်၏ ခန့်မှန်းအက်ပ်များ"</string>
 </resources>
diff --git a/quickstep/res/values-nb/strings.xml b/quickstep/res/values-nb/strings.xml
index 74f43d2..01bbb6a 100644
--- a/quickstep/res/values-nb/strings.xml
+++ b/quickstep/res/values-nb/strings.xml
@@ -31,4 +31,7 @@
     <string name="task_contents_description_with_remaining_time" msgid="4479688746574672685">"<xliff:g id="TASK_DESCRIPTION">%1$s</xliff:g>, <xliff:g id="REMAINING_TIME">%2$s</xliff:g>"</string>
     <string name="shorter_duration_less_than_one_minute" msgid="4722015666335015336">"&lt; 1 minutt"</string>
     <string name="time_left_for_app" msgid="3111996412933644358">"<xliff:g id="TIME">%1$s</xliff:g> gjenstår i dag"</string>
+    <string name="title_app_suggestions" msgid="4185902664111965088">"Appanbefalinger"</string>
+    <string name="all_apps_label" msgid="8542784161730910663">"Alle apper"</string>
+    <string name="all_apps_prediction_tip" msgid="2672336544844936186">"Forslag til apper"</string>
 </resources>
diff --git a/quickstep/res/values-ne/strings.xml b/quickstep/res/values-ne/strings.xml
index 6053def..60e9bd5 100644
--- a/quickstep/res/values-ne/strings.xml
+++ b/quickstep/res/values-ne/strings.xml
@@ -31,4 +31,7 @@
     <string name="task_contents_description_with_remaining_time" msgid="4479688746574672685">"<xliff:g id="TASK_DESCRIPTION">%1$s</xliff:g>, <xliff:g id="REMAINING_TIME">%2$s</xliff:g>"</string>
     <string name="shorter_duration_less_than_one_minute" msgid="4722015666335015336">"&lt; १ मिनेट"</string>
     <string name="time_left_for_app" msgid="3111996412933644358">"आज: <xliff:g id="TIME">%1$s</xliff:g> बाँकी"</string>
+    <string name="title_app_suggestions" msgid="4185902664111965088">"अनुप्रयोगसम्बन्धी सुझावहरू"</string>
+    <string name="all_apps_label" msgid="8542784161730910663">"सबै अनुप्रयोगहरू"</string>
+    <string name="all_apps_prediction_tip" msgid="2672336544844936186">"तपाईंका पूर्वानुमानित अनुप्रयोगहरू"</string>
 </resources>
diff --git a/quickstep/res/values-nl/strings.xml b/quickstep/res/values-nl/strings.xml
index 4e3a34c..8032567 100644
--- a/quickstep/res/values-nl/strings.xml
+++ b/quickstep/res/values-nl/strings.xml
@@ -31,4 +31,7 @@
     <string name="task_contents_description_with_remaining_time" msgid="4479688746574672685">"<xliff:g id="TASK_DESCRIPTION">%1$s</xliff:g>, <xliff:g id="REMAINING_TIME">%2$s</xliff:g>"</string>
     <string name="shorter_duration_less_than_one_minute" msgid="4722015666335015336">"&lt; 1 minuut"</string>
     <string name="time_left_for_app" msgid="3111996412933644358">"Nog <xliff:g id="TIME">%1$s</xliff:g> vandaag"</string>
+    <string name="title_app_suggestions" msgid="4185902664111965088">"App-suggesties"</string>
+    <string name="all_apps_label" msgid="8542784161730910663">"Alle apps"</string>
+    <string name="all_apps_prediction_tip" msgid="2672336544844936186">"Je voorspelde apps"</string>
 </resources>
diff --git a/quickstep/res/values-pa/strings.xml b/quickstep/res/values-pa/strings.xml
index 5aeeae6..58c0d2a 100644
--- a/quickstep/res/values-pa/strings.xml
+++ b/quickstep/res/values-pa/strings.xml
@@ -31,4 +31,7 @@
     <string name="task_contents_description_with_remaining_time" msgid="4479688746574672685">"<xliff:g id="TASK_DESCRIPTION">%1$s</xliff:g>, <xliff:g id="REMAINING_TIME">%2$s</xliff:g>"</string>
     <string name="shorter_duration_less_than_one_minute" msgid="4722015666335015336">"&lt; 1 ਮਿੰਟ"</string>
     <string name="time_left_for_app" msgid="3111996412933644358">"ਅੱਜ <xliff:g id="TIME">%1$s</xliff:g> ਬਾਕੀ"</string>
+    <string name="title_app_suggestions" msgid="4185902664111965088">"ਐਪ ਸੰਬੰਧੀ ਸੁਝਾਅ"</string>
+    <string name="all_apps_label" msgid="8542784161730910663">"ਸਾਰੀਆਂ ਐਪਾਂ"</string>
+    <string name="all_apps_prediction_tip" msgid="2672336544844936186">"ਤੁਹਾਡੀਆਂ ਪੂਰਵ ਅਨੁਮਾਨਿਤ ਐਪਾਂ"</string>
 </resources>
diff --git a/quickstep/res/values-pl/strings.xml b/quickstep/res/values-pl/strings.xml
index 210edcf..d83160d 100644
--- a/quickstep/res/values-pl/strings.xml
+++ b/quickstep/res/values-pl/strings.xml
@@ -31,4 +31,7 @@
     <string name="task_contents_description_with_remaining_time" msgid="4479688746574672685">"<xliff:g id="TASK_DESCRIPTION">%1$s</xliff:g>, <xliff:g id="REMAINING_TIME">%2$s</xliff:g>"</string>
     <string name="shorter_duration_less_than_one_minute" msgid="4722015666335015336">"&gt; 1 min"</string>
     <string name="time_left_for_app" msgid="3111996412933644358">"Na dziś zostało <xliff:g id="TIME">%1$s</xliff:g>"</string>
+    <string name="title_app_suggestions" msgid="4185902664111965088">"Sugerowane aplikacje"</string>
+    <string name="all_apps_label" msgid="8542784161730910663">"Wszystkie aplikacje"</string>
+    <string name="all_apps_prediction_tip" msgid="2672336544844936186">"Przewidywane aplikacje"</string>
 </resources>
diff --git a/quickstep/res/values-pt-rPT/strings.xml b/quickstep/res/values-pt-rPT/strings.xml
index 8a129d5..2fd34d6 100644
--- a/quickstep/res/values-pt-rPT/strings.xml
+++ b/quickstep/res/values-pt-rPT/strings.xml
@@ -31,4 +31,7 @@
     <string name="task_contents_description_with_remaining_time" msgid="4479688746574672685">"<xliff:g id="TASK_DESCRIPTION">%1$s</xliff:g>, <xliff:g id="REMAINING_TIME">%2$s</xliff:g>"</string>
     <string name="shorter_duration_less_than_one_minute" msgid="4722015666335015336">"&lt; 1 minuto"</string>
     <string name="time_left_for_app" msgid="3111996412933644358">"Resta(m) <xliff:g id="TIME">%1$s</xliff:g> hoje."</string>
+    <string name="title_app_suggestions" msgid="4185902664111965088">"Sugestões de aplicações"</string>
+    <string name="all_apps_label" msgid="8542784161730910663">"Todas as aplicações"</string>
+    <string name="all_apps_prediction_tip" msgid="2672336544844936186">"As suas aplicações previstas"</string>
 </resources>
diff --git a/quickstep/res/values-pt/strings.xml b/quickstep/res/values-pt/strings.xml
index e5380d5..673dfe2 100644
--- a/quickstep/res/values-pt/strings.xml
+++ b/quickstep/res/values-pt/strings.xml
@@ -31,4 +31,7 @@
     <string name="task_contents_description_with_remaining_time" msgid="4479688746574672685">"<xliff:g id="TASK_DESCRIPTION">%1$s</xliff:g>, <xliff:g id="REMAINING_TIME">%2$s</xliff:g>"</string>
     <string name="shorter_duration_less_than_one_minute" msgid="4722015666335015336">"&lt; 1 min"</string>
     <string name="time_left_for_app" msgid="3111996412933644358">"<xliff:g id="TIME">%1$s</xliff:g> restante(s) hoje"</string>
+    <string name="title_app_suggestions" msgid="4185902664111965088">"Sugestões de apps"</string>
+    <string name="all_apps_label" msgid="8542784161730910663">"Todos os apps"</string>
+    <string name="all_apps_prediction_tip" msgid="2672336544844936186">"Suas predições de apps"</string>
 </resources>
diff --git a/quickstep/res/values-ro/strings.xml b/quickstep/res/values-ro/strings.xml
index 54452a0..2ac783e 100644
--- a/quickstep/res/values-ro/strings.xml
+++ b/quickstep/res/values-ro/strings.xml
@@ -31,4 +31,7 @@
     <string name="task_contents_description_with_remaining_time" msgid="4479688746574672685">"<xliff:g id="TASK_DESCRIPTION">%1$s</xliff:g>, <xliff:g id="REMAINING_TIME">%2$s</xliff:g>"</string>
     <string name="shorter_duration_less_than_one_minute" msgid="4722015666335015336">"&lt; 1 minut"</string>
     <string name="time_left_for_app" msgid="3111996412933644358">"Au mai rămas <xliff:g id="TIME">%1$s</xliff:g> astăzi"</string>
+    <string name="title_app_suggestions" msgid="4185902664111965088">"Sugestii de aplicații"</string>
+    <string name="all_apps_label" msgid="8542784161730910663">"Toate aplicațiile"</string>
+    <string name="all_apps_prediction_tip" msgid="2672336544844936186">"Aplicațiile estimate"</string>
 </resources>
diff --git a/quickstep/res/values-ru/strings.xml b/quickstep/res/values-ru/strings.xml
index 8b2016a..5dd89a6 100644
--- a/quickstep/res/values-ru/strings.xml
+++ b/quickstep/res/values-ru/strings.xml
@@ -31,4 +31,7 @@
     <string name="task_contents_description_with_remaining_time" msgid="4479688746574672685">"<xliff:g id="TASK_DESCRIPTION">%1$s</xliff:g>: <xliff:g id="REMAINING_TIME">%2$s</xliff:g>"</string>
     <string name="shorter_duration_less_than_one_minute" msgid="4722015666335015336">"&lt; 1 мин."</string>
     <string name="time_left_for_app" msgid="3111996412933644358">"Осталось сегодня: <xliff:g id="TIME">%1$s</xliff:g>"</string>
+    <string name="title_app_suggestions" msgid="4185902664111965088">"Рекомендуемые приложения"</string>
+    <string name="all_apps_label" msgid="8542784161730910663">"Все приложения"</string>
+    <string name="all_apps_prediction_tip" msgid="2672336544844936186">"Ваши рекомендуемые приложения"</string>
 </resources>
diff --git a/quickstep/res/values-si/strings.xml b/quickstep/res/values-si/strings.xml
index 2163390..f6584c4 100644
--- a/quickstep/res/values-si/strings.xml
+++ b/quickstep/res/values-si/strings.xml
@@ -31,4 +31,7 @@
     <string name="task_contents_description_with_remaining_time" msgid="4479688746574672685">"<xliff:g id="TASK_DESCRIPTION">%1$s</xliff:g>, <xliff:g id="REMAINING_TIME">%2$s</xliff:g>"</string>
     <string name="shorter_duration_less_than_one_minute" msgid="4722015666335015336">"&lt; 1 විනාඩියක්"</string>
     <string name="time_left_for_app" msgid="3111996412933644358">"අද <xliff:g id="TIME">%1$s</xliff:g>ක් ඉතුරුයි"</string>
+    <string name="title_app_suggestions" msgid="4185902664111965088">"යෙදුම් යෝජනා"</string>
+    <string name="all_apps_label" msgid="8542784161730910663">"සියලු යෙදුම්"</string>
+    <string name="all_apps_prediction_tip" msgid="2672336544844936186">"ඔබේ පුරෝකථන කළ යෙදුම්"</string>
 </resources>
diff --git a/quickstep/res/values-sk/strings.xml b/quickstep/res/values-sk/strings.xml
index 12983db..8a9c736 100644
--- a/quickstep/res/values-sk/strings.xml
+++ b/quickstep/res/values-sk/strings.xml
@@ -31,4 +31,7 @@
     <string name="task_contents_description_with_remaining_time" msgid="4479688746574672685">"<xliff:g id="TASK_DESCRIPTION">%1$s</xliff:g>, <xliff:g id="REMAINING_TIME">%2$s</xliff:g>"</string>
     <string name="shorter_duration_less_than_one_minute" msgid="4722015666335015336">"Menej ako 1 minúta"</string>
     <string name="time_left_for_app" msgid="3111996412933644358">"Dnes ešte zostáva: <xliff:g id="TIME">%1$s</xliff:g>"</string>
+    <string name="title_app_suggestions" msgid="4185902664111965088">"Návrhy aplikácií"</string>
+    <string name="all_apps_label" msgid="8542784161730910663">"Všetky aplikácie"</string>
+    <string name="all_apps_prediction_tip" msgid="2672336544844936186">"Vaše predpovedané aplikácie"</string>
 </resources>
diff --git a/quickstep/res/values-sl/strings.xml b/quickstep/res/values-sl/strings.xml
index a940f2b..15f8f89 100644
--- a/quickstep/res/values-sl/strings.xml
+++ b/quickstep/res/values-sl/strings.xml
@@ -31,4 +31,7 @@
     <string name="task_contents_description_with_remaining_time" msgid="4479688746574672685">"<xliff:g id="TASK_DESCRIPTION">%1$s</xliff:g>, <xliff:g id="REMAINING_TIME">%2$s</xliff:g>"</string>
     <string name="shorter_duration_less_than_one_minute" msgid="4722015666335015336">"&lt; 1 min"</string>
     <string name="time_left_for_app" msgid="3111996412933644358">"Danes je ostalo še <xliff:g id="TIME">%1$s</xliff:g>"</string>
+    <string name="title_app_suggestions" msgid="4185902664111965088">"Predlogi za aplikacije"</string>
+    <string name="all_apps_label" msgid="8542784161730910663">"Vse aplikacije"</string>
+    <string name="all_apps_prediction_tip" msgid="2672336544844936186">"Predvidene aplikacije"</string>
 </resources>
diff --git a/quickstep/res/values-sq/strings.xml b/quickstep/res/values-sq/strings.xml
index e41bcb5..d8f5f28 100644
--- a/quickstep/res/values-sq/strings.xml
+++ b/quickstep/res/values-sq/strings.xml
@@ -31,4 +31,7 @@
     <string name="task_contents_description_with_remaining_time" msgid="4479688746574672685">"<xliff:g id="TASK_DESCRIPTION">%1$s</xliff:g>, <xliff:g id="REMAINING_TIME">%2$s</xliff:g>"</string>
     <string name="shorter_duration_less_than_one_minute" msgid="4722015666335015336">"&lt; 1 minutë"</string>
     <string name="time_left_for_app" msgid="3111996412933644358">"<xliff:g id="TIME">%1$s</xliff:g> të mbetura sot"</string>
+    <string name="title_app_suggestions" msgid="4185902664111965088">"Sugjerimet e aplikacioneve"</string>
+    <string name="all_apps_label" msgid="8542784161730910663">"Të gjitha aplikacionet"</string>
+    <string name="all_apps_prediction_tip" msgid="2672336544844936186">"Aplikacionet e tua të parashikuara"</string>
 </resources>
diff --git a/quickstep/res/values-sr/strings.xml b/quickstep/res/values-sr/strings.xml
index 8f26c66..b721641 100644
--- a/quickstep/res/values-sr/strings.xml
+++ b/quickstep/res/values-sr/strings.xml
@@ -31,4 +31,7 @@
     <string name="task_contents_description_with_remaining_time" msgid="4479688746574672685">"<xliff:g id="TASK_DESCRIPTION">%1$s</xliff:g>, <xliff:g id="REMAINING_TIME">%2$s</xliff:g>"</string>
     <string name="shorter_duration_less_than_one_minute" msgid="4722015666335015336">"&lt; 1 мин"</string>
     <string name="time_left_for_app" msgid="3111996412933644358">"Још <xliff:g id="TIME">%1$s</xliff:g> данас"</string>
+    <string name="title_app_suggestions" msgid="4185902664111965088">"Предлози апликација"</string>
+    <string name="all_apps_label" msgid="8542784161730910663">"Све апликације"</string>
+    <string name="all_apps_prediction_tip" msgid="2672336544844936186">"Предвиђене апликације"</string>
 </resources>
diff --git a/quickstep/res/values-sv/strings.xml b/quickstep/res/values-sv/strings.xml
index 70740e5..ba7ebcd 100644
--- a/quickstep/res/values-sv/strings.xml
+++ b/quickstep/res/values-sv/strings.xml
@@ -31,4 +31,7 @@
     <string name="task_contents_description_with_remaining_time" msgid="4479688746574672685">"<xliff:g id="TASK_DESCRIPTION">%1$s</xliff:g>, <xliff:g id="REMAINING_TIME">%2$s</xliff:g>"</string>
     <string name="shorter_duration_less_than_one_minute" msgid="4722015666335015336">"&lt; 1 min"</string>
     <string name="time_left_for_app" msgid="3111996412933644358">"<xliff:g id="TIME">%1$s</xliff:g> kvar i dag"</string>
+    <string name="title_app_suggestions" msgid="4185902664111965088">"Appförslag"</string>
+    <string name="all_apps_label" msgid="8542784161730910663">"Alla appar"</string>
+    <string name="all_apps_prediction_tip" msgid="2672336544844936186">"Föreslagna appar"</string>
 </resources>
diff --git a/quickstep/res/values-sw/strings.xml b/quickstep/res/values-sw/strings.xml
index c646b6a..24db429 100644
--- a/quickstep/res/values-sw/strings.xml
+++ b/quickstep/res/values-sw/strings.xml
@@ -31,4 +31,7 @@
     <string name="task_contents_description_with_remaining_time" msgid="4479688746574672685">"<xliff:g id="TASK_DESCRIPTION">%1$s</xliff:g>, <xliff:g id="REMAINING_TIME">%2$s</xliff:g>"</string>
     <string name="shorter_duration_less_than_one_minute" msgid="4722015666335015336">"&lt; dak 1"</string>
     <string name="time_left_for_app" msgid="3111996412933644358">"Umebakisha <xliff:g id="TIME">%1$s</xliff:g> leo"</string>
+    <string name="title_app_suggestions" msgid="4185902664111965088">"Mapendekezo ya programu"</string>
+    <string name="all_apps_label" msgid="8542784161730910663">"Programu zote"</string>
+    <string name="all_apps_prediction_tip" msgid="2672336544844936186">"Programu zako zinazopendekezwa"</string>
 </resources>
diff --git a/quickstep/res/values-ta/strings.xml b/quickstep/res/values-ta/strings.xml
index 19bfaa9..97d51cd 100644
--- a/quickstep/res/values-ta/strings.xml
+++ b/quickstep/res/values-ta/strings.xml
@@ -31,4 +31,7 @@
     <string name="task_contents_description_with_remaining_time" msgid="4479688746574672685">"<xliff:g id="TASK_DESCRIPTION">%1$s</xliff:g>, <xliff:g id="REMAINING_TIME">%2$s</xliff:g>"</string>
     <string name="shorter_duration_less_than_one_minute" msgid="4722015666335015336">"&lt; 1 நி"</string>
     <string name="time_left_for_app" msgid="3111996412933644358">"இன்று <xliff:g id="TIME">%1$s</xliff:g> மீதமுள்ளது"</string>
+    <string name="title_app_suggestions" msgid="4185902664111965088">"ஆப்ஸ் பரிந்துரைகள்"</string>
+    <string name="all_apps_label" msgid="8542784161730910663">"அனைத்து ஆப்ஸும்"</string>
+    <string name="all_apps_prediction_tip" msgid="2672336544844936186">"நீங்கள் கணித்த ஆப்ஸ்"</string>
 </resources>
diff --git a/quickstep/res/values-te/strings.xml b/quickstep/res/values-te/strings.xml
index 071755a..24b37f7 100644
--- a/quickstep/res/values-te/strings.xml
+++ b/quickstep/res/values-te/strings.xml
@@ -31,4 +31,7 @@
     <string name="task_contents_description_with_remaining_time" msgid="4479688746574672685">"<xliff:g id="TASK_DESCRIPTION">%1$s</xliff:g>, <xliff:g id="REMAINING_TIME">%2$s</xliff:g>"</string>
     <string name="shorter_duration_less_than_one_minute" msgid="4722015666335015336">"&lt; 1 నిమిషం"</string>
     <string name="time_left_for_app" msgid="3111996412933644358">"నేటికి <xliff:g id="TIME">%1$s</xliff:g> మిగిలి ఉంది"</string>
+    <string name="title_app_suggestions" msgid="4185902664111965088">"యాప్ సూచనలు"</string>
+    <string name="all_apps_label" msgid="8542784161730910663">"అన్ని యాప్‌లు"</string>
+    <string name="all_apps_prediction_tip" msgid="2672336544844936186">"మీ సూచించబడిన యాప్‌లు"</string>
 </resources>
diff --git a/quickstep/res/values-th/strings.xml b/quickstep/res/values-th/strings.xml
index c0e78ce..0f6821b 100644
--- a/quickstep/res/values-th/strings.xml
+++ b/quickstep/res/values-th/strings.xml
@@ -31,4 +31,7 @@
     <string name="task_contents_description_with_remaining_time" msgid="4479688746574672685">"<xliff:g id="TASK_DESCRIPTION">%1$s</xliff:g> <xliff:g id="REMAINING_TIME">%2$s</xliff:g>"</string>
     <string name="shorter_duration_less_than_one_minute" msgid="4722015666335015336">"&lt;1 นาที"</string>
     <string name="time_left_for_app" msgid="3111996412933644358">"วันนี้เหลืออีก <xliff:g id="TIME">%1$s</xliff:g>"</string>
+    <string name="title_app_suggestions" msgid="4185902664111965088">"คำแนะนำเกี่ยวกับแอป"</string>
+    <string name="all_apps_label" msgid="8542784161730910663">"แอปทั้งหมด"</string>
+    <string name="all_apps_prediction_tip" msgid="2672336544844936186">"แอปที่คาดการณ์ไว้"</string>
 </resources>
diff --git a/quickstep/res/values-tl/strings.xml b/quickstep/res/values-tl/strings.xml
index 76a0b25..491bac5 100644
--- a/quickstep/res/values-tl/strings.xml
+++ b/quickstep/res/values-tl/strings.xml
@@ -31,4 +31,7 @@
     <string name="task_contents_description_with_remaining_time" msgid="4479688746574672685">"<xliff:g id="TASK_DESCRIPTION">%1$s</xliff:g>, <xliff:g id="REMAINING_TIME">%2$s</xliff:g>"</string>
     <string name="shorter_duration_less_than_one_minute" msgid="4722015666335015336">"&lt; 1 min"</string>
     <string name="time_left_for_app" msgid="3111996412933644358">"<xliff:g id="TIME">%1$s</xliff:g> na lang ngayon"</string>
+    <string name="title_app_suggestions" msgid="4185902664111965088">"Mga iminumungkahing app"</string>
+    <string name="all_apps_label" msgid="8542784161730910663">"Lahat ng app"</string>
+    <string name="all_apps_prediction_tip" msgid="2672336544844936186">"Iyong mga nahulaang app"</string>
 </resources>
diff --git a/quickstep/res/values-tr/strings.xml b/quickstep/res/values-tr/strings.xml
index 8b59c7b..ec6d884 100644
--- a/quickstep/res/values-tr/strings.xml
+++ b/quickstep/res/values-tr/strings.xml
@@ -31,4 +31,7 @@
     <string name="task_contents_description_with_remaining_time" msgid="4479688746574672685">"<xliff:g id="TASK_DESCRIPTION">%1$s</xliff:g>, <xliff:g id="REMAINING_TIME">%2$s</xliff:g>"</string>
     <string name="shorter_duration_less_than_one_minute" msgid="4722015666335015336">"&lt; 1 dk."</string>
     <string name="time_left_for_app" msgid="3111996412933644358">"Bugün <xliff:g id="TIME">%1$s</xliff:g> kaldı"</string>
+    <string name="title_app_suggestions" msgid="4185902664111965088">"Uygulama önerileri"</string>
+    <string name="all_apps_label" msgid="8542784161730910663">"Tüm uygulamalar"</string>
+    <string name="all_apps_prediction_tip" msgid="2672336544844936186">"Tahmin edilen uygulamalarınız"</string>
 </resources>
diff --git a/quickstep/res/values-uk/strings.xml b/quickstep/res/values-uk/strings.xml
index 39c3848..7736062 100644
--- a/quickstep/res/values-uk/strings.xml
+++ b/quickstep/res/values-uk/strings.xml
@@ -31,4 +31,7 @@
     <string name="task_contents_description_with_remaining_time" msgid="4479688746574672685">"<xliff:g id="TASK_DESCRIPTION">%1$s</xliff:g>, <xliff:g id="REMAINING_TIME">%2$s</xliff:g>"</string>
     <string name="shorter_duration_less_than_one_minute" msgid="4722015666335015336">"&lt; 1 хв"</string>
     <string name="time_left_for_app" msgid="3111996412933644358">"Сьогодні залишилося <xliff:g id="TIME">%1$s</xliff:g>"</string>
+    <string name="title_app_suggestions" msgid="4185902664111965088">"Пропозиції додатків"</string>
+    <string name="all_apps_label" msgid="8542784161730910663">"Усі додатки"</string>
+    <string name="all_apps_prediction_tip" msgid="2672336544844936186">"Передбачені додатки"</string>
 </resources>
diff --git a/quickstep/res/values-ur/strings.xml b/quickstep/res/values-ur/strings.xml
index 4fd9e69..87b303f 100644
--- a/quickstep/res/values-ur/strings.xml
+++ b/quickstep/res/values-ur/strings.xml
@@ -31,4 +31,7 @@
     <string name="task_contents_description_with_remaining_time" msgid="4479688746574672685">"<xliff:g id="TASK_DESCRIPTION">%1$s</xliff:g>،<xliff:g id="REMAINING_TIME">%2$s</xliff:g>"</string>
     <string name="shorter_duration_less_than_one_minute" msgid="4722015666335015336">"‏&lt; 1 منٹ"</string>
     <string name="time_left_for_app" msgid="3111996412933644358">"آج <xliff:g id="TIME">%1$s</xliff:g> بچا ہے"</string>
+    <string name="title_app_suggestions" msgid="4185902664111965088">"ایپ کی تجاویز"</string>
+    <string name="all_apps_label" msgid="8542784161730910663">"تمام ایپس"</string>
+    <string name="all_apps_prediction_tip" msgid="2672336544844936186">"آپ کی پیشن گوئی کردہ ایپس"</string>
 </resources>
diff --git a/quickstep/res/values-uz/strings.xml b/quickstep/res/values-uz/strings.xml
index 466d79e..67c8e91 100644
--- a/quickstep/res/values-uz/strings.xml
+++ b/quickstep/res/values-uz/strings.xml
@@ -31,4 +31,7 @@
     <string name="task_contents_description_with_remaining_time" msgid="4479688746574672685">"<xliff:g id="TASK_DESCRIPTION">%1$s</xliff:g>, <xliff:g id="REMAINING_TIME">%2$s</xliff:g>"</string>
     <string name="shorter_duration_less_than_one_minute" msgid="4722015666335015336">"&lt; 1 daqiqa"</string>
     <string name="time_left_for_app" msgid="3111996412933644358">"Bugun <xliff:g id="TIME">%1$s</xliff:g> qoldi"</string>
+    <string name="title_app_suggestions" msgid="4185902664111965088">"Tavsiya etiladigan ilovalar"</string>
+    <string name="all_apps_label" msgid="8542784161730910663">"Barcha ilovalar"</string>
+    <string name="all_apps_prediction_tip" msgid="2672336544844936186">"Taklif qilingan ilovalaringiz"</string>
 </resources>
diff --git a/quickstep/res/values-vi/strings.xml b/quickstep/res/values-vi/strings.xml
index 842b22b..34c89ef 100644
--- a/quickstep/res/values-vi/strings.xml
+++ b/quickstep/res/values-vi/strings.xml
@@ -31,4 +31,7 @@
     <string name="task_contents_description_with_remaining_time" msgid="4479688746574672685">"<xliff:g id="TASK_DESCRIPTION">%1$s</xliff:g>, <xliff:g id="REMAINING_TIME">%2$s</xliff:g>"</string>
     <string name="shorter_duration_less_than_one_minute" msgid="4722015666335015336">"&lt; 1 phút"</string>
     <string name="time_left_for_app" msgid="3111996412933644358">"Hôm nay còn <xliff:g id="TIME">%1$s</xliff:g>"</string>
+    <string name="title_app_suggestions" msgid="4185902664111965088">"Các ứng dụng đề xuất"</string>
+    <string name="all_apps_label" msgid="8542784161730910663">"Tất cả ứng dụng"</string>
+    <string name="all_apps_prediction_tip" msgid="2672336544844936186">"Các ứng dụng gợi ý của bạn"</string>
 </resources>
diff --git a/quickstep/res/values-zh-rCN/strings.xml b/quickstep/res/values-zh-rCN/strings.xml
index 951489f..0e83977 100644
--- a/quickstep/res/values-zh-rCN/strings.xml
+++ b/quickstep/res/values-zh-rCN/strings.xml
@@ -31,4 +31,7 @@
     <string name="task_contents_description_with_remaining_time" msgid="4479688746574672685">"<xliff:g id="TASK_DESCRIPTION">%1$s</xliff:g>(<xliff:g id="REMAINING_TIME">%2$s</xliff:g>)"</string>
     <string name="shorter_duration_less_than_one_minute" msgid="4722015666335015336">"不到 1 分钟"</string>
     <string name="time_left_for_app" msgid="3111996412933644358">"今天还可使用 <xliff:g id="TIME">%1$s</xliff:g>"</string>
+    <string name="title_app_suggestions" msgid="4185902664111965088">"应用推荐"</string>
+    <string name="all_apps_label" msgid="8542784161730910663">"所有应用"</string>
+    <string name="all_apps_prediction_tip" msgid="2672336544844936186">"您的预测应用"</string>
 </resources>
diff --git a/quickstep/res/values-zh-rHK/strings.xml b/quickstep/res/values-zh-rHK/strings.xml
index 361623d..ac7e8e9 100644
--- a/quickstep/res/values-zh-rHK/strings.xml
+++ b/quickstep/res/values-zh-rHK/strings.xml
@@ -31,4 +31,7 @@
     <string name="task_contents_description_with_remaining_time" msgid="4479688746574672685">"<xliff:g id="TASK_DESCRIPTION">%1$s</xliff:g>,<xliff:g id="REMAINING_TIME">%2$s</xliff:g>"</string>
     <string name="shorter_duration_less_than_one_minute" msgid="4722015666335015336">"少於 1 分鐘"</string>
     <string name="time_left_for_app" msgid="3111996412933644358">"今天剩餘時間:<xliff:g id="TIME">%1$s</xliff:g>"</string>
+    <string name="title_app_suggestions" msgid="4185902664111965088">"應用程式建議"</string>
+    <string name="all_apps_label" msgid="8542784161730910663">"所有應用程式"</string>
+    <string name="all_apps_prediction_tip" msgid="2672336544844936186">"您的預測應用程式"</string>
 </resources>
diff --git a/quickstep/res/values-zh-rTW/strings.xml b/quickstep/res/values-zh-rTW/strings.xml
index 6938d3e..3323bfd 100644
--- a/quickstep/res/values-zh-rTW/strings.xml
+++ b/quickstep/res/values-zh-rTW/strings.xml
@@ -31,4 +31,7 @@
     <string name="task_contents_description_with_remaining_time" msgid="4479688746574672685">"<xliff:g id="TASK_DESCRIPTION">%1$s</xliff:g> (<xliff:g id="REMAINING_TIME">%2$s</xliff:g>)"</string>
     <string name="shorter_duration_less_than_one_minute" msgid="4722015666335015336">"&lt; 1 分鐘"</string>
     <string name="time_left_for_app" msgid="3111996412933644358">"今天還能使用 <xliff:g id="TIME">%1$s</xliff:g>"</string>
+    <string name="title_app_suggestions" msgid="4185902664111965088">"應用程式建議"</string>
+    <string name="all_apps_label" msgid="8542784161730910663">"所有應用程式"</string>
+    <string name="all_apps_prediction_tip" msgid="2672336544844936186">"系統預測你會使用的應用程式"</string>
 </resources>
diff --git a/quickstep/res/values-zu/strings.xml b/quickstep/res/values-zu/strings.xml
index 98f7b02..0f1d99d 100644
--- a/quickstep/res/values-zu/strings.xml
+++ b/quickstep/res/values-zu/strings.xml
@@ -31,4 +31,7 @@
     <string name="task_contents_description_with_remaining_time" msgid="4479688746574672685">"<xliff:g id="TASK_DESCRIPTION">%1$s</xliff:g>, <xliff:g id="REMAINING_TIME">%2$s</xliff:g>"</string>
     <string name="shorter_duration_less_than_one_minute" msgid="4722015666335015336">"&lt; 1 iminithi"</string>
     <string name="time_left_for_app" msgid="3111996412933644358">"<xliff:g id="TIME">%1$s</xliff:g> esele namhlanje"</string>
+    <string name="title_app_suggestions" msgid="4185902664111965088">"Iziphakamiso zohlelo lokusebenza"</string>
+    <string name="all_apps_label" msgid="8542784161730910663">"Zonke izinhlelo zokusebenza"</string>
+    <string name="all_apps_prediction_tip" msgid="2672336544844936186">"Izinhlelo zakho zokusebenza eziqagelwe"</string>
 </resources>
diff --git a/quickstep/res/values/dimens.xml b/quickstep/res/values/dimens.xml
index 32f312f..82d1aa6 100644
--- a/quickstep/res/values/dimens.xml
+++ b/quickstep/res/values/dimens.xml
@@ -36,6 +36,7 @@
 
     <!-- These speeds are in dp / ms -->
     <dimen name="motion_pause_detector_speed_very_slow">0.0285dp</dimen>
+    <dimen name="motion_pause_detector_speed_slow">0.15dp</dimen>
     <dimen name="motion_pause_detector_speed_somewhat_fast">0.285dp</dimen>
     <dimen name="motion_pause_detector_speed_fast">0.5dp</dimen>
     <dimen name="motion_pause_detector_min_displacement_from_app">36dp</dimen>
diff --git a/quickstep/src/com/android/launcher3/QuickstepAppTransitionManagerImpl.java b/quickstep/src/com/android/launcher3/QuickstepAppTransitionManagerImpl.java
index e1a115a..3b75304 100644
--- a/quickstep/src/com/android/launcher3/QuickstepAppTransitionManagerImpl.java
+++ b/quickstep/src/com/android/launcher3/QuickstepAppTransitionManagerImpl.java
@@ -132,7 +132,7 @@
     private final DragLayer mDragLayer;
     private final AlphaProperty mDragLayerAlpha;
 
-    private final Handler mHandler;
+    final Handler mHandler;
     private final boolean mIsRtl;
 
     private final float mContentTransY;
@@ -573,70 +573,9 @@
      * @return Runner that plays when user goes to Launcher
      *         ie. pressing home, swiping up from nav bar.
      */
-    private RemoteAnimationRunnerCompat getWallpaperOpenRunner(boolean fromUnlock) {
-        return new LauncherAnimationRunner(mHandler, false /* startAtFrontOfQueue */) {
-            @Override
-            public void onCreateAnimation(RemoteAnimationTargetCompat[] targetCompats,
-                    AnimationResult result) {
-                if (!mLauncher.hasBeenResumed()) {
-                    // If launcher is not resumed, wait until new async-frame after resume
-                    mLauncher.setOnResumeCallback(() ->
-                            postAsyncCallback(mHandler, () ->
-                                    onCreateAnimation(targetCompats, result)));
-                    return;
-                }
-
-                if (mLauncher.hasSomeInvisibleFlag(PENDING_INVISIBLE_BY_WALLPAPER_ANIMATION)) {
-                    mLauncher.addForceInvisibleFlag(INVISIBLE_BY_PENDING_FLAGS);
-                    mLauncher.getStateManager().moveToRestState();
-                }
-
-                AnimatorSet anim = null;
-                RemoteAnimationProvider provider = mRemoteAnimationProvider;
-                if (provider != null) {
-                    anim = provider.createWindowAnimation(targetCompats);
-                }
-
-                if (anim == null) {
-                    anim = new AnimatorSet();
-                    anim.play(fromUnlock
-                            ? getUnlockWindowAnimator(targetCompats)
-                            : getClosingWindowAnimators(targetCompats));
-
-                    // Normally, we run the launcher content animation when we are transitioning
-                    // home, but if home is already visible, then we don't want to animate the
-                    // contents of launcher unless we know that we are animating home as a result
-                    // of the home button press with quickstep, which will result in launcher being
-                    // started on touch down, prior to the animation home (and won't be in the
-                    // targets list because it is already visible). In that case, we force
-                    // invisibility on touch down, and only reset it after the animation to home
-                    // is initialized.
-                    if (launcherIsATargetWithMode(targetCompats, MODE_OPENING)
-                            || mLauncher.isForceInvisible()) {
-                        // Only register the content animation for cancellation when state changes
-                        mLauncher.getStateManager().setCurrentAnimation(anim);
-                        if (fromUnlock) {
-                            Pair<AnimatorSet, Runnable> contentAnimator =
-                                    getLauncherContentAnimator(false /* isAppOpening */,
-                                            new float[] {mContentTransY, 0});
-                            contentAnimator.first.setStartDelay(0);
-                            anim.play(contentAnimator.first);
-                            anim.addListener(new AnimatorListenerAdapter() {
-                                @Override
-                                public void onAnimationEnd(Animator animation) {
-                                    contentAnimator.second.run();
-                                }
-                            });
-                        } else {
-                            createLauncherResumeAnimation(anim);
-                        }
-                    }
-                }
-
-                mLauncher.clearForceInvisibleFlag(INVISIBLE_ALL);
-                result.setAnimation(anim);
-            }
-        };
+    RemoteAnimationRunnerCompat getWallpaperOpenRunner(boolean fromUnlock) {
+        return new WallpaperOpenLauncherAnimationRunner(mHandler, false /* startAtFrontOfQueue */,
+                fromUnlock);
     }
 
     /**
@@ -773,4 +712,79 @@
         return mLauncher.checkSelfPermission(CONTROL_REMOTE_APP_TRANSITION_PERMISSION)
                 == PackageManager.PERMISSION_GRANTED;
     }
+
+    /**
+     * Remote animation runner for animation from the app to Launcher, including recents.
+     */
+    class WallpaperOpenLauncherAnimationRunner extends LauncherAnimationRunner {
+        private final boolean mFromUnlock;
+
+        public WallpaperOpenLauncherAnimationRunner(Handler handler, boolean startAtFrontOfQueue,
+                boolean fromUnlock) {
+            super(handler, startAtFrontOfQueue);
+            mFromUnlock = fromUnlock;
+        }
+
+        @Override
+        public void onCreateAnimation(RemoteAnimationTargetCompat[] targetCompats,
+                LauncherAnimationRunner.AnimationResult result) {
+            if (!mLauncher.hasBeenResumed()) {
+                // If launcher is not resumed, wait until new async-frame after resume
+                mLauncher.setOnResumeCallback(() ->
+                        postAsyncCallback(mHandler, () ->
+                                onCreateAnimation(targetCompats, result)));
+                return;
+            }
+
+            if (mLauncher.hasSomeInvisibleFlag(PENDING_INVISIBLE_BY_WALLPAPER_ANIMATION)) {
+                mLauncher.addForceInvisibleFlag(INVISIBLE_BY_PENDING_FLAGS);
+                mLauncher.getStateManager().moveToRestState();
+            }
+
+            AnimatorSet anim = null;
+            RemoteAnimationProvider provider = mRemoteAnimationProvider;
+            if (provider != null) {
+                anim = provider.createWindowAnimation(targetCompats);
+            }
+
+            if (anim == null) {
+                anim = new AnimatorSet();
+                anim.play(mFromUnlock
+                        ? getUnlockWindowAnimator(targetCompats)
+                        : getClosingWindowAnimators(targetCompats));
+
+                // Normally, we run the launcher content animation when we are transitioning
+                // home, but if home is already visible, then we don't want to animate the
+                // contents of launcher unless we know that we are animating home as a result
+                // of the home button press with quickstep, which will result in launcher being
+                // started on touch down, prior to the animation home (and won't be in the
+                // targets list because it is already visible). In that case, we force
+                // invisibility on touch down, and only reset it after the animation to home
+                // is initialized.
+                if (launcherIsATargetWithMode(targetCompats, MODE_OPENING)
+                        || mLauncher.isForceInvisible()) {
+                    // Only register the content animation for cancellation when state changes
+                    mLauncher.getStateManager().setCurrentAnimation(anim);
+                    if (mFromUnlock) {
+                        Pair<AnimatorSet, Runnable> contentAnimator =
+                                getLauncherContentAnimator(false /* isAppOpening */,
+                                        new float[] {mContentTransY, 0});
+                        contentAnimator.first.setStartDelay(0);
+                        anim.play(contentAnimator.first);
+                        anim.addListener(new AnimatorListenerAdapter() {
+                            @Override
+                            public void onAnimationEnd(Animator animation) {
+                                contentAnimator.second.run();
+                            }
+                        });
+                    } else {
+                        createLauncherResumeAnimation(anim);
+                    }
+                }
+            }
+
+            mLauncher.clearForceInvisibleFlag(INVISIBLE_ALL);
+            result.setAnimation(anim);
+        }
+    }
 }
diff --git a/quickstep/src/com/android/quickstep/util/MotionPauseDetector.java b/quickstep/src/com/android/quickstep/util/MotionPauseDetector.java
index f58f0d4..893c053 100644
--- a/quickstep/src/com/android/quickstep/util/MotionPauseDetector.java
+++ b/quickstep/src/com/android/quickstep/util/MotionPauseDetector.java
@@ -35,10 +35,18 @@
     /** If no motion is added for this amount of time, assume the motion has paused. */
     private static final long FORCE_PAUSE_TIMEOUT = 300;
 
+    /**
+     * After {@link #makePauseHarderToTrigger()}, must
+     * move slowly for this long to trigger a pause.
+     */
+    private static final long HARDER_TRIGGER_TIMEOUT = 400;
+
     private final float mSpeedVerySlow;
+    private final float mSpeedSlow;
     private final float mSpeedSomewhatFast;
     private final float mSpeedFast;
     private final Alarm mForcePauseTimeout;
+    private final boolean mMakePauseHarderToTrigger;
 
     private Long mPreviousTime = null;
     private Float mPreviousPosition = null;
@@ -52,19 +60,29 @@
     private boolean mHasEverBeenPaused;
     /** @see #setDisallowPause(boolean) */
     private boolean mDisallowPause;
+    // Time at which speed became < mSpeedSlow (only used if mMakePauseHarderToTrigger == true).
+    private long mSlowStartTime;
 
     public MotionPauseDetector(Context context) {
+        this(context, false);
+    }
+
+    /**
+     * @param makePauseHarderToTrigger Used for gestures that require a more explicit pause.
+     */
+    public MotionPauseDetector(Context context, boolean makePauseHarderToTrigger) {
         Resources res = context.getResources();
         mSpeedVerySlow = res.getDimension(R.dimen.motion_pause_detector_speed_very_slow);
+        mSpeedSlow = res.getDimension(R.dimen.motion_pause_detector_speed_slow);
         mSpeedSomewhatFast = res.getDimension(R.dimen.motion_pause_detector_speed_somewhat_fast);
         mSpeedFast = res.getDimension(R.dimen.motion_pause_detector_speed_fast);
         mForcePauseTimeout = new Alarm();
         mForcePauseTimeout.setOnAlarmListener(alarm -> updatePaused(true /* isPaused */));
+        mMakePauseHarderToTrigger = makePauseHarderToTrigger;
     }
 
     /**
-     * Get callbacks for when motion pauses and resumes, including an
-     * immediate callback with the current pause state.
+     * Get callbacks for when motion pauses and resumes.
      */
     public void setOnMotionPauseListener(OnMotionPauseListener listener) {
         mOnMotionPauseListener = listener;
@@ -88,13 +106,15 @@
         if (mFirstPosition == null) {
             mFirstPosition = position;
         }
-        mForcePauseTimeout.setAlarm(FORCE_PAUSE_TIMEOUT);
+        mForcePauseTimeout.setAlarm(mMakePauseHarderToTrigger
+                ? HARDER_TRIGGER_TIMEOUT
+                : FORCE_PAUSE_TIMEOUT);
         if (mPreviousTime != null && mPreviousPosition != null) {
             long changeInTime = Math.max(1, time - mPreviousTime);
             float changeInPosition = position - mPreviousPosition;
             float velocity = changeInPosition / changeInTime;
             if (mPreviousVelocity != null) {
-                checkMotionPaused(velocity, mPreviousVelocity);
+                checkMotionPaused(velocity, mPreviousVelocity, time);
             }
             mPreviousVelocity = velocity;
         }
@@ -102,7 +122,7 @@
         mPreviousPosition = position;
     }
 
-    private void checkMotionPaused(float velocity, float prevVelocity) {
+    private void checkMotionPaused(float velocity, float prevVelocity, long time) {
         float speed = Math.abs(velocity);
         float previousSpeed = Math.abs(prevVelocity);
         boolean isPaused;
@@ -122,6 +142,17 @@
                     boolean isRapidDeceleration = speed < previousSpeed * RAPID_DECELERATION_FACTOR;
                     isPaused = isRapidDeceleration && speed < mSpeedSomewhatFast;
                 }
+                if (mMakePauseHarderToTrigger) {
+                    if (speed < mSpeedSlow) {
+                        if (mSlowStartTime == 0) {
+                            mSlowStartTime = time;
+                        }
+                        isPaused = time - mSlowStartTime >= HARDER_TRIGGER_TIMEOUT;
+                    } else {
+                        mSlowStartTime = 0;
+                        isPaused = false;
+                    }
+                }
             }
         }
         updatePaused(isPaused);
@@ -149,6 +180,7 @@
         mFirstPosition = null;
         setOnMotionPauseListener(null);
         mIsPaused = mHasEverBeenPaused = false;
+        mSlowStartTime = 0;
         mForcePauseTimeout.cancelAlarm();
     }
 
diff --git a/quickstep/tests/src/com/android/quickstep/StartLauncherViaGestureTests.java b/quickstep/tests/src/com/android/quickstep/StartLauncherViaGestureTests.java
index 8bdb90d..2111e2c 100644
--- a/quickstep/tests/src/com/android/quickstep/StartLauncherViaGestureTests.java
+++ b/quickstep/tests/src/com/android/quickstep/StartLauncherViaGestureTests.java
@@ -28,6 +28,7 @@
 import com.android.launcher3.util.RaceConditionReproducer;
 import com.android.quickstep.NavigationModeSwitchRule.Mode;
 import com.android.quickstep.NavigationModeSwitchRule.NavigationModeSwitch;
+import com.android.quickstep.inputconsumers.OtherActivityInputConsumer;
 
 import org.junit.Before;
 import org.junit.Ignore;
diff --git a/res/layout/launcher.xml b/res/layout/launcher.xml
index cca899b..9cab9c2 100644
--- a/res/layout/launcher.xml
+++ b/res/layout/launcher.xml
@@ -48,6 +48,11 @@
             layout="@layout/overview_panel"
             android:visibility="gone" />
 
+        <include
+            android:id="@+id/hints"
+            layout="@layout/proactive_hints_container"
+            android:visibility="gone"/>
+
         <!-- Keep these behind the workspace so that they are not visible when
          we go into AllApps -->
         <com.android.launcher3.pageindicators.WorkspacePageIndicator
diff --git a/res/layout/proactive_hints_container.xml b/res/layout/proactive_hints_container.xml
new file mode 100644
index 0000000..2637f03
--- /dev/null
+++ b/res/layout/proactive_hints_container.xml
@@ -0,0 +1,20 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+     Copyright (C) 2016 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.
+-->
+<Space
+    xmlns:android="http://schemas.android.com/apk/res/android"
+    android:layout_width="0dp"
+    android:layout_height="0dp" />
\ No newline at end of file
diff --git a/res/values/dimens.xml b/res/values/dimens.xml
index 469b176..0da56da 100644
--- a/res/values/dimens.xml
+++ b/res/values/dimens.xml
@@ -235,6 +235,7 @@
 <!-- Hints -->
     <dimen name="chip_hint_height">26dp</dimen>
     <dimen name="chip_hint_bottom_margin">194dp</dimen>
+    <dimen name="chip_hint_overhang">15dp</dimen>
 
 <!-- Theming related -->
     <dimen name="default_dialog_corner_radius">8dp</dimen>
diff --git a/src/com/android/launcher3/DeviceProfile.java b/src/com/android/launcher3/DeviceProfile.java
index 3d2d7cf..d098b8c 100644
--- a/src/com/android/launcher3/DeviceProfile.java
+++ b/src/com/android/launcher3/DeviceProfile.java
@@ -213,7 +213,7 @@
         // Add a bit of space between nav bar and hotseat in multi-window vertical bar layout.
         hotseatBarSidePaddingStartPx = isMultiWindowMode && isVerticalBarLayout()
                 ? edgeMarginPx : 0;
-        hotseatBarSizePx = Utilities.pxFromDp(inv.iconSize, dm) + (isVerticalBarLayout()
+        hotseatBarSizePx = ResourceUtils.pxFromDp(inv.iconSize, dm) + (isVerticalBarLayout()
                 ? (hotseatBarSidePaddingStartPx + hotseatBarSidePaddingEndPx)
                 : (res.getDimensionPixelSize(R.dimen.dynamic_grid_hotseat_extra_vertical_size)
                         + hotseatBarTopPaddingPx + hotseatBarBottomPaddingPx));
@@ -319,7 +319,7 @@
         // Workspace
         final boolean isVerticalLayout = isVerticalBarLayout();
         float invIconSizePx = isVerticalLayout ? inv.landscapeIconSize : inv.iconSize;
-        iconSizePx = Math.max(1, (int) (Utilities.pxFromDp(invIconSizePx, dm) * scale));
+        iconSizePx = Math.max(1, (int) (ResourceUtils.pxFromDp(invIconSizePx, dm) * scale));
         iconTextSizePx = (int) (Utilities.pxFromSp(inv.iconTextSize, dm) * scale);
         iconDrawablePaddingPx = (int) (iconDrawablePaddingOriginalPx * scale);
 
@@ -399,7 +399,7 @@
     }
 
     private void updateFolderCellSize(float scale, DisplayMetrics dm, Resources res) {
-        folderChildIconSizePx = (int) (Utilities.pxFromDp(inv.iconSize, dm) * scale);
+        folderChildIconSizePx = (int) (ResourceUtils.pxFromDp(inv.iconSize, dm) * scale);
         folderChildTextSizePx =
                 (int) (res.getDimensionPixelSize(R.dimen.folder_child_text_size) * scale);
 
diff --git a/src/com/android/launcher3/InvariantDeviceProfile.java b/src/com/android/launcher3/InvariantDeviceProfile.java
index 819a551..8a8a2fb 100644
--- a/src/com/android/launcher3/InvariantDeviceProfile.java
+++ b/src/com/android/launcher3/InvariantDeviceProfile.java
@@ -210,7 +210,7 @@
         iconSize = interpolatedDisplayOption.iconSize;
         iconShapePath = getIconShapePath(context);
         landscapeIconSize = interpolatedDisplayOption.landscapeIconSize;
-        iconBitmapSize = Utilities.pxFromDp(iconSize, dm);
+        iconBitmapSize = ResourceUtils.pxFromDp(iconSize, dm);
         iconTextSize = interpolatedDisplayOption.iconTextSize;
         fillResIconDpi = getLauncherIconDensity(iconBitmapSize);
 
diff --git a/src/com/android/launcher3/ResourceUtils.java b/src/com/android/launcher3/ResourceUtils.java
new file mode 100644
index 0000000..8df3290
--- /dev/null
+++ b/src/com/android/launcher3/ResourceUtils.java
@@ -0,0 +1,45 @@
+/*
+ * 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;
+
+import android.content.res.Resources;
+import android.util.DisplayMetrics;
+import android.util.TypedValue;
+
+public class ResourceUtils {
+    public static final String NAVBAR_VERTICAL_SIZE = "navigation_bar_frame_height";
+    public static final String NAVBAR_HORIZONTAL_SIZE = "navigation_bar_width";
+
+    public static int getNavbarSize(String resName, Resources res) {
+        return getDimenByName(resName, res, 48);
+    }
+
+    private static int getDimenByName(String resName, Resources res, int defaultValue) {
+        final int frameSize;
+        final int frameSizeResID = res.getIdentifier(resName, "dimen", "android");
+        if (frameSizeResID != 0) {
+            frameSize = res.getDimensionPixelSize(frameSizeResID);
+        } else {
+            frameSize = pxFromDp(defaultValue, res.getDisplayMetrics());
+        }
+        return frameSize;
+    }
+
+    public static int pxFromDp(float size, DisplayMetrics metrics) {
+        return Math.round(TypedValue.applyDimension(TypedValue.COMPLEX_UNIT_DIP, size, metrics));
+    }
+}
diff --git a/src/com/android/launcher3/Utilities.java b/src/com/android/launcher3/Utilities.java
index 35b967f..5cfd95c 100644
--- a/src/com/android/launcher3/Utilities.java
+++ b/src/com/android/launcher3/Utilities.java
@@ -477,10 +477,7 @@
         float densityRatio = (float) metrics.densityDpi / DisplayMetrics.DENSITY_DEFAULT;
         return (size / densityRatio);
     }
-    public static int pxFromDp(float size, DisplayMetrics metrics) {
-        return (int) Math.round(TypedValue.applyDimension(TypedValue.COMPLEX_UNIT_DIP,
-                size, metrics));
-    }
+
     public static int pxFromSp(float size, DisplayMetrics metrics) {
         return (int) Math.round(TypedValue.applyDimension(TypedValue.COMPLEX_UNIT_SP,
                 size, metrics));
diff --git a/src/com/android/launcher3/allapps/AllAppsContainerView.java b/src/com/android/launcher3/allapps/AllAppsContainerView.java
index e2a5160..41252aa 100644
--- a/src/com/android/launcher3/allapps/AllAppsContainerView.java
+++ b/src/com/android/launcher3/allapps/AllAppsContainerView.java
@@ -604,4 +604,18 @@
 
         return super.performAccessibilityAction(action, arguments);
     }
+
+    @Override
+    public boolean dispatchTouchEvent(MotionEvent ev) {
+        switch (ev.getActionMasked()) {
+            case MotionEvent.ACTION_DOWN:
+                mAllAppsStore.setDeferUpdates(true);
+                break;
+            case MotionEvent.ACTION_UP:
+            case MotionEvent.ACTION_CANCEL:
+                mAllAppsStore.setDeferUpdates(false);
+                break;
+        }
+        return super.dispatchTouchEvent(ev);
+    }
 }
diff --git a/src/com/android/launcher3/folder/FolderAnimationManager.java b/src/com/android/launcher3/folder/FolderAnimationManager.java
index 2450039..0e2ddd4 100644
--- a/src/com/android/launcher3/folder/FolderAnimationManager.java
+++ b/src/com/android/launcher3/folder/FolderAnimationManager.java
@@ -39,6 +39,7 @@
 import com.android.launcher3.CellLayout;
 import com.android.launcher3.Launcher;
 import com.android.launcher3.R;
+import com.android.launcher3.ResourceUtils;
 import com.android.launcher3.ShortcutAndWidgetContainer;
 import com.android.launcher3.Utilities;
 import com.android.launcher3.anim.PropertyResetListener;
@@ -165,7 +166,7 @@
                 Math.round((totalOffsetX + initialSize) / initialScale),
                 Math.round((paddingOffsetY + initialSize) / initialScale));
         Rect endRect = new Rect(0, 0, lp.width, lp.height);
-        float finalRadius = Utilities.pxFromDp(2, mContext.getResources().getDisplayMetrics());
+        float finalRadius = ResourceUtils.pxFromDp(2, mContext.getResources().getDisplayMetrics());
 
         // Create the animators.
         AnimatorSet a = new AnimatorSet();
diff --git a/src/com/android/launcher3/graphics/WorkspaceAndHotseatScrim.java b/src/com/android/launcher3/graphics/WorkspaceAndHotseatScrim.java
index 66f9dbf..c0aa75f 100644
--- a/src/com/android/launcher3/graphics/WorkspaceAndHotseatScrim.java
+++ b/src/com/android/launcher3/graphics/WorkspaceAndHotseatScrim.java
@@ -43,7 +43,7 @@
 import com.android.launcher3.CellLayout;
 import com.android.launcher3.Launcher;
 import com.android.launcher3.R;
-import com.android.launcher3.Utilities;
+import com.android.launcher3.ResourceUtils;
 import com.android.launcher3.Workspace;
 import com.android.launcher3.uioverrides.WallpaperColorInfo;
 import com.android.launcher3.util.Themes;
@@ -148,7 +148,7 @@
         mLauncher = Launcher.getLauncher(view.getContext());
         mWallpaperColorInfo = WallpaperColorInfo.getInstance(mLauncher);
 
-        mMaskHeight = Utilities.pxFromDp(ALPHA_MASK_BITMAP_DP,
+        mMaskHeight = ResourceUtils.pxFromDp(ALPHA_MASK_BITMAP_DP,
                 view.getResources().getDisplayMetrics());
         mTopScrim = Themes.getAttrDrawable(view.getContext(), R.attr.workspaceStatusBarScrim);
         mBottomMask = mTopScrim == null ? null : createDitheredAlphaMask();
@@ -297,8 +297,8 @@
 
     public Bitmap createDitheredAlphaMask() {
         DisplayMetrics dm = mLauncher.getResources().getDisplayMetrics();
-        int width = Utilities.pxFromDp(ALPHA_MASK_WIDTH_DP, dm);
-        int gradientHeight = Utilities.pxFromDp(ALPHA_MASK_HEIGHT_DP, dm);
+        int width = ResourceUtils.pxFromDp(ALPHA_MASK_WIDTH_DP, dm);
+        int gradientHeight = ResourceUtils.pxFromDp(ALPHA_MASK_HEIGHT_DP, dm);
         Bitmap dst = Bitmap.createBitmap(width, mMaskHeight, Bitmap.Config.ALPHA_8);
         Canvas c = new Canvas(dst);
         Paint paint = new Paint(Paint.DITHER_FLAG);
diff --git a/src/com/android/launcher3/provider/RestoreDbTask.java b/src/com/android/launcher3/provider/RestoreDbTask.java
index e6e20e1..053c493 100644
--- a/src/com/android/launcher3/provider/RestoreDbTask.java
+++ b/src/com/android/launcher3/provider/RestoreDbTask.java
@@ -201,7 +201,7 @@
      */
     private UserHandle getUserForAncestralSerialNumber(BackupManager backupManager,
             long ancestralSerialNumber) {
-        if (Build.VERSION.SDK_INT < 29) {
+        if (!Utilities.ATLEAST_Q) {
             return null;
         }
         return backupManager.getUserForAncestralSerialNumber(ancestralSerialNumber);
diff --git a/src/com/android/launcher3/widget/WidgetsBottomSheet.java b/src/com/android/launcher3/widget/WidgetsBottomSheet.java
index 3e2c0ae..a7078a2 100644
--- a/src/com/android/launcher3/widget/WidgetsBottomSheet.java
+++ b/src/com/android/launcher3/widget/WidgetsBottomSheet.java
@@ -36,7 +36,7 @@
 import com.android.launcher3.ItemInfo;
 import com.android.launcher3.LauncherAppState;
 import com.android.launcher3.R;
-import com.android.launcher3.Utilities;
+import com.android.launcher3.ResourceUtils;
 import com.android.launcher3.anim.Interpolators;
 import com.android.launcher3.model.WidgetItem;
 import com.android.launcher3.util.PackageUserKey;
@@ -126,7 +126,7 @@
             // Otherwise, add an empty view to the start as padding (but still scroll edge to edge).
             View leftPaddingView = LayoutInflater.from(getContext()).inflate(
                     R.layout.widget_list_divider, widgetRow, false);
-            leftPaddingView.getLayoutParams().width = Utilities.pxFromDp(
+            leftPaddingView.getLayoutParams().width = ResourceUtils.pxFromDp(
                     16, getResources().getDisplayMetrics());
             widgetCells.addView(leftPaddingView, 0);
         }
diff --git a/tests/Android.mk b/tests/Android.mk
index 080c98b..0991a04 100644
--- a/tests/Android.mk
+++ b/tests/Android.mk
@@ -30,6 +30,7 @@
     LOCAL_STATIC_JAVA_LIBRARIES += libSharedSystemUI
 
     LOCAL_SRC_FILES := $(call all-java-files-under, tapl) \
+        ../src/com/android/launcher3/ResourceUtils.java \
         ../src/com/android/launcher3/util/SecureSettingsObserver.java \
         ../src/com/android/launcher3/TestProtocol.java
 endif
diff --git a/tests/src/com/android/launcher3/ui/AbstractLauncherUiTest.java b/tests/src/com/android/launcher3/ui/AbstractLauncherUiTest.java
index 75db2f1..b6878bb 100644
--- a/tests/src/com/android/launcher3/ui/AbstractLauncherUiTest.java
+++ b/tests/src/com/android/launcher3/ui/AbstractLauncherUiTest.java
@@ -51,6 +51,7 @@
 import com.android.launcher3.LauncherSettings;
 import com.android.launcher3.LauncherState;
 import com.android.launcher3.MainThreadExecutor;
+import com.android.launcher3.ResourceUtils;
 import com.android.launcher3.Utilities;
 import com.android.launcher3.compat.LauncherAppsCompat;
 import com.android.launcher3.tapl.LauncherInstrumentation;
@@ -208,7 +209,9 @@
      * @return the matching object.
      */
     protected UiObject2 scrollAndFind(UiObject2 container, BySelector condition) {
-        container.setGestureMargins(0, 0, 0, 200);
+        final int margin = ResourceUtils.getNavbarSize(
+                ResourceUtils.NAVBAR_VERTICAL_SIZE, mLauncher.getResources()) + 1;
+        container.setGestureMargins(0, 0, 0, margin);
 
         int i = 0;
         for (; ; ) {
@@ -216,7 +219,8 @@
             mDevice.wait(Until.findObject(condition), SHORT_UI_TIMEOUT);
             UiObject2 widget = container.findObject(condition);
             if (widget != null && widget.getVisibleBounds().intersects(
-                    0, 0, mDevice.getDisplayWidth(), mDevice.getDisplayHeight() - 200)) {
+                    0, 0, mDevice.getDisplayWidth(),
+                    mDevice.getDisplayHeight() - margin)) {
                 return widget;
             }
             if (++i > 40) fail("Too many attempts");
diff --git a/tests/src/com/android/launcher3/ui/TaplTestsLauncher3.java b/tests/src/com/android/launcher3/ui/TaplTestsLauncher3.java
index 581e886..7578dff 100644
--- a/tests/src/com/android/launcher3/ui/TaplTestsLauncher3.java
+++ b/tests/src/com/android/launcher3/ui/TaplTestsLauncher3.java
@@ -24,7 +24,6 @@
 import static org.junit.Assert.assertNull;
 import static org.junit.Assert.assertTrue;
 
-import android.content.Intent;
 import android.util.Log;
 
 import androidx.test.filters.LargeTest;
@@ -241,9 +240,8 @@
     }
 
     public static void runIconLaunchFromAllAppsTest(AbstractLauncherUiTest test, AllApps allApps) {
-        final AppIcon app = allApps.getAppIcon("Calculator");
-        assertNotNull("AppIcon.launch returned null", app.launch(
-                test.resolveSystemApp(Intent.CATEGORY_APP_CALCULATOR)));
+        final AppIcon app = allApps.getAppIcon("TestActivity7");
+        assertNotNull("AppIcon.launch returned null", app.launch(getAppPackageName()));
         test.executeOnLauncher(launcher -> assertTrue(
                 "Launcher activity is the top activity; expecting another activity to be the top "
                         + "one",
diff --git a/tests/tapl/com/android/launcher3/tapl/AllApps.java b/tests/tapl/com/android/launcher3/tapl/AllApps.java
index 1ad0037..68bdfe3 100644
--- a/tests/tapl/com/android/launcher3/tapl/AllApps.java
+++ b/tests/tapl/com/android/launcher3/tapl/AllApps.java
@@ -23,6 +23,7 @@
 import androidx.test.uiautomator.Direction;
 import androidx.test.uiautomator.UiObject2;
 
+import com.android.launcher3.ResourceUtils;
 import com.android.launcher3.TestProtocol;
 
 /**
@@ -66,12 +67,9 @@
         try (LauncherInstrumentation.Closable c = mLauncher.addContextLayer(
                 "want to get app icon on all apps")) {
             final UiObject2 allAppsContainer = verifyActiveContainer();
-            if (mLauncher.getNavigationModel() != ZERO_BUTTON) {
-                final UiObject2 navBar = mLauncher.waitForSystemUiObject("navigation_bar_frame");
-                allAppsContainer.setGestureMargins(0, 0, 0, navBar.getVisibleBounds().height() + 1);
-            } else {
-                allAppsContainer.setGestureMargins(0, 0, 0, 200);
-            }
+            allAppsContainer.setGestureMargins(0, 0, 0,
+                    ResourceUtils.getNavbarSize(ResourceUtils.NAVBAR_VERTICAL_SIZE,
+                            mLauncher.getResources()) + 1);
             final BySelector appIconSelector = AppIcon.getAppIconSelector(appName, mLauncher);
             if (!hasClickableIcon(allAppsContainer, appIconSelector)) {
                 scrollBackToBeginning();
diff --git a/tests/tapl/com/android/launcher3/tapl/Background.java b/tests/tapl/com/android/launcher3/tapl/Background.java
index 3b2a7b8..60d2850 100644
--- a/tests/tapl/com/android/launcher3/tapl/Background.java
+++ b/tests/tapl/com/android/launcher3/tapl/Background.java
@@ -78,7 +78,8 @@
 
                 final long downTime = SystemClock.uptimeMillis();
                 mLauncher.sendPointer(downTime, downTime, MotionEvent.ACTION_DOWN, start);
-                mLauncher.movePointer(downTime, ZERO_BUTTON_SWIPE_UP_GESTURE_DURATION, start, end);
+                mLauncher.movePointer(
+                        downTime, downTime, ZERO_BUTTON_SWIPE_UP_GESTURE_DURATION, start, end);
                 LauncherInstrumentation.sleep(ZERO_BUTTON_SWIPE_UP_HOLD_DURATION);
                 mLauncher.sendPointer(
                         downTime, SystemClock.uptimeMillis(), MotionEvent.ACTION_UP, end);
diff --git a/tests/tapl/com/android/launcher3/tapl/LauncherInstrumentation.java b/tests/tapl/com/android/launcher3/tapl/LauncherInstrumentation.java
index 87ef044..4d8ff1b 100644
--- a/tests/tapl/com/android/launcher3/tapl/LauncherInstrumentation.java
+++ b/tests/tapl/com/android/launcher3/tapl/LauncherInstrumentation.java
@@ -70,6 +70,7 @@
 
     private static final String TAG = "Tapl";
     private static final int ZERO_BUTTON_STEPS_FROM_BACKGROUND_TO_HOME = 20;
+    private static final int GESTURE_STEP_MS = 16;
 
     // Types for launcher containers that the user is interacting with. "Background" is a
     // pseudo-container corresponding to inactive launcher covered by another app.
@@ -359,7 +360,7 @@
                         ? NORMAL_STATE_ORDINAL : BACKGROUND_APP_STATE_ORDINAL;
                 final Point displaySize = getRealDisplaySize();
 
-                swipe(
+                swipeViaMovePointer(
                         displaySize.x / 2, displaySize.y - 1,
                         displaySize.x / 2, 0,
                         finalState, ZERO_BUTTON_STEPS_FROM_BACKGROUND_TO_HOME);
@@ -543,8 +544,28 @@
     }
 
     void swipe(int startX, int startY, int endX, int endY, int expectedState, int steps) {
+        changeStateViaGesture(startX, startY, endX, endY, expectedState,
+                () -> mDevice.swipe(startX, startY, endX, endY, steps));
+    }
+
+    void swipeViaMovePointer(
+            int startX, int startY, int endX, int endY, int expectedState, int steps) {
+        changeStateViaGesture(startX, startY, endX, endY, expectedState, () -> {
+            final long downTime = SystemClock.uptimeMillis();
+            final Point start = new Point(startX, startY);
+            final Point end = new Point(endX, endY);
+            sendPointer(downTime, downTime, MotionEvent.ACTION_DOWN, start);
+            final long endTime = movePointer(downTime, downTime, steps * GESTURE_STEP_MS, start,
+                    end);
+            sendPointer(
+                    downTime, endTime, MotionEvent.ACTION_UP, end);
+        });
+    }
+
+    private void changeStateViaGesture(int startX, int startY, int endX, int endY,
+            int expectedState, Runnable gesture) {
         final Bundle parcel = (Bundle) executeAndWaitForEvent(
-                () -> mDevice.swipe(startX, startY, endX, endY, steps),
+                gesture,
                 event -> TestProtocol.SWITCHED_TO_STATE_MESSAGE.equals(event.getClassName()),
                 "Swipe failed to receive an event for the swipe end: " + startX + ", " + startY
                         + ", " + endX + ", " + endY);
@@ -565,6 +586,10 @@
         return ViewConfiguration.get(getContext()).getScaledTouchSlop();
     }
 
+    public Resources getResources() {
+        return getContext().getResources();
+    }
+
     private static MotionEvent getMotionEvent(long downTime, long eventTime, int action,
             float x, float y) {
         MotionEvent.PointerProperties properties = new MotionEvent.PointerProperties();
@@ -589,21 +614,22 @@
         event.recycle();
     }
 
-    void movePointer(long downTime, long duration, Point from, Point to) {
+    long movePointer(long downTime, long startTime, long duration, Point from, Point to) {
         final Point point = new Point();
-        final long startTime = SystemClock.uptimeMillis();
-        for (; ; ) {
-            sleep(16);
+        long steps = duration / GESTURE_STEP_MS;
+        long currentTime = startTime;
+        for (long i = 0; i < steps; ++i) {
+            sleep(GESTURE_STEP_MS);
 
-            final long currentTime = SystemClock.uptimeMillis();
+            currentTime += GESTURE_STEP_MS;
             final float progress = (currentTime - startTime) / (float) duration;
-            if (progress > 1) return;
 
             point.x = from.x + (int) (progress * (to.x - from.x));
             point.y = from.y + (int) (progress * (to.y - from.y));
 
             sendPointer(downTime, currentTime, MotionEvent.ACTION_MOVE, point);
         }
+        return currentTime;
     }
 
     public static boolean isGesturalMode(Context context) {
diff --git a/tests/tapl/com/android/launcher3/tapl/Widgets.java b/tests/tapl/com/android/launcher3/tapl/Widgets.java
index 100a11c..f7e0b6c 100644
--- a/tests/tapl/com/android/launcher3/tapl/Widgets.java
+++ b/tests/tapl/com/android/launcher3/tapl/Widgets.java
@@ -19,6 +19,8 @@
 import androidx.test.uiautomator.Direction;
 import androidx.test.uiautomator.UiObject2;
 
+import com.android.launcher3.ResourceUtils;
+
 /**
  * All widgets container.
  */
@@ -38,7 +40,9 @@
                 "want to fling forward in widgets")) {
             LauncherInstrumentation.log("Widgets.flingForward enter");
             final UiObject2 widgetsContainer = verifyActiveContainer();
-            widgetsContainer.setGestureMargins(0, 0, 0, 200);
+            widgetsContainer.setGestureMargins(0, 0, 0,
+                    ResourceUtils.getNavbarSize(ResourceUtils.NAVBAR_VERTICAL_SIZE,
+                            mLauncher.getResources()) + 1);
             widgetsContainer.fling(Direction.DOWN,
                     (int) (FLING_SPEED * mLauncher.getDisplayDensity()));
             try (LauncherInstrumentation.Closable c1 = mLauncher.addContextLayer("flung forward")) {
diff --git a/tests/tapl/com/android/launcher3/tapl/Workspace.java b/tests/tapl/com/android/launcher3/tapl/Workspace.java
index 9a47aef..e8a0b54 100644
--- a/tests/tapl/com/android/launcher3/tapl/Workspace.java
+++ b/tests/tapl/com/android/launcher3/tapl/Workspace.java
@@ -150,7 +150,8 @@
         LauncherInstrumentation.log("dragIconToWorkspace: sent down");
         launcher.waitForLauncherObject(longPressIndicator);
         LauncherInstrumentation.log("dragIconToWorkspace: indicator");
-        launcher.movePointer(downTime, DRAG_DURACTION, launchableCenter, dest);
+        launcher.movePointer(
+                downTime, SystemClock.uptimeMillis(), DRAG_DURACTION, launchableCenter, dest);
         LauncherInstrumentation.log("dragIconToWorkspace: moved pointer");
         launcher.sendPointer(
                 downTime, SystemClock.uptimeMillis(), MotionEvent.ACTION_UP, dest);