summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--go/quickstep/src/com/android/quickstep/AppToOverviewAnimationProvider.java142
-rw-r--r--go/quickstep/src/com/android/quickstep/ContentFillItemAnimator.java54
-rw-r--r--go/quickstep/src/com/android/quickstep/FallbackActivityControllerHelper.java1
-rw-r--r--go/quickstep/src/com/android/quickstep/LauncherActivityControllerHelper.java2
-rw-r--r--go/quickstep/src/com/android/quickstep/OverviewCommandHelper.java60
-rw-r--r--go/quickstep/src/com/android/quickstep/RecentsActivity.java4
-rw-r--r--go/quickstep/src/com/android/quickstep/views/IconRecentsView.java343
-rw-r--r--go/quickstep/src/com/android/quickstep/views/TaskItemView.java8
-rw-r--r--protos/launcher_log.proto1
-rw-r--r--quickstep/recents_ui_overrides/res/layout/proactive_hints_container.xml7
-rw-r--r--quickstep/recents_ui_overrides/src/com/android/launcher3/appprediction/PredictionAppTracker.java16
-rw-r--r--quickstep/recents_ui_overrides/src/com/android/launcher3/uioverrides/RecentsViewStateController.java18
-rw-r--r--quickstep/recents_ui_overrides/src/com/android/quickstep/RecentsAnimationWrapper.java1
-rw-r--r--quickstep/recents_ui_overrides/src/com/android/quickstep/TaskSystemShortcut.java4
-rw-r--r--quickstep/recents_ui_overrides/src/com/android/quickstep/TouchInteractionService.java13
-rw-r--r--quickstep/recents_ui_overrides/src/com/android/quickstep/WindowTransformSwipeHandler.java27
-rw-r--r--quickstep/recents_ui_overrides/src/com/android/quickstep/hints/ProactiveHintsContainer.java55
-rw-r--r--quickstep/recents_ui_overrides/src/com/android/quickstep/inputconsumers/AccessibilityInputConsumer.java (renamed from quickstep/recents_ui_overrides/src/com/android/quickstep/AccessibilityInputConsumer.java)2
-rw-r--r--quickstep/recents_ui_overrides/src/com/android/quickstep/inputconsumers/AssistantTouchConsumer.java (renamed from quickstep/recents_ui_overrides/src/com/android/quickstep/AssistantTouchConsumer.java)5
-rw-r--r--quickstep/recents_ui_overrides/src/com/android/quickstep/inputconsumers/DelegateInputConsumer.java (renamed from quickstep/recents_ui_overrides/src/com/android/quickstep/DelegateInputConsumer.java)2
-rw-r--r--quickstep/recents_ui_overrides/src/com/android/quickstep/inputconsumers/DeviceLockedInputConsumer.java (renamed from quickstep/recents_ui_overrides/src/com/android/quickstep/DeviceLockedInputConsumer.java)2
-rw-r--r--quickstep/recents_ui_overrides/src/com/android/quickstep/inputconsumers/InputConsumer.java (renamed from quickstep/recents_ui_overrides/src/com/android/quickstep/InputConsumer.java)3
-rw-r--r--quickstep/recents_ui_overrides/src/com/android/quickstep/inputconsumers/OtherActivityInputConsumer.java (renamed from quickstep/recents_ui_overrides/src/com/android/quickstep/OtherActivityInputConsumer.java)10
-rw-r--r--quickstep/recents_ui_overrides/src/com/android/quickstep/inputconsumers/OverviewInputConsumer.java (renamed from quickstep/recents_ui_overrides/src/com/android/quickstep/OverviewInputConsumer.java)4
-rw-r--r--quickstep/recents_ui_overrides/src/com/android/quickstep/inputconsumers/ScreenPinnedInputConsumer.java88
-rw-r--r--quickstep/recents_ui_overrides/src/com/android/quickstep/util/RectFSpringAnim.java5
-rw-r--r--quickstep/recents_ui_overrides/src/com/android/quickstep/views/LauncherRecentsView.java64
-rw-r--r--quickstep/res/values-af/strings.xml3
-rw-r--r--quickstep/res/values-am/strings.xml3
-rw-r--r--quickstep/res/values-ar/strings.xml3
-rw-r--r--quickstep/res/values-az/strings.xml3
-rw-r--r--quickstep/res/values-b+sr+Latn/strings.xml3
-rw-r--r--quickstep/res/values-be/strings.xml3
-rw-r--r--quickstep/res/values-bg/strings.xml3
-rw-r--r--quickstep/res/values-bn/strings.xml3
-rw-r--r--quickstep/res/values-bs/strings.xml3
-rw-r--r--quickstep/res/values-ca/strings.xml3
-rw-r--r--quickstep/res/values-cs/strings.xml3
-rw-r--r--quickstep/res/values-da/strings.xml3
-rw-r--r--quickstep/res/values-de/strings.xml3
-rw-r--r--quickstep/res/values-el/strings.xml3
-rw-r--r--quickstep/res/values-en-rAU/strings.xml3
-rw-r--r--quickstep/res/values-en-rGB/strings.xml3
-rw-r--r--quickstep/res/values-en-rIN/strings.xml3
-rw-r--r--quickstep/res/values-es-rUS/strings.xml3
-rw-r--r--quickstep/res/values-es/strings.xml3
-rw-r--r--quickstep/res/values-et/strings.xml3
-rw-r--r--quickstep/res/values-eu/strings.xml3
-rw-r--r--quickstep/res/values-fa/strings.xml3
-rw-r--r--quickstep/res/values-fi/strings.xml3
-rw-r--r--quickstep/res/values-fr-rCA/strings.xml3
-rw-r--r--quickstep/res/values-fr/strings.xml3
-rw-r--r--quickstep/res/values-gl/strings.xml3
-rw-r--r--quickstep/res/values-gu/strings.xml3
-rw-r--r--quickstep/res/values-hi/strings.xml3
-rw-r--r--quickstep/res/values-hr/strings.xml3
-rw-r--r--quickstep/res/values-hu/strings.xml3
-rw-r--r--quickstep/res/values-hy/strings.xml3
-rw-r--r--quickstep/res/values-in/strings.xml3
-rw-r--r--quickstep/res/values-is/strings.xml3
-rw-r--r--quickstep/res/values-it/strings.xml3
-rw-r--r--quickstep/res/values-iw/strings.xml3
-rw-r--r--quickstep/res/values-ja/strings.xml3
-rw-r--r--quickstep/res/values-ka/strings.xml3
-rw-r--r--quickstep/res/values-kk/strings.xml3
-rw-r--r--quickstep/res/values-km/strings.xml3
-rw-r--r--quickstep/res/values-kn/strings.xml3
-rw-r--r--quickstep/res/values-ko/strings.xml3
-rw-r--r--quickstep/res/values-ky/strings.xml3
-rw-r--r--quickstep/res/values-lo/strings.xml3
-rw-r--r--quickstep/res/values-lt/strings.xml3
-rw-r--r--quickstep/res/values-lv/strings.xml3
-rw-r--r--quickstep/res/values-mk/strings.xml3
-rw-r--r--quickstep/res/values-ml/strings.xml3
-rw-r--r--quickstep/res/values-mn/strings.xml3
-rw-r--r--quickstep/res/values-mr/strings.xml3
-rw-r--r--quickstep/res/values-ms/strings.xml3
-rw-r--r--quickstep/res/values-my/strings.xml3
-rw-r--r--quickstep/res/values-nb/strings.xml3
-rw-r--r--quickstep/res/values-ne/strings.xml3
-rw-r--r--quickstep/res/values-nl/strings.xml3
-rw-r--r--quickstep/res/values-pa/strings.xml3
-rw-r--r--quickstep/res/values-pl/strings.xml3
-rw-r--r--quickstep/res/values-pt-rPT/strings.xml3
-rw-r--r--quickstep/res/values-pt/strings.xml3
-rw-r--r--quickstep/res/values-ro/strings.xml3
-rw-r--r--quickstep/res/values-ru/strings.xml3
-rw-r--r--quickstep/res/values-si/strings.xml3
-rw-r--r--quickstep/res/values-sk/strings.xml3
-rw-r--r--quickstep/res/values-sl/strings.xml3
-rw-r--r--quickstep/res/values-sq/strings.xml3
-rw-r--r--quickstep/res/values-sr/strings.xml3
-rw-r--r--quickstep/res/values-sv/strings.xml3
-rw-r--r--quickstep/res/values-sw/strings.xml3
-rw-r--r--quickstep/res/values-ta/strings.xml3
-rw-r--r--quickstep/res/values-te/strings.xml3
-rw-r--r--quickstep/res/values-th/strings.xml3
-rw-r--r--quickstep/res/values-tl/strings.xml3
-rw-r--r--quickstep/res/values-tr/strings.xml3
-rw-r--r--quickstep/res/values-uk/strings.xml3
-rw-r--r--quickstep/res/values-ur/strings.xml3
-rw-r--r--quickstep/res/values-uz/strings.xml3
-rw-r--r--quickstep/res/values-vi/strings.xml3
-rw-r--r--quickstep/res/values-zh-rCN/strings.xml3
-rw-r--r--quickstep/res/values-zh-rHK/strings.xml3
-rw-r--r--quickstep/res/values-zh-rTW/strings.xml3
-rw-r--r--quickstep/res/values-zu/strings.xml3
-rw-r--r--quickstep/res/values/dimens.xml1
-rw-r--r--quickstep/src/com/android/launcher3/QuickstepAppTransitionManagerImpl.java23
-rw-r--r--quickstep/src/com/android/quickstep/util/MotionPauseDetector.java42
-rw-r--r--quickstep/tests/src/com/android/quickstep/AppPredictionsUITests.java8
-rw-r--r--quickstep/tests/src/com/android/quickstep/StartLauncherViaGestureTests.java1
-rw-r--r--res/layout/launcher.xml5
-rw-r--r--res/layout/proactive_hints_container.xml20
-rw-r--r--res/values/dimens.xml1
-rw-r--r--src/com/android/launcher3/allapps/AllAppsContainerView.java14
-rw-r--r--src/com/android/launcher3/anim/FlingSpringAnim.java4
-rw-r--r--src/com/android/launcher3/logging/LoggerUtils.java4
-rw-r--r--src/com/android/launcher3/views/FloatingIconView.java68
-rw-r--r--tests/tapl/com/android/launcher3/tapl/Background.java6
-rw-r--r--tests/tapl/com/android/launcher3/tapl/BaseOverview.java1
-rw-r--r--tests/tapl/com/android/launcher3/tapl/LauncherInstrumentation.java41
-rw-r--r--tests/tapl/com/android/launcher3/tapl/Workspace.java4
123 files changed, 1141 insertions, 283 deletions
diff --git a/go/quickstep/src/com/android/quickstep/AppToOverviewAnimationProvider.java b/go/quickstep/src/com/android/quickstep/AppToOverviewAnimationProvider.java
index c228bb94f..fe10a7a21 100644
--- a/go/quickstep/src/com/android/quickstep/AppToOverviewAnimationProvider.java
+++ b/go/quickstep/src/com/android/quickstep/AppToOverviewAnimationProvider.java
@@ -15,30 +15,21 @@
*/
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.ACTIVITY_TYPE_HOME;
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,14 +38,12 @@ import com.android.systemui.shared.system.SyncRtSurfaceTransactionApplierCompat.
*/
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;
private final int mTargetTaskId;
private IconRecentsView mRecentsView;
+ private AppToOverviewAnimationListener mAnimationReadyListener;
AppToOverviewAnimationProvider(ActivityControlHelper<T> helper, int targetTaskId) {
mHelper = helper;
@@ -62,12 +51,24 @@ final class AppToOverviewAnimationProvider<T extends BaseDraggingActivity> imple
}
/**
+ * Set listener to various points in the animation preparing to animate.
+ *
+ * @param listener listener
+ */
+ void setAnimationListener(AppToOverviewAnimationListener listener) {
+ mAnimationReadyListener = listener;
+ }
+
+ /**
* Callback for when the activity is ready/initialized.
*
* @param activity the activity that is ready
* @param wasVisible true if it was visible before
*/
boolean onActivityReady(T activity, Boolean wasVisible) {
+ if (mAnimationReadyListener != null) {
+ mAnimationReadyListener.onActivityReady(activity);
+ }
ActivityControlHelper.AnimationFactory factory =
mHelper.prepareRecentsUI(activity, wasVisible,
false /* animate activity */, (controller) -> {
@@ -92,6 +93,9 @@ final class AppToOverviewAnimationProvider<T extends BaseDraggingActivity> imple
*/
@Override
public AnimatorSet createWindowAnimation(RemoteAnimationTargetCompat[] targetCompats) {
+ if (mAnimationReadyListener != null) {
+ mAnimationReadyListener.onWindowAnimationCreated();
+ }
AnimatorSet anim = new AnimatorSet();
if (mRecentsView == null) {
if (Log.isLoggable(TAG, Log.WARN)) {
@@ -131,106 +135,38 @@ final class AppToOverviewAnimationProvider<T extends BaseDraggingActivity> imple
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;
+ if (closingAppTarget.activityType == ACTIVITY_TYPE_HOME) {
+ mRecentsView.playRemoteHomeToRecentsAnimation(anim, closingAppTarget, recentsTarget);
+ } else {
+ mRecentsView.playRemoteAppToRecentsAnimation(anim, closingAppTarget, recentsTarget);
}
- playAppScaleDownAnim(anim, closingAppTarget, recentsTarget, thumbnailView);
-
return anim;
}
/**
- * Animate a closing app to scale down to the location of the thumbnail view in recents.
+ * Get duration of animation from app to overview.
*
- * @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
+ * @return duration of animation
*/
- 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);
+ long getRecentsLaunchDuration() {
+ return REMOTE_APP_TO_OVERVIEW_DURATION;
}
/**
- * Get duration of animation from app to overview.
- *
- * @return duration of animation
+ * Listener for various points in the app to overview animation preparing to animate.
*/
- long getRecentsLaunchDuration() {
- return APP_SCALE_DOWN_DURATION;
+ interface AppToOverviewAnimationListener {
+ /**
+ * Logic for when activity we're animating to is ready
+ *
+ * @param activity activity to animate to
+ */
+ void onActivityReady(BaseDraggingActivity activity);
+
+ /**
+ * Logic for when we've created the app to recents animation.
+ */
+ void onWindowAnimationCreated();
}
}
diff --git a/go/quickstep/src/com/android/quickstep/ContentFillItemAnimator.java b/go/quickstep/src/com/android/quickstep/ContentFillItemAnimator.java
index 87ae6955e..808cd7217 100644
--- a/go/quickstep/src/com/android/quickstep/ContentFillItemAnimator.java
+++ b/go/quickstep/src/com/android/quickstep/ContentFillItemAnimator.java
@@ -180,6 +180,7 @@ public final class ContentFillItemAnimator extends SimpleItemAnimator {
@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 @@ public final class ContentFillItemAnimator extends SimpleItemAnimator {
@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 = 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();
+ }
+ 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;
}
- dispatchAnimationsFinished();
}
@Override
diff --git a/go/quickstep/src/com/android/quickstep/FallbackActivityControllerHelper.java b/go/quickstep/src/com/android/quickstep/FallbackActivityControllerHelper.java
index bba08a40a..eb0c5b942 100644
--- a/go/quickstep/src/com/android/quickstep/FallbackActivityControllerHelper.java
+++ b/go/quickstep/src/com/android/quickstep/FallbackActivityControllerHelper.java
@@ -50,6 +50,7 @@ public final class FallbackActivityControllerHelper extends
}
IconRecentsView rv = activity.getOverviewPanel();
+ rv.setUsingRemoteAnimation(true);
rv.setAlpha(0);
return new AnimationFactory() {
diff --git a/go/quickstep/src/com/android/quickstep/LauncherActivityControllerHelper.java b/go/quickstep/src/com/android/quickstep/LauncherActivityControllerHelper.java
index 40db7ddbc..d5950077d 100644
--- a/go/quickstep/src/com/android/quickstep/LauncherActivityControllerHelper.java
+++ b/go/quickstep/src/com/android/quickstep/LauncherActivityControllerHelper.java
@@ -40,6 +40,7 @@ public final class LauncherActivityControllerHelper extends GoActivityControlHel
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 @@ public final class LauncherActivityControllerHelper extends GoActivityControlHel
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/OverviewCommandHelper.java b/go/quickstep/src/com/android/quickstep/OverviewCommandHelper.java
index 379cc100e..0fa3d866f 100644
--- a/go/quickstep/src/com/android/quickstep/OverviewCommandHelper.java
+++ b/go/quickstep/src/com/android/quickstep/OverviewCommandHelper.java
@@ -18,7 +18,6 @@ package com.android.quickstep;
import static com.android.systemui.shared.system.ActivityManagerWrapper
.CLOSE_SYSTEM_WINDOWS_REASON_RECENTS;
-import android.animation.AnimatorSet;
import android.annotation.TargetApi;
import android.content.Context;
import android.os.Build;
@@ -30,10 +29,10 @@ import com.android.launcher3.MainThreadExecutor;
import com.android.launcher3.logging.UserEventDispatcher;
import com.android.launcher3.userevent.nano.LauncherLogProto;
import com.android.quickstep.ActivityControlHelper.ActivityInitListener;
+import com.android.quickstep.AppToOverviewAnimationProvider.AppToOverviewAnimationListener;
import com.android.quickstep.views.IconRecentsView;
import com.android.systemui.shared.system.ActivityManagerWrapper;
import com.android.systemui.shared.system.LatencyTrackerCompat;
-import com.android.systemui.shared.system.RemoteAnimationTargetCompat;
/**
* Helper class to handle various atomic commands for switching between Overview.
@@ -105,7 +104,6 @@ public class OverviewCommandHelper {
protected final ActivityControlHelper<T> mHelper;
private final long mCreateTime;
- private final AppToOverviewAnimationProvider<T> mAnimationProvider;
private final long mToggleClickedTime = SystemClock.uptimeMillis();
private boolean mUserEventLogged;
@@ -114,8 +112,6 @@ public class OverviewCommandHelper {
public RecentsActivityCommand() {
mHelper = mOverviewComponentObserver.getActivityControlHelper();
mCreateTime = SystemClock.elapsedRealtime();
- mAnimationProvider =
- new AppToOverviewAnimationProvider<>(mHelper, RecentsModel.getRunningTaskId());
// Preload the plan
mRecentsModel.getTasks(null);
@@ -136,11 +132,37 @@ public class OverviewCommandHelper {
return;
}
+ AppToOverviewAnimationProvider<T> provider =
+ new AppToOverviewAnimationProvider<>(mHelper, RecentsModel.getRunningTaskId());
+ provider.setAnimationListener(
+ new AppToOverviewAnimationListener() {
+ @Override
+ public void onActivityReady(BaseDraggingActivity activity) {
+ if (!mUserEventLogged) {
+ activity.getUserEventDispatcher().logActionCommand(
+ LauncherLogProto.Action.Command.RECENTS_BUTTON,
+ mHelper.getContainerType(),
+ LauncherLogProto.ContainerType.TASKSWITCHER);
+ mUserEventLogged = true;
+ }
+ }
+
+ @Override
+ public void onWindowAnimationCreated() {
+ if (LatencyTrackerCompat.isEnabled(mContext)) {
+ LatencyTrackerCompat.logToggleRecents(
+ (int) (SystemClock.uptimeMillis() - mToggleClickedTime));
+ }
+
+ mListener.unregister();
+ }
+ });
+
// Otherwise, start overview.
- mListener = mHelper.createActivityInitListener(this::onActivityReady);
+ mListener = mHelper.createActivityInitListener(provider::onActivityReady);
mListener.registerAndStartActivity(mOverviewComponentObserver.getOverviewIntent(),
- this::createWindowAnimation, mContext, mMainThreadExecutor.getHandler(),
- mAnimationProvider.getRecentsLaunchDuration());
+ provider, mContext, mMainThreadExecutor.getHandler(),
+ provider.getRecentsLaunchDuration());
}
protected boolean handleCommand(long elapsedTime) {
@@ -155,27 +177,5 @@ public class OverviewCommandHelper {
}
return false;
}
-
- private boolean onActivityReady(T activity, Boolean wasVisible) {
- if (!mUserEventLogged) {
- activity.getUserEventDispatcher().logActionCommand(
- LauncherLogProto.Action.Command.RECENTS_BUTTON,
- mHelper.getContainerType(),
- LauncherLogProto.ContainerType.TASKSWITCHER);
- mUserEventLogged = true;
- }
- return mAnimationProvider.onActivityReady(activity, wasVisible);
- }
-
- private AnimatorSet createWindowAnimation(RemoteAnimationTargetCompat[] targetCompats) {
- if (LatencyTrackerCompat.isEnabled(mContext)) {
- LatencyTrackerCompat.logToggleRecents(
- (int) (SystemClock.uptimeMillis() - mToggleClickedTime));
- }
-
- mListener.unregister();
-
- return mAnimationProvider.createWindowAnimation(targetCompats);
- }
}
}
diff --git a/go/quickstep/src/com/android/quickstep/RecentsActivity.java b/go/quickstep/src/com/android/quickstep/RecentsActivity.java
index 078f3a5ff..7f813ce2a 100644
--- a/go/quickstep/src/com/android/quickstep/RecentsActivity.java
+++ b/go/quickstep/src/com/android/quickstep/RecentsActivity.java
@@ -67,8 +67,8 @@ public final class RecentsActivity extends BaseRecentsActivity {
}
@Override
- protected void onStart() {
+ protected void onResume() {
mIconRecentsView.onBeginTransitionToOverview();
- super.onStart();
+ super.onResume();
}
}
diff --git a/go/quickstep/src/com/android/quickstep/views/IconRecentsView.java b/go/quickstep/src/com/android/quickstep/views/IconRecentsView.java
index 79e0bbed1..7f9f5975b 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 android.content.res.Configuration.ORIENTATION_LANDSCAPE;
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.PropertyValuesHolder;
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.util.FloatProperty;
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.TaskAdapter;
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 @@ public final class IconRecentsView extends FrameLayout implements Insettable {
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,9 @@ public final class IconRecentsView extends FrameLayout implements Insettable {
private View mEmptyView;
private View mContentView;
private boolean mTransitionedFromApp;
+ private boolean mUsingRemoteAnimation;
+ private boolean mStartedEnterAnimation;
+ private boolean mShowStatusBarForegroundScrim;
private AnimatorSet mLayoutAnimation;
private final ArraySet<View> mLayingOutViews = new ArraySet<>();
private Rect mInsets;
@@ -271,13 +301,16 @@ public final class IconRecentsView extends FrameLayout implements Insettable {
* becomes visible.
*/
public void onBeginTransitionToOverview() {
+ mStartedEnterAnimation = false;
if (mContext.getResources().getConfiguration().orientation == ORIENTATION_LANDSCAPE) {
// Scroll to bottom of task in landscape mode. This is a non-issue in portrait mode as
// all tasks should be visible to fill up the screen in portrait mode and the view will
// not be scrollable.
mTaskLayoutManager.scrollToPositionWithOffset(TASKS_START_POSITION, 0 /* offset */);
}
- scheduleFadeInLayoutAnimation();
+ if (!mUsingRemoteAnimation) {
+ scheduleFadeInLayoutAnimation();
+ }
// Load any task changes
if (!mTaskLoader.needsToLoad()) {
return;
@@ -293,16 +326,22 @@ public final class IconRecentsView extends FrameLayout implements Insettable {
+ "of items to animate to.");
}
// Possible that task list loads faster than adapter changes propagate to layout so
- // only start content fill animation if there aren't any pending adapter changes.
- if (!mTaskRecyclerView.hasPendingAdapterUpdates()) {
+ // only start content fill animation if there aren't any pending adapter changes and
+ // we've started the on enter layout animation.
+ boolean needsContentFillAnimation =
+ !mTaskRecyclerView.hasPendingAdapterUpdates() && mStartedEnterAnimation;
+ if (needsContentFillAnimation) {
// Set item animator for content filling animation. The item animator will switch
// back to the default on completion
mTaskRecyclerView.setItemAnimator(mLoadingContentItemAnimator);
+ mTaskAdapter.notifyItemRangeRemoved(TASKS_START_POSITION + numActualItems,
+ numEmptyItems - numActualItems);
+ mTaskAdapter.notifyItemRangeChanged(TASKS_START_POSITION, numActualItems,
+ CHANGE_EVENT_TYPE_EMPTY_TO_CONTENT);
+ } else {
+ // Notify change without animating.
+ mTaskAdapter.notifyDataSetChanged();
}
- mTaskAdapter.notifyItemRangeRemoved(TASKS_START_POSITION + numActualItems,
- numEmptyItems - numActualItems);
- mTaskAdapter.notifyItemRangeChanged(TASKS_START_POSITION, numActualItems,
- CHANGE_EVENT_TYPE_EMPTY_TO_CONTENT);
});
}
@@ -316,6 +355,17 @@ public final class IconRecentsView extends FrameLayout implements Insettable {
}
/**
+ * 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.
*/
@@ -361,22 +411,31 @@ public final class IconRecentsView extends FrameLayout implements Insettable {
* @param showStatusBarForegroundScrim true to show the scrim, false to hide
*/
public void setShowStatusBarForegroundScrim(boolean showStatusBarForegroundScrim) {
- boolean shouldShow = mInsets.top != 0 && showStatusBarForegroundScrim;
+ mShowStatusBarForegroundScrim = showStatusBarForegroundScrim;
+ if (mShowStatusBarForegroundScrim != showStatusBarForegroundScrim) {
+ updateStatusBarScrim();
+ }
+ }
+
+ private void updateStatusBarScrim() {
+ boolean shouldShow = mInsets.top != 0 && mShowStatusBarForegroundScrim;
mActivity.getDragLayer().setForeground(shouldShow ? mStatusBarForegroundScrim : null);
}
/**
- * 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;
}
/**
@@ -580,6 +639,255 @@ public final class IconRecentsView extends FrameLayout implements Insettable {
}
});
mLayoutAnimation.start();
+ mStartedEnterAnimation = true;
+ }
+
+ /**
+ * Play remote app to recents animation when the app is the home activity. We use a simple
+ * cross-fade here. Note this is only used if the home activity is a separate app than the
+ * recents activity.
+ *
+ * @param anim animator set
+ * @param homeTarget the home surface thats closing
+ * @param recentsTarget the surface containing recents
+ */
+ public void playRemoteHomeToRecentsAnimation(@NonNull AnimatorSet anim,
+ @NonNull RemoteAnimationTargetCompat homeTarget,
+ @NonNull RemoteAnimationTargetCompat recentsTarget) {
+ SyncRtSurfaceTransactionApplierCompat surfaceApplier =
+ new SyncRtSurfaceTransactionApplierCompat(this);
+
+ SurfaceParams[] params = new SurfaceParams[2];
+ int boostedMode = MODE_CLOSING;
+
+ ValueAnimator remoteHomeAnim = ValueAnimator.ofFloat(0, 1);
+ remoteHomeAnim.setDuration(REMOTE_APP_TO_OVERVIEW_DURATION);
+
+ remoteHomeAnim.addUpdateListener(valueAnimator -> {
+ float val = (float) valueAnimator.getAnimatedValue();
+ float alpha;
+ RemoteAnimationTargetCompat visibleTarget;
+ RemoteAnimationTargetCompat invisibleTarget;
+ if (val < .5f) {
+ visibleTarget = homeTarget;
+ invisibleTarget = recentsTarget;
+ alpha = 1 - (val * 2);
+ } else {
+ visibleTarget = recentsTarget;
+ invisibleTarget = homeTarget;
+ alpha = (val - .5f) * 2;
+ }
+ params[0] = new SurfaceParams(visibleTarget.leash, alpha, null /* matrix */,
+ null /* windowCrop */, getLayer(visibleTarget, boostedMode),
+ 0 /* cornerRadius */);
+ params[1] = new SurfaceParams(invisibleTarget.leash, 0.0f, null /* matrix */,
+ null /* windowCrop */, getLayer(invisibleTarget, boostedMode),
+ 0 /* cornerRadius */);
+ surfaceApplier.scheduleApply(params);
+ });
+ anim.play(remoteHomeAnim);
+ animateFadeInLayoutAnimation();
+ }
+
+ /**
+ * 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));
+ return;
+ }
+ final Matrix appMatrix = new Matrix();
+ playRemoteTransYAnim(anim, appMatrix);
+ playRemoteAppScaleDownAnim(anim, appMatrix, appTarget, recentsTarget,
+ bottomView.getThumbnailView());
+ playRemoteTaskListFadeIn(anim, bottomView);
+ mStartedEnterAnimation = true;
+ }
+
+ /**
+ * 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
@@ -587,6 +895,9 @@ public final class IconRecentsView extends FrameLayout implements Insettable {
mInsets = insets;
mTaskRecyclerView.setPadding(insets.left, insets.top, insets.right, insets.bottom);
mTaskRecyclerView.invalidateItemDecorations();
+ if (mInsets.top != 0) {
+ updateStatusBarScrim();
+ }
}
/**
diff --git a/go/quickstep/src/com/android/quickstep/views/TaskItemView.java b/go/quickstep/src/com/android/quickstep/views/TaskItemView.java
index 6db801322..f184ad06a 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 @@ public final class TaskItemView extends LinearLayout {
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/protos/launcher_log.proto b/protos/launcher_log.proto
index 02c6b0f41..49fd43617 100644
--- a/protos/launcher_log.proto
+++ b/protos/launcher_log.proto
@@ -56,6 +56,7 @@ message Target {
optional int32 predictedRank = 15;
optional TargetExtension extension = 16;
optional TipType tip_type = 17;
+ optional int32 search_query_length = 18;
}
// Used to define what type of item a Target would represent.
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 000000000..be3f17acd
--- /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/appprediction/PredictionAppTracker.java b/quickstep/recents_ui_overrides/src/com/android/launcher3/appprediction/PredictionAppTracker.java
index 0b8c1c57f..fa2810630 100644
--- a/quickstep/recents_ui_overrides/src/com/android/launcher3/appprediction/PredictionAppTracker.java
+++ b/quickstep/recents_ui_overrides/src/com/android/launcher3/appprediction/PredictionAppTracker.java
@@ -158,10 +158,10 @@ public class PredictionAppTracker extends AppLaunchTracker {
public void onStartShortcut(String packageName, String shortcutId, UserHandle user,
String container) {
// TODO: Use the full shortcut info
- AppTarget target = new AppTarget.Builder(new AppTargetId("shortcut:" + shortcutId))
- .setTarget(packageName, user)
- .setClassName(shortcutId)
- .build();
+ AppTarget target = new AppTarget
+ .Builder(new AppTargetId("shortcut:" + shortcutId), packageName, user)
+ .setClassName(shortcutId)
+ .build();
sendLaunch(target, container);
}
@@ -169,10 +169,10 @@ public class PredictionAppTracker extends AppLaunchTracker {
@UiThread
public void onStartApp(ComponentName cn, UserHandle user, String container) {
if (cn != null) {
- AppTarget target = new AppTarget.Builder(new AppTargetId("app:" + cn))
- .setTarget(cn.getPackageName(), user)
- .setClassName(cn.getClassName())
- .build();
+ AppTarget target = new AppTarget
+ .Builder(new AppTargetId("app:" + cn), cn.getPackageName(), user)
+ .setClassName(cn.getClassName())
+ .build();
sendLaunch(target, container);
}
}
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 11a1885d1..c3a769887 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.LauncherState;
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 @@ public final class RecentsViewStateController extends
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 @@ public final class RecentsViewStateController extends
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 @@ public final class RecentsViewStateController extends
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 96d2dca97..5eecf1713 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.KeyEvent;
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 e20ef5259..2c919b3c1 100644
--- a/quickstep/recents_ui_overrides/src/com/android/quickstep/TaskSystemShortcut.java
+++ b/quickstep/recents_ui_overrides/src/com/android/quickstep/TaskSystemShortcut.java
@@ -296,10 +296,6 @@ public class TaskSystemShortcut<T extends SystemShortcut> extends SystemShortcut
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 ee9876ac5..128fd45fe 100644
--- a/quickstep/recents_ui_overrides/src/com/android/quickstep/TouchInteractionService.java
+++ b/quickstep/recents_ui_overrides/src/com/android/quickstep/TouchInteractionService.java
@@ -66,6 +66,13 @@ import com.android.launcher3.util.LooperExecutor;
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;
@@ -460,6 +467,12 @@ public class TouchInteractionService extends Service implements
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 58ae5eb73..d927d8306 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.WindowManager;
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;
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 @@ public class WindowTransformSwipeHandler<T extends BaseDraggingActivity>
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 @@ public class WindowTransformSwipeHandler<T extends BaseDraggingActivity>
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 @@ public class WindowTransformSwipeHandler<T extends BaseDraggingActivity>
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;
@@ -1092,14 +1095,15 @@ public class WindowTransformSwipeHandler<T extends BaseDraggingActivity>
homeAnim.setPlayFraction(progress);
- float iconAlpha = Utilities.mapToRange(interpolatedProgress, 0,
- windowAlphaThreshold, 0f, 1f, Interpolators.LINEAR);
- mTransformParams.setCurrentRectAndTargetAlpha(currentRect, 1f - iconAlpha);
+ float windowAlpha = Utilities.mapToRange(interpolatedProgress, 0,
+ windowAlphaThreshold, 1f, 0f, Interpolators.LINEAR);
+ mTransformParams.setProgress(progress)
+ .setCurrentRectAndTargetAlpha(currentRect, windowAlpha);
mClipAnimationHelper.applyTransform(targetSet, mTransformParams,
false /* launcherOnTop */);
if (isFloatingIconView) {
- ((FloatingIconView) floatingView).update(currentRect, iconAlpha, progress,
+ ((FloatingIconView) floatingView).update(currentRect, 1f, progress,
windowAlphaThreshold, mClipAnimationHelper.getCurrentCornerRadius(), false);
}
@@ -1125,6 +1129,13 @@ public class WindowTransformSwipeHandler<T extends BaseDraggingActivity>
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 000000000..74a48517b
--- /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
index 8f8cd18fe..f8475ca18 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
index 335e8b15a..0448fd14a 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,7 +14,7 @@
* 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;
@@ -43,6 +43,7 @@ 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;
@@ -236,7 +237,7 @@ public class AssistantTouchConsumer extends DelegateInputConsumer
}
}
- static boolean withinTouchRegion(Context context, MotionEvent ev) {
+ 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;
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
index d36162f8b..311ddd27c 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
index 7fd09f7de..b1d175df8 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
index 37b728871..2e8880dde 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 @@ public interface InputConsumer {
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
index db377b0c0..e862fa6c8 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.graphics.RotationMode;
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 @@ public class OtherActivityInputConsumer extends ContextWrapper implements InputC
// 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
index bafc367c8..bab3c71c6 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 androidx.annotation.Nullable;
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 000000000..a0e20f2cd
--- /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/util/RectFSpringAnim.java b/quickstep/recents_ui_overrides/src/com/android/quickstep/util/RectFSpringAnim.java
index 40b9c4dce..09db6952f 100644
--- a/quickstep/recents_ui_overrides/src/com/android/quickstep/util/RectFSpringAnim.java
+++ b/quickstep/recents_ui_overrides/src/com/android/quickstep/util/RectFSpringAnim.java
@@ -33,6 +33,8 @@ import com.android.launcher3.anim.FlingSpringAnim;
import java.util.ArrayList;
import java.util.List;
+import static com.android.launcher3.anim.Interpolators.DEACCEL;
+
/**
* Applies spring forces to animate from a starting rect to a target rect,
* while providing update callbacks to the caller.
@@ -45,7 +47,7 @@ public class RectFSpringAnim {
* can be done in parallel at a fixed duration. Update callbacks are sent based on the progress
* of this animation, while the end callback is sent after all animations finish.
*/
- private static final long RECT_SCALE_DURATION = 180;
+ private static final long RECT_SCALE_DURATION = 250;
private static final FloatPropertyCompat<RectFSpringAnim> RECT_CENTER_X =
new FloatPropertyCompat<RectFSpringAnim>("rectCenterXSpring") {
@@ -148,6 +150,7 @@ public class RectFSpringAnim {
mRectScaleAnim = ObjectAnimator.ofPropertyValuesHolder(this,
PropertyValuesHolder.ofFloat(RECT_SCALE_PROGRESS, 1))
.setDuration(RECT_SCALE_DURATION);
+ mRectScaleAnim.setInterpolator(DEACCEL);
mRectScaleAnim.addListener(new AnimationSuccessListener() {
@Override
public void onAnimationSuccess(Animator animator) {
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 d6f223503..bdac750de 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.os.Build;
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.R;
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 @@ import com.android.quickstep.util.LayoutUtils;
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 class LauncherRecentsView extends RecentsView<Launcher> {
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 @@ public class LauncherRecentsView extends RecentsView<Launcher> {
}
}
+ @Nullable
+ public ProactiveHintsContainer getProactiveHintsContainer() {
+ return mProactiveHintsContainer;
+ }
+
@Override
public void draw(Canvas canvas) {
maybeDrawEmptyMessage(canvas);
@@ -137,6 +159,48 @@ public class LauncherRecentsView extends RecentsView<Launcher> {
@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 88954b227..64b8e2c3b 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 34fb3be41..3daa92226 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 ebdcf7363..73c7c5c03 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 02312f49e..aa8fa536a 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 baab4a12f..fbbe9d2dc 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 b28f3771a..c4a277267 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 0475c0d1f..9e8c54a9c 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 e6764e016..57f92e5a0 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 77b4c4607..7968f7cc6 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 484f445db..6420aa8cb 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 a698d49de..194ff87dc 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 b3e8524f8..b43a76eb9 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 10e4fd7ce..7f4e56d26 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 6ef1e9426..87268df74 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 d640b63ea..2d1418e5f 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 d640b63ea..2d1418e5f 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 d640b63ea..2d1418e5f 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 c93e8fc4a..5f5d0bdfe 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 3a588e5fc..329286b3b 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 7032765bb..0577b0f56 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 66e08b9f1..c2d149e36 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 112d04cde..cc26695a6 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 6a0a35930..f43433e3a 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 248a5da5e..a9a1cffb6 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 338d9baff..5394f495e 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 d6ddf3cd6..c6698bb48 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 4493e3b5d..660ad87ac 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 3c53cce45..0467af4b2 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 103710ff9..ab56e57b5 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 22b2380f2..dec6ea015 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 910265acc..1656a1444 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 a7749df88..6824d16b4 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 ba0c6723f..f60a2c680 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 746443eab..559fdb4b6 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 96a8adcaf..58cab4e0a 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 5484ae1fc..d3fecde20 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 9218fb8b8..67b03a754 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 076615022..a9fcbedb2 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 8737ae830..c422041e7 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 099957cb7..52782610b 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 9543e7987..7a8e6a1f9 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 d1d2d201d..4018e57dc 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 aba4156d0..e406b7083 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 933b3f094..ed1fc373e 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 1e2ed00f1..85ce0e017 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 7a6c094b5..9f11521df 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 b5eac1dc3..2e02e80fa 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 a105ef160..5de860202 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 bf725e337..1ca558a24 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 2e3f236b1..254296376 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 7b931257b..7683e0599 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 74f43d2e2..01bbb6a75 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 6053def16..60e9bd531 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 4e3a34c25..8032567e1 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 5aeeae6b3..58c0d2afa 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 210edcf01..d83160dff 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 8a129d5ea..2fd34d636 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 e5380d560..673dfe2e7 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 54452a058..2ac783eb0 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 8b2016ab2..5dd89a644 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 216339067..f6584c4dc 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 12983db6d..8a9c7365f 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 a940f2bfc..15f8f89cc 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 e41bcb59a..d8f5f28b4 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 8f26c6650..b72164144 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 70740e502..ba7ebcdec 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 c646b6a5f..24db42909 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 19bfaa92f..97d51cd35 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 071755a95..24b37f75d 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 c0e78cec1..0f6821bf1 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 76a0b250a..491bac5bd 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 8b59c7bd0..ec6d88405 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 39c3848bd..77360625d 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 4fd9e69bf..87b303f2a 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 466d79ea5..67c8e91c0 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 842b22bfe..34c89efcf 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 951489fff..0e83977fa 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 361623dfa..ac7e8e900 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 6938d3e81..3323bfd57 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 98f7b02d9..0f1d99d7b 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 32f312fdb..82d1aa672 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 3b75304b7..7dd4df7d6 100644
--- a/quickstep/src/com/android/launcher3/QuickstepAppTransitionManagerImpl.java
+++ b/quickstep/src/com/android/launcher3/QuickstepAppTransitionManagerImpl.java
@@ -104,16 +104,18 @@ public abstract class QuickstepAppTransitionManagerImpl extends LauncherAppTrans
private static final String CONTROL_REMOTE_APP_TRANSITION_PERMISSION =
"android.permission.CONTROL_REMOTE_APP_TRANSITION_ANIMATIONS";
- private static final long APP_LAUNCH_DURATION = 500;
+ private static final long APP_LAUNCH_DURATION = 450;
// Use a shorter duration for x or y translation to create a curve effect
- private static final long APP_LAUNCH_CURVED_DURATION = APP_LAUNCH_DURATION / 2;
+ private static final long APP_LAUNCH_CURVED_DURATION = 250;
private static final long APP_LAUNCH_ALPHA_DURATION = 50;
+ private static final long APP_LAUNCH_ALPHA_START_DELAY = 50;
// We scale the durations for the downward app launch animations (minus the scale animation).
private static final float APP_LAUNCH_DOWN_DUR_SCALE_FACTOR = 0.8f;
private static final long APP_LAUNCH_DOWN_DURATION =
(long) (APP_LAUNCH_DURATION * APP_LAUNCH_DOWN_DUR_SCALE_FACTOR);
- private static final long APP_LAUNCH_DOWN_CURVED_DURATION = APP_LAUNCH_DOWN_DURATION / 2;
+ private static final long APP_LAUNCH_DOWN_CURVED_DURATION =
+ (long) (APP_LAUNCH_CURVED_DURATION * APP_LAUNCH_DOWN_DUR_SCALE_FACTOR);
private static final long APP_LAUNCH_ALPHA_DOWN_DURATION =
(long) (APP_LAUNCH_ALPHA_DURATION * APP_LAUNCH_DOWN_DUR_SCALE_FACTOR);
@@ -475,17 +477,18 @@ public abstract class QuickstepAppTransitionManagerImpl extends LauncherAppTrans
float shapeRevealDuration = APP_LAUNCH_DURATION * SHAPE_PROGRESS_DURATION;
final float windowRadius = mDeviceProfile.isMultiWindowMode
- ? 0 : getWindowCornerRadius(mLauncher.getResources());
-
+ ? 0 : getWindowCornerRadius(mLauncher.getResources());
appAnimator.addUpdateListener(new MultiValueUpdateListener() {
FloatProp mDx = new FloatProp(0, dX, 0, xDuration, AGGRESSIVE_EASE);
FloatProp mDy = new FloatProp(0, dY, 0, yDuration, AGGRESSIVE_EASE);
FloatProp mIconScale = new FloatProp(initialStartScale, scale, 0, APP_LAUNCH_DURATION,
EXAGGERATED_EASE);
- FloatProp mIconAlpha = new FloatProp(1f, 0f, shapeRevealDuration, alphaDuration,
- LINEAR);
+ FloatProp mIconAlpha = new FloatProp(1f, 0f, APP_LAUNCH_ALPHA_START_DELAY,
+ alphaDuration, LINEAR);
FloatProp mCropHeight = new FloatProp(windowTargetBounds.width(),
- windowTargetBounds.height(), 0, shapeRevealDuration, AGGRESSIVE_EASE);
+ windowTargetBounds.height(), 0, APP_LAUNCH_DURATION, EXAGGERATED_EASE);
+ FloatProp mWindowRadius = new FloatProp(windowTargetBounds.width() / 2f,
+ windowRadius, 0, APP_LAUNCH_DURATION, EXAGGERATED_EASE);
@Override
public void onUpdate(float percent) {
@@ -518,6 +521,7 @@ public abstract class QuickstepAppTransitionManagerImpl extends LauncherAppTrans
float transX0 = temp.left - offsetX;
float transY0 = temp.top - offsetY;
+ float croppedHeight = (windowTargetBounds.height() - crop.height()) * scale;
SurfaceParams[] params = new SurfaceParams[targets.length];
for (int i = targets.length - 1; i >= 0; i--) {
RemoteAnimationTargetCompat target = targets[i];
@@ -529,8 +533,9 @@ public abstract class QuickstepAppTransitionManagerImpl extends LauncherAppTrans
matrix.postTranslate(transX0, transY0);
targetCrop = crop;
alpha = 1f - mIconAlpha.value;
- cornerRadius = windowRadius;
+ cornerRadius = mWindowRadius.value;
matrix.mapRect(currentBounds, targetBounds);
+ currentBounds.bottom -= croppedHeight;
mFloatingView.update(currentBounds, mIconAlpha.value, percent, 0f,
cornerRadius * scale, true /* isOpening */);
} else {
diff --git a/quickstep/src/com/android/quickstep/util/MotionPauseDetector.java b/quickstep/src/com/android/quickstep/util/MotionPauseDetector.java
index f58f0d485..893c05356 100644
--- a/quickstep/src/com/android/quickstep/util/MotionPauseDetector.java
+++ b/quickstep/src/com/android/quickstep/util/MotionPauseDetector.java
@@ -35,10 +35,18 @@ public class MotionPauseDetector {
/** 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 @@ public class MotionPauseDetector {
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 @@ public class MotionPauseDetector {
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 @@ public class MotionPauseDetector {
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 @@ public class MotionPauseDetector {
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 @@ public class MotionPauseDetector {
mFirstPosition = null;
setOnMotionPauseListener(null);
mIsPaused = mHasEverBeenPaused = false;
+ mSlowStartTime = 0;
mForcePauseTimeout.cancelAlarm();
}
diff --git a/quickstep/tests/src/com/android/quickstep/AppPredictionsUITests.java b/quickstep/tests/src/com/android/quickstep/AppPredictionsUITests.java
index ffe363335..47ce44c67 100644
--- a/quickstep/tests/src/com/android/quickstep/AppPredictionsUITests.java
+++ b/quickstep/tests/src/com/android/quickstep/AppPredictionsUITests.java
@@ -149,10 +149,10 @@ public class AppPredictionsUITests extends AbstractQuickStepTest {
List<AppTarget> targets = new ArrayList<>(activities.length);
for (LauncherActivityInfo info : activities) {
ComponentName cn = info.getComponentName();
- AppTarget target = new AppTarget.Builder(new AppTargetId("app:" + cn))
- .setTarget(cn.getPackageName(), info.getUser())
- .setClassName(cn.getClassName())
- .build();
+ AppTarget target =
+ new AppTarget.Builder(new AppTargetId("app:" + cn), cn.getPackageName(), info.getUser())
+ .setClassName(cn.getClassName())
+ .build();
targets.add(target);
}
mCallback.onTargetsAvailable(targets);
diff --git a/quickstep/tests/src/com/android/quickstep/StartLauncherViaGestureTests.java b/quickstep/tests/src/com/android/quickstep/StartLauncherViaGestureTests.java
index 8bdb90db7..2111e2ca2 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.Launcher;
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 cca899bda..9cab9c2a5 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 000000000..2637f038c
--- /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 469b176fb..0da56dafb 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/allapps/AllAppsContainerView.java b/src/com/android/launcher3/allapps/AllAppsContainerView.java
index e2a5160af..41252aab5 100644
--- a/src/com/android/launcher3/allapps/AllAppsContainerView.java
+++ b/src/com/android/launcher3/allapps/AllAppsContainerView.java
@@ -604,4 +604,18 @@ public class AllAppsContainerView extends SpringRelativeLayout implements DragSo
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/anim/FlingSpringAnim.java b/src/com/android/launcher3/anim/FlingSpringAnim.java
index bb0f855d8..3d981c136 100644
--- a/src/com/android/launcher3/anim/FlingSpringAnim.java
+++ b/src/com/android/launcher3/anim/FlingSpringAnim.java
@@ -30,8 +30,8 @@ public class FlingSpringAnim {
private static final float FLING_FRICTION = 1.5f;
// Have the spring pull towards the target if we've slowed down too much before reaching it.
private static final float FLING_END_THRESHOLD_PX = 50f;
- private static final float SPRING_STIFFNESS = 350f;
- private static final float SPRING_DAMPING = SpringForce.DAMPING_RATIO_LOW_BOUNCY;
+ private static final float SPRING_STIFFNESS = 200;
+ private static final float SPRING_DAMPING = 0.85f;
private final FlingAnimation mFlingAnim;
private SpringAnimation mSpringAnim;
diff --git a/src/com/android/launcher3/logging/LoggerUtils.java b/src/com/android/launcher3/logging/LoggerUtils.java
index 1ffa69857..9b75b43b4 100644
--- a/src/com/android/launcher3/logging/LoggerUtils.java
+++ b/src/com/android/launcher3/logging/LoggerUtils.java
@@ -144,6 +144,10 @@ public class LoggerUtils {
+ "), pageIdx=" + t.pageIndex;
}
+ if (t.searchQueryLength != 0) {
+ typeStr += ", searchQueryLength=" + t.searchQueryLength;
+ }
+
if (t.itemType == ItemType.TASK) {
typeStr += ", pageIdx=" + t.pageIndex;
}
diff --git a/src/com/android/launcher3/views/FloatingIconView.java b/src/com/android/launcher3/views/FloatingIconView.java
index 787c93ce9..73f11b22d 100644
--- a/src/com/android/launcher3/views/FloatingIconView.java
+++ b/src/com/android/launcher3/views/FloatingIconView.java
@@ -98,10 +98,9 @@ public class FloatingIconView extends View implements
private RectF mPositionOut;
private Runnable mOnTargetChangeRunnable;
+ private final Rect mOutline = new Rect();
private final Rect mFinalDrawableBounds = new Rect();
private final Rect mBgDrawableBounds = new Rect();
- private float mBgDrawableStartScale = 1f;
- private float mBgDrawableEndScale = 1f;
private AnimatorSet mFadeAnimatorSet;
private ListenerView mListenerView;
@@ -143,11 +142,10 @@ public class FloatingIconView extends View implements
setTranslationX(dX);
setTranslationY(dY);
- float scaleX = rect.width() / (float) lp.width;
- float scaleY = rect.height() / (float) lp.height;
- float scale = mIsAdaptiveIcon && !isOpening ? Math.max(scaleX, scaleY)
- : Math.min(scaleX, scaleY);
- scale = Math.max(1f, scale);
+ float minSize = Math.min(lp.width, lp.height);
+ float scaleX = rect.width() / minSize;
+ float scaleY = rect.height() / minSize;
+ float scale = Math.max(1f, Math.min(scaleX, scaleY));
setPivotX(0);
setPivotY(0);
@@ -160,27 +158,27 @@ public class FloatingIconView extends View implements
Math.max(shapeProgressStart, progress), shapeProgressStart, 1f, 0, toMax,
LINEAR), 0, 1);
- mTaskCornerRadius = cornerRadius;
- if (mIsAdaptiveIcon && shapeRevealProgress >= 0) {
- if (mRevealAnimator == null) {
- mRevealAnimator = (ValueAnimator) IconShape.getShape().createRevealAnimator(this,
- mStartRevealRect, mEndRevealRect, mTaskCornerRadius / scale, !isOpening);
- mRevealAnimator.addListener(new AnimatorListenerAdapter() {
- @Override
- public void onAnimationEnd(Animator animation) {
- mRevealAnimator = null;
- }
- });
- mRevealAnimator.start();
- // We pause here so we can set the current fraction ourselves.
- mRevealAnimator.pause();
+ mOutline.bottom = (int) (rect.height() / scale);
+ mTaskCornerRadius = cornerRadius / scale;
+ if (mIsAdaptiveIcon) {
+ if (!isOpening && shapeRevealProgress >= 0) {
+ if (mRevealAnimator == null) {
+ mRevealAnimator = (ValueAnimator) IconShape.getShape().createRevealAnimator(
+ this, mStartRevealRect, mOutline, mTaskCornerRadius, !isOpening);
+ mRevealAnimator.addListener(new AnimatorListenerAdapter() {
+ @Override
+ public void onAnimationEnd(Animator animation) {
+ mRevealAnimator = null;
+ }
+ });
+ mRevealAnimator.start();
+ // We pause here so we can set the current fraction ourselves.
+ mRevealAnimator.pause();
+ }
+ mRevealAnimator.setCurrentFraction(shapeRevealProgress);
}
- mRevealAnimator.setCurrentFraction(shapeRevealProgress);
-
- float bgScale = (mBgDrawableEndScale * shapeRevealProgress) + mBgDrawableStartScale
- * (1 - shapeRevealProgress);
- setBackgroundDrawableBounds(bgScale);
+ setBackgroundDrawableBounds(mOutline.height() / minSize);
}
invalidate();
invalidateOutline();
@@ -363,24 +361,22 @@ public class FloatingIconView extends View implements
layout(lp.leftMargin, lp.topMargin, lp.leftMargin + lp.width, lp.topMargin
+ lp.height);
- Rect rectOutline = new Rect();
float scale = Math.max((float) lp.height / originalHeight,
(float) lp.width / originalWidth);
+ float bgDrawableStartScale;
if (isOpening) {
- mBgDrawableStartScale = 1f;
- mBgDrawableEndScale = scale;
- rectOutline.set(0, 0, originalWidth, originalHeight);
+ bgDrawableStartScale = 1f;
+ mOutline.set(0, 0, originalWidth, originalHeight);
} else {
- mBgDrawableStartScale = scale;
- mBgDrawableEndScale = 1f;
- rectOutline.set(0, 0, lp.width, lp.height);
+ bgDrawableStartScale = scale;
+ mOutline.set(0, 0, lp.width, lp.height);
}
+ setBackgroundDrawableBounds(bgDrawableStartScale);
mEndRevealRect.set(0, 0, lp.width, lp.height);
- setBackgroundDrawableBounds(mBgDrawableStartScale);
setOutlineProvider(new ViewOutlineProvider() {
@Override
public void getOutline(View view, Outline outline) {
- outline.setRoundRect(rectOutline, mTaskCornerRadius);
+ outline.setRoundRect(mOutline, mTaskCornerRadius);
}
});
setClipToOutline(true);
@@ -630,5 +626,7 @@ public class FloatingIconView extends View implements
mListenerView.setListener(null);
mOriginalIcon = null;
mOnTargetChangeRunnable = null;
+ mTaskCornerRadius = 0;
+ mOutline.setEmpty();
}
}
diff --git a/tests/tapl/com/android/launcher3/tapl/Background.java b/tests/tapl/com/android/launcher3/tapl/Background.java
index 60d2850b4..8f5e7fed0 100644
--- a/tests/tapl/com/android/launcher3/tapl/Background.java
+++ b/tests/tapl/com/android/launcher3/tapl/Background.java
@@ -17,16 +17,12 @@
package com.android.launcher3.tapl;
import static com.android.launcher3.TestProtocol.BACKGROUND_APP_STATE_ORDINAL;
-import static com.android.launcher3.tapl.LauncherInstrumentation.WAIT_TIME_MS;
-import static com.android.launcher3.tapl.TestHelpers.getOverviewPackageName;
import android.graphics.Point;
import android.os.SystemClock;
import android.view.MotionEvent;
import androidx.annotation.NonNull;
-import androidx.test.uiautomator.By;
-import androidx.test.uiautomator.Until;
import com.android.launcher3.TestProtocol;
@@ -59,8 +55,6 @@ public class Background extends LauncherInstrumentation.VisibleContainer {
"want to switch from background to overview")) {
verifyActiveContainer();
goToOverviewUnchecked(BACKGROUND_APP_STATE_ORDINAL);
- mLauncher.assertTrue("Overview not visible", mLauncher.getDevice().wait(
- Until.hasObject(By.pkg(getOverviewPackageName())), WAIT_TIME_MS));
return new BaseOverview(mLauncher);
}
}
diff --git a/tests/tapl/com/android/launcher3/tapl/BaseOverview.java b/tests/tapl/com/android/launcher3/tapl/BaseOverview.java
index 70d8cf7ab..b3a369aad 100644
--- a/tests/tapl/com/android/launcher3/tapl/BaseOverview.java
+++ b/tests/tapl/com/android/launcher3/tapl/BaseOverview.java
@@ -33,6 +33,7 @@ public class BaseOverview extends LauncherInstrumentation.VisibleContainer {
BaseOverview(LauncherInstrumentation launcher) {
super(launcher);
+ verifyActiveContainer();
}
@Override
diff --git a/tests/tapl/com/android/launcher3/tapl/LauncherInstrumentation.java b/tests/tapl/com/android/launcher3/tapl/LauncherInstrumentation.java
index 4d8ff1bb2..a63d468e5 100644
--- a/tests/tapl/com/android/launcher3/tapl/LauncherInstrumentation.java
+++ b/tests/tapl/com/android/launcher3/tapl/LauncherInstrumentation.java
@@ -18,6 +18,7 @@ package com.android.launcher3.tapl;
import static com.android.launcher3.TestProtocol.BACKGROUND_APP_STATE_ORDINAL;
import static com.android.launcher3.TestProtocol.NORMAL_STATE_ORDINAL;
+import static com.android.launcher3.tapl.TestHelpers.getOverviewPackageName;
import android.app.ActivityManager;
import android.app.Instrumentation;
@@ -176,17 +177,19 @@ public final class LauncherInstrumentation {
// Workaround, use constructed context because both the instrumentation context and the
// app context are not constructed with resources that take overlays into account
final Context ctx = baseContext.createPackageContext("android", 0);
- log("Interaction mode = " + getCurrentInteractionMode(ctx));
- if (isGesturalMode(ctx)) {
- return NavigationModel.ZERO_BUTTON;
- } else if (isSwipeUpMode(ctx)) {
- return NavigationModel.TWO_BUTTON;
- } else if (isLegacyMode(ctx)) {
- return NavigationModel.THREE_BUTTON;
- } else {
- fail("Can't detect navigation mode");
+ for (int i = 0; i < 100; ++i) {
+ log("Interaction mode = " + getCurrentInteractionMode(ctx));
+ if (isGesturalMode(ctx)) {
+ return NavigationModel.ZERO_BUTTON;
+ } else if (isSwipeUpMode(ctx)) {
+ return NavigationModel.TWO_BUTTON;
+ } else if (isLegacyMode(ctx)) {
+ return NavigationModel.THREE_BUTTON;
+ }
+ Thread.sleep(100);
}
- } catch (PackageManager.NameNotFoundException e) {
+ fail("Can't detect navigation mode");
+ } catch (Exception e) {
fail(e.toString());
}
return NavigationModel.THREE_BUTTON;
@@ -294,14 +297,14 @@ public final class LauncherInstrumentation {
} else {
waitUntilGone(APPS_RES_ID);
}
- // Fall through
- }
- case BASE_OVERVIEW: {
waitUntilGone(WORKSPACE_RES_ID);
waitUntilGone(WIDGETS_RES_ID);
return waitForLauncherObject(OVERVIEW_RES_ID);
}
+ case BASE_OVERVIEW: {
+ return waitForFallbackLauncherObject(OVERVIEW_RES_ID);
+ }
case BACKGROUND: {
waitUntilGone(WORKSPACE_RES_ID);
waitUntilGone(APPS_RES_ID);
@@ -526,10 +529,22 @@ public final class LauncherInstrumentation {
return object;
}
+ @NonNull
+ UiObject2 waitForFallbackLauncherObject(String resName) {
+ final BySelector selector = getFallbackLauncherObjectSelector(resName);
+ final UiObject2 object = mDevice.wait(Until.findObject(selector), WAIT_TIME_MS);
+ assertNotNull("Can't find a fallback launcher object; selector: " + selector, object);
+ return object;
+ }
+
BySelector getLauncherObjectSelector(String resName) {
return By.res(getLauncherPackageName(), resName);
}
+ BySelector getFallbackLauncherObjectSelector(String resName) {
+ return By.res(getOverviewPackageName(), resName);
+ }
+
String getLauncherPackageName() {
return mDevice.getLauncherPackageName();
}
diff --git a/tests/tapl/com/android/launcher3/tapl/Workspace.java b/tests/tapl/com/android/launcher3/tapl/Workspace.java
index e8a0b5468..c0bafa2e7 100644
--- a/tests/tapl/com/android/launcher3/tapl/Workspace.java
+++ b/tests/tapl/com/android/launcher3/tapl/Workspace.java
@@ -58,9 +58,13 @@ public final class Workspace extends Home {
verifyActiveContainer();
final UiObject2 hotseat = mHotseat;
final Point start = hotseat.getVisibleCenter();
+ start.y = hotseat.getVisibleBounds().bottom - 1;
final int swipeHeight = mLauncher.getTestInfo(
TestProtocol.REQUEST_HOME_TO_ALL_APPS_SWIPE_HEIGHT).
getInt(TestProtocol.TEST_INFO_RESPONSE_FIELD);
+ LauncherInstrumentation.log(
+ "switchToAllApps: swipeHeight = " + swipeHeight + ", slop = "
+ + mLauncher.getTouchSlop());
mLauncher.swipe(
start.x,
start.y,