diff options
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">"< 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">"< 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">"< 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">"< 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">"< 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">"< 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">"< ১ মি."</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">"< 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">"< 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">"< 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">"< 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">"< 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">"< 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">"< 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">"< 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">"< 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">"< 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">"<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">"< 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">"< 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">"< ۱ دقیقه"</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">"< 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">"< 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">"< 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">"<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">"< 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">"<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">"< 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">"< 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">"< 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">"< 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">"< 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">"< 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">"< דקה"</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">"< 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">"< 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">"< 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">"< 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">"< 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">"< 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">"< 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">"< 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">"<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">"< 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">"< 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">"< 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">"< 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">"< ၁ မိနစ်"</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">"< 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">"< १ मिनेट"</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">"< 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">"< 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">"> 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">"< 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">"< 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">"< 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">"< 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">"< 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">"< 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">"< 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">"< 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">"< 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">"< 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">"< 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">"< 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">"<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">"< 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">"< 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">"< 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">"< 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">"< 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">"< 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">"< 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">"< 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, |