diff options
Diffstat (limited to 'quickstep')
12 files changed, 264 insertions, 66 deletions
diff --git a/quickstep/res/values/dimens.xml b/quickstep/res/values/dimens.xml index 49c4492b6..17d5c60ba 100644 --- a/quickstep/res/values/dimens.xml +++ b/quickstep/res/values/dimens.xml @@ -33,7 +33,7 @@ <!-- Launcher app transition --> <dimen name="content_trans_y">50dp</dimen> - <dimen name="workspace_trans_y">50dp</dimen> + <dimen name="springs_trans_y">-70dp</dimen> <dimen name="closing_window_trans_y">115dp</dimen> <dimen name="recents_empty_message_text_size">16sp</dimen> diff --git a/quickstep/src/com/android/launcher3/LauncherAppTransitionManagerImpl.java b/quickstep/src/com/android/launcher3/LauncherAppTransitionManagerImpl.java index 13530b2e5..252e3eaee 100644 --- a/quickstep/src/com/android/launcher3/LauncherAppTransitionManagerImpl.java +++ b/quickstep/src/com/android/launcher3/LauncherAppTransitionManagerImpl.java @@ -16,6 +16,7 @@ package com.android.launcher3; +import static android.view.View.TRANSLATION_Y; import static com.android.launcher3.BaseActivity.INVISIBLE_ALL; import static com.android.launcher3.BaseActivity.INVISIBLE_BY_APP_TRANSITIONS; import static com.android.launcher3.BaseActivity.INVISIBLE_BY_PENDING_FLAGS; @@ -27,8 +28,10 @@ import static com.android.launcher3.LauncherState.OVERVIEW; import static com.android.launcher3.Utilities.postAsyncCallback; import static com.android.launcher3.allapps.AllAppsTransitionController.ALL_APPS_PROGRESS; import static com.android.launcher3.anim.Interpolators.AGGRESSIVE_EASE; +import static com.android.launcher3.anim.Interpolators.DEACCEL; import static com.android.launcher3.anim.Interpolators.DEACCEL_1_7; import static com.android.launcher3.anim.Interpolators.LINEAR; +import static com.android.launcher3.anim.Interpolators.OSCILLATE; import static com.android.launcher3.dragndrop.DragLayer.ALPHA_INDEX_TRANSITIONS; import static com.android.quickstep.TaskUtils.findTaskViewToLaunch; import static com.android.quickstep.TaskUtils.getRecentsWindowAnimator; @@ -54,6 +57,7 @@ import android.os.CancellationSignal; import android.os.Handler; import android.os.Looper; import android.util.Pair; +import android.util.Property; import android.view.View; import android.view.ViewGroup; @@ -115,12 +119,20 @@ public class LauncherAppTransitionManagerImpl extends LauncherAppTransitionManag public static final int RECENTS_LAUNCH_DURATION = 336; public static final int RECENTS_QUICKSCRUB_LAUNCH_DURATION = 300; - private static final int LAUNCHER_RESUME_START_DELAY = 100; + private static final int LAUNCHER_RESUME_START_DELAY = 40; private static final int CLOSING_TRANSITION_DURATION_MS = 250; // Progress = 0: All apps is fully pulled up, Progress = 1: All apps is fully pulled down. public static final float ALL_APPS_PROGRESS_OFF_SCREEN = 1.3059858f; + private static final int APP_CLOSE_ROW_START_DELAY_MS = 8; + + // The sum of [slide, oscillate, and settle] should be <= LAUNCHER_RESUME_TOTAL_DURATION. + private static final int LAUNCHER_RESUME_TOTAL_DURATION = 346; + private static final int SPRING_SLIDE_DURATION = 166; + private static final int SPRING_OSCILLATE_DURATION = 130; + private static final int SPRING_SETTLE_DURATION = 50; + private final Launcher mLauncher; private final DragLayer mDragLayer; private final AlphaProperty mDragLayerAlpha; @@ -129,7 +141,8 @@ public class LauncherAppTransitionManagerImpl extends LauncherAppTransitionManag private final boolean mIsRtl; private final float mContentTransY; - private final float mWorkspaceTransY; + private final float mStartSlideTransY; + private final float mEndSlideTransY; private final float mClosingWindowTransY; private DeviceProfile mDeviceProfile; @@ -159,8 +172,9 @@ public class LauncherAppTransitionManagerImpl extends LauncherAppTransitionManag Resources res = mLauncher.getResources(); mContentTransY = res.getDimensionPixelSize(R.dimen.content_trans_y); - mWorkspaceTransY = res.getDimensionPixelSize(R.dimen.workspace_trans_y); mClosingWindowTransY = res.getDimensionPixelSize(R.dimen.closing_window_trans_y); + mStartSlideTransY = res.getDimensionPixelSize(R.dimen.springs_trans_y); + mEndSlideTransY = -mStartSlideTransY * 0.1f; mLauncher.addOnDeviceProfileChangeListener(this); registerRemoteAnimations(); @@ -195,7 +209,7 @@ public class LauncherAppTransitionManagerImpl extends LauncherAppTransitionManag mLauncher.getStateManager().setCurrentAnimation(anim); Rect windowTargetBounds = getWindowTargetBounds(targetCompats); - anim.play(getIconAnimator(v, windowTargetBounds)); + playIconAnimators(anim, v, windowTargetBounds); if (launcherClosing) { Pair<AnimatorSet, Runnable> launcherContentAnimator = getLauncherContentAnimator(true /* isAppOpening */); @@ -420,9 +434,9 @@ public class LauncherAppTransitionManagerImpl extends LauncherAppTransitionManag } /** - * @return Animator that controls the icon used to launch the target. + * Animators for the "floating view" of the view used to launch the target. */ - private AnimatorSet getIconAnimator(View v, Rect windowTargetBounds) { + private void playIconAnimators(AnimatorSet appOpenAnimator, View v, Rect windowTargetBounds) { final boolean isBubbleTextView = v instanceof BubbleTextView; mFloatingView = new View(mLauncher); if (isBubbleTextView && v.getTag() instanceof ItemInfoWithIcon ) { @@ -477,7 +491,6 @@ public class LauncherAppTransitionManagerImpl extends LauncherAppTransitionManag ((ViewGroup) mDragLayer.getParent()).addView(mFloatingView); v.setVisibility(View.INVISIBLE); - AnimatorSet appIconAnimatorSet = new AnimatorSet(); int[] dragLayerBounds = new int[2]; mDragLayer.getLocationOnScreen(dragLayerBounds); @@ -507,8 +520,8 @@ public class LauncherAppTransitionManagerImpl extends LauncherAppTransitionManag } x.setInterpolator(AGGRESSIVE_EASE); y.setInterpolator(AGGRESSIVE_EASE); - appIconAnimatorSet.play(x); - appIconAnimatorSet.play(y); + appOpenAnimator.play(x); + appOpenAnimator.play(y); // Scale the app icon to take up the entire screen. This simplifies the math when // animating the app window position / scale. @@ -519,7 +532,7 @@ public class LauncherAppTransitionManagerImpl extends LauncherAppTransitionManag .ofFloat(mFloatingView, SCALE_PROPERTY, startScale, scale); scaleAnim.setDuration(APP_LAUNCH_DURATION) .setInterpolator(Interpolators.EXAGGERATED_EASE); - appIconAnimatorSet.play(scaleAnim); + appOpenAnimator.play(scaleAnim); // Fade out the app icon. ObjectAnimator alpha = ObjectAnimator.ofFloat(mFloatingView, View.ALPHA, 1f, 0f); @@ -532,9 +545,9 @@ public class LauncherAppTransitionManagerImpl extends LauncherAppTransitionManag alpha.setDuration((long) (APP_LAUNCH_DOWN_DUR_SCALE_FACTOR * APP_LAUNCH_ALPHA_DURATION)); } alpha.setInterpolator(LINEAR); - appIconAnimatorSet.play(alpha); + appOpenAnimator.play(alpha); - appIconAnimatorSet.addListener(new AnimatorListenerAdapter() { + appOpenAnimator.addListener(new AnimatorListenerAdapter() { @Override public void onAnimationEnd(Animator animation) { // Reset launcher to normal state @@ -542,7 +555,6 @@ public class LauncherAppTransitionManagerImpl extends LauncherAppTransitionManag ((ViewGroup) mDragLayer.getParent()).removeView(mFloatingView); } }); - return appIconAnimatorSet; } /** @@ -774,25 +786,33 @@ public class LauncherAppTransitionManagerImpl extends LauncherAppTransitionManag }); } else { AnimatorSet workspaceAnimator = new AnimatorSet(); + workspaceAnimator.setStartDelay(LAUNCHER_RESUME_START_DELAY); - mDragLayer.setTranslationY(-mWorkspaceTransY);; - workspaceAnimator.play(ObjectAnimator.ofFloat(mDragLayer, View.TRANSLATION_Y, - -mWorkspaceTransY, 0)); + ShortcutAndWidgetContainer currentPage = ((CellLayout) mLauncher.getWorkspace() + .getChildAt(mLauncher.getWorkspace().getCurrentPage())) + .getShortcutsAndWidgets(); - mDragLayerAlpha.setValue(0); - workspaceAnimator.play(ObjectAnimator.ofFloat( - mDragLayerAlpha, MultiValueAlpha.VALUE, 0, 1f)); + // Set up springs on workspace items. + for (int i = currentPage.getChildCount() - 1; i >= 0; i--) { + View child = currentPage.getChildAt(i); + CellLayout.LayoutParams lp = ((CellLayout.LayoutParams) child.getLayoutParams()); + addStaggeredAnimationForView(child, workspaceAnimator, lp.cellY + lp.cellVSpan); + } - workspaceAnimator.setStartDelay(LAUNCHER_RESUME_START_DELAY); - workspaceAnimator.setDuration(333); - workspaceAnimator.setInterpolator(Interpolators.DEACCEL_1_7); + // Set up a spring for the shelf. + if (!mLauncher.getDeviceProfile().isVerticalBarLayout()) { + AllAppsTransitionController allAppsController = mLauncher.getAllAppsController(); + float shiftRange = allAppsController.getShiftRange(); + float slideStart = shiftRange / (shiftRange - mStartSlideTransY); + float oscillateStart = shiftRange / (shiftRange - mEndSlideTransY); - mDragLayer.getScrim().hideSysUiScrim(true); + buildSpringAnimation(workspaceAnimator, allAppsController, ALL_APPS_PROGRESS, + 0 /* startDelay */, slideStart, oscillateStart, 1f /* finalPosition */); + } + mDragLayer.getScrim().hideSysUiScrim(true); // Pause page indicator animations as they lead to layer trashing. mLauncher.getWorkspace().getPageIndicator().pauseAnimations(); - mDragLayer.setLayerType(View.LAYER_TYPE_HARDWARE, null); - workspaceAnimator.addListener(new AnimatorListenerAdapter() { @Override public void onAnimationEnd(Animator animation) { @@ -803,6 +823,66 @@ public class LauncherAppTransitionManagerImpl extends LauncherAppTransitionManag } } + /** + * Adds an alpha/trans animator for {@param v}, with a start delay based on the view's row. + * + * @param v View in a ShortcutAndWidgetContainer. + * @param row The bottom-most row that contains the view. + */ + private void addStaggeredAnimationForView(View v, AnimatorSet outAnimator, int row) { + // Invert the rows, because we stagger starting from the bottom of the screen. + int invertedRow = LauncherAppState.getIDP(mLauncher).numRows - row + 1; + long startDelay = (long) (invertedRow * APP_CLOSE_ROW_START_DELAY_MS); + + v.setAlpha(0); + ObjectAnimator alpha = ObjectAnimator.ofFloat(v, View.ALPHA, 1f); + alpha.setInterpolator(LINEAR); + alpha.setDuration(SPRING_SLIDE_DURATION + SPRING_OSCILLATE_DURATION); + alpha.setStartDelay(startDelay); + outAnimator.play(alpha); + + buildSpringAnimation(outAnimator, v, TRANSLATION_Y, startDelay, mStartSlideTransY, + mEndSlideTransY, 0f /* finalPosition */); + + outAnimator.addListener(new AnimatorListenerAdapter() { + @Override + public void onAnimationEnd(Animator animation) { + v.setAlpha(1f); + v.setTranslationY(0); + } + }); + } + + /** + * Spring animations consists of three sequential animators: a slide, an oscillation, and + * a settle. + */ + private <T> void buildSpringAnimation(AnimatorSet outAnimator, T objectToSpring, + Property<T, Float> property, long startDelay, float slideStart, float oscillateStart, + float finalPosition) { + // Ensures a clean hand-off between slide and oscillate. + float slideEnd = Utilities.mapToRange(0, 0, 1f, oscillateStart, finalPosition, OSCILLATE); + + property.set(objectToSpring, slideStart); + + ObjectAnimator slideIn = ObjectAnimator.ofFloat(objectToSpring, property, slideStart, + slideEnd); + slideIn.setInterpolator(DEACCEL); + slideIn.setStartDelay(startDelay); + slideIn.setDuration(SPRING_SLIDE_DURATION); + + ObjectAnimator oscillate = ObjectAnimator.ofFloat(objectToSpring, property, oscillateStart, + finalPosition); + oscillate.setInterpolator(OSCILLATE); + oscillate.setDuration(SPRING_OSCILLATE_DURATION); + + ObjectAnimator settle = ObjectAnimator.ofFloat(objectToSpring, property, finalPosition); + settle.setInterpolator(LINEAR); + settle.setDuration(SPRING_SETTLE_DURATION); + + outAnimator.playSequentially(slideIn, oscillate, settle); + } + private void resetContentView() { mLauncher.getWorkspace().getPageIndicator().skipAnimationsToEnd(); mDragLayerAlpha.setValue(1f); diff --git a/quickstep/src/com/android/launcher3/uioverrides/OverviewState.java b/quickstep/src/com/android/launcher3/uioverrides/OverviewState.java index 1e1031958..7f956f8a2 100644 --- a/quickstep/src/com/android/launcher3/uioverrides/OverviewState.java +++ b/quickstep/src/com/android/launcher3/uioverrides/OverviewState.java @@ -29,6 +29,7 @@ import com.android.launcher3.R; import com.android.launcher3.Workspace; import com.android.launcher3.allapps.DiscoveryBounce; import com.android.launcher3.userevent.nano.LauncherLogProto.ContainerType; +import com.android.quickstep.RecentsModel; import com.android.quickstep.views.RecentsView; /** @@ -76,6 +77,7 @@ public class OverviewState extends LauncherState { public void onStateDisabled(Launcher launcher) { RecentsView rv = launcher.getOverviewPanel(); rv.setOverviewStateEnabled(false); + RecentsModel.getInstance(launcher).resetAssistCache(); } @Override diff --git a/quickstep/src/com/android/launcher3/uioverrides/PortraitStatesTouchController.java b/quickstep/src/com/android/launcher3/uioverrides/PortraitStatesTouchController.java index 512d19af7..0eead8883 100644 --- a/quickstep/src/com/android/launcher3/uioverrides/PortraitStatesTouchController.java +++ b/quickstep/src/com/android/launcher3/uioverrides/PortraitStatesTouchController.java @@ -18,7 +18,11 @@ package com.android.launcher3.uioverrides; import static com.android.launcher3.LauncherState.ALL_APPS; import static com.android.launcher3.LauncherState.NORMAL; import static com.android.launcher3.LauncherState.OVERVIEW; +import static com.android.launcher3.anim.AnimatorSetBuilder.ANIM_ALL_APPS_FADE; +import static com.android.launcher3.anim.AnimatorSetBuilder.ANIM_OVERVIEW_FADE; import static com.android.launcher3.anim.AnimatorSetBuilder.ANIM_VERTICAL_PROGRESS; +import static com.android.launcher3.anim.Interpolators.ACCEL; +import static com.android.launcher3.anim.Interpolators.DEACCEL; import static com.android.launcher3.anim.Interpolators.LINEAR; import android.animation.TimeInterpolator; @@ -31,6 +35,7 @@ import com.android.launcher3.DeviceProfile; import com.android.launcher3.Launcher; import com.android.launcher3.LauncherState; import com.android.launcher3.LauncherStateManager.AnimationComponents; +import com.android.launcher3.allapps.AllAppsTransitionController; import com.android.launcher3.anim.AnimatorPlaybackController; import com.android.launcher3.anim.AnimatorSetBuilder; import com.android.launcher3.anim.Interpolators; @@ -50,6 +55,16 @@ public class PortraitStatesTouchController extends AbstractStateChangeTouchContr private static final String TAG = "PortraitStatesTouchCtrl"; + /** + * The progress at which all apps content will be fully visible when swiping up from overview. + */ + private static final float ALL_APPS_CONTENT_FADE_THRESHOLD = 0.08f; + + /** + * The progress at which recents will begin fading out when swiping up from overview. + */ + private static final float RECENTS_FADE_THRESHOLD = 0.88f; + private InterpolatorWrapper mAllAppsInterpolatorWrapper = new InterpolatorWrapper(); // If true, we will finish the current animation instantly on second touch. @@ -68,8 +83,18 @@ public class PortraitStatesTouchController extends AbstractStateChangeTouchContr mCurrentAnimation.getAnimationPlayer().end(); } - // If we are already animating from a previous state, we can intercept. - return true; + AllAppsTransitionController allAppsController = mLauncher.getAllAppsController(); + if (ev.getY() >= allAppsController.getShiftRange() * allAppsController.getProgress()) { + // If we are already animating from a previous state, we can intercept as long as + // the touch is below the current all apps progress (to allow for double swipe). + return true; + } + // Otherwise, make sure everything is settled and don't intercept so they can scroll + // recents, dismiss a task, etc. + if (mAtomicAnim != null) { + mAtomicAnim.end(); + } + return false; } if (mLauncher.isInState(ALL_APPS)) { // In all-apps only listen if the container cannot scroll itself @@ -114,7 +139,38 @@ public class PortraitStatesTouchController extends AbstractStateChangeTouchContr AnimatorSetBuilder builder = new AnimatorSetBuilder(); builder.setInterpolator(ANIM_VERTICAL_PROGRESS, mAllAppsInterpolatorWrapper); + return builder; + } + + public static AnimatorSetBuilder getOverviewToAllAppsAnimation() { + AnimatorSetBuilder builder = new AnimatorSetBuilder(); + builder.setInterpolator(ANIM_ALL_APPS_FADE, Interpolators.clampToProgress(ACCEL, + 0, ALL_APPS_CONTENT_FADE_THRESHOLD)); + builder.setInterpolator(ANIM_OVERVIEW_FADE, Interpolators.clampToProgress(DEACCEL, + RECENTS_FADE_THRESHOLD, 1)); + return builder; + } + private AnimatorSetBuilder getAllAppsToOverviewAnimation() { + AnimatorSetBuilder builder = new AnimatorSetBuilder(); + builder.setInterpolator(ANIM_ALL_APPS_FADE, Interpolators.clampToProgress(DEACCEL, + 1 - ALL_APPS_CONTENT_FADE_THRESHOLD, 1)); + builder.setInterpolator(ANIM_OVERVIEW_FADE, Interpolators.clampToProgress(ACCEL, + 0f, 1 - RECENTS_FADE_THRESHOLD)); + return builder; + } + + @Override + protected AnimatorSetBuilder getAnimatorSetBuilderForStates(LauncherState fromState, + LauncherState toState) { + AnimatorSetBuilder builder = new AnimatorSetBuilder(); + if (fromState == NORMAL && toState == OVERVIEW) { + builder = getNormalToOverviewAnimation(); + } else if (fromState == OVERVIEW && toState == ALL_APPS) { + builder = getOverviewToAllAppsAnimation(); + } else if (fromState == ALL_APPS && toState == OVERVIEW) { + builder = getAllAppsToOverviewAnimation(); + } return builder; } @@ -128,13 +184,8 @@ public class PortraitStatesTouchController extends AbstractStateChangeTouchContr float totalShift = endVerticalShift - startVerticalShift; - final AnimatorSetBuilder builder; - - if (mFromState == NORMAL && mToState == OVERVIEW && totalShift != 0) { - builder = getNormalToOverviewAnimation(); - } else { - builder = new AnimatorSetBuilder(); - } + final AnimatorSetBuilder builder = totalShift == 0 ? new AnimatorSetBuilder() + : getAnimatorSetBuilderForStates(mFromState, mToState); cancelPendingAnim(); diff --git a/quickstep/src/com/android/quickstep/LongSwipeHelper.java b/quickstep/src/com/android/quickstep/LongSwipeHelper.java index 336be2bd8..078509330 100644 --- a/quickstep/src/com/android/quickstep/LongSwipeHelper.java +++ b/quickstep/src/com/android/quickstep/LongSwipeHelper.java @@ -25,10 +25,13 @@ import android.animation.ValueAnimator; import com.android.launcher3.Launcher; import com.android.launcher3.LauncherAnimUtils; +import com.android.launcher3.LauncherStateManager; import com.android.launcher3.R; import com.android.launcher3.allapps.AllAppsTransitionController; import com.android.launcher3.allapps.DiscoveryBounce; import com.android.launcher3.anim.AnimatorPlaybackController; +import com.android.launcher3.anim.AnimatorSetBuilder; +import com.android.launcher3.uioverrides.PortraitStatesTouchController; import com.android.launcher3.userevent.nano.LauncherLogProto.Action.Direction; import com.android.launcher3.userevent.nano.LauncherLogProto.Action.Touch; import com.android.launcher3.userevent.nano.LauncherLogProto.ContainerType; @@ -67,8 +70,10 @@ public class LongSwipeHelper { AllAppsTransitionController controller = mLauncher.getAllAppsController(); // TODO: Scale it down so that we can reach all-apps in screen space mMaxSwipeDistance = Math.max(1, controller.getProgress() * controller.getShiftRange()); - mAnimator = mLauncher.getStateManager() - .createAnimationToNewWorkspace(ALL_APPS, Math.round(2 * mMaxSwipeDistance)); + + AnimatorSetBuilder builder = PortraitStatesTouchController.getOverviewToAllAppsAnimation(); + mAnimator = mLauncher.getStateManager().createAnimationToNewWorkspace(ALL_APPS, builder, + Math.round(2 * mMaxSwipeDistance), null, LauncherStateManager.ANIM_ALL); mAnimator.dispatchOnStart(); } diff --git a/quickstep/src/com/android/quickstep/OtherActivityTouchConsumer.java b/quickstep/src/com/android/quickstep/OtherActivityTouchConsumer.java index c85628263..0e811f771 100644 --- a/quickstep/src/com/android/quickstep/OtherActivityTouchConsumer.java +++ b/quickstep/src/com/android/quickstep/OtherActivityTouchConsumer.java @@ -78,6 +78,7 @@ public class OtherActivityTouchConsumer extends ContextWrapper implements TouchC private final MainThreadExecutor mMainThreadExecutor; private final Choreographer mBackgroundThreadChoreographer; private final OverviewCallbacks mOverviewCallbacks; + private final TaskOverlayFactory mTaskOverlayFactory; private final boolean mIsDeferredDownTarget; private final PointF mDownPos = new PointF(); @@ -99,7 +100,7 @@ public class OtherActivityTouchConsumer extends ContextWrapper implements TouchC RecentsModel recentsModel, Intent homeIntent, ActivityControlHelper activityControl, MainThreadExecutor mainThreadExecutor, Choreographer backgroundThreadChoreographer, @HitTarget int downHitTarget, OverviewCallbacks overviewCallbacks, - VelocityTracker velocityTracker) { + TaskOverlayFactory taskOverlayFactory, VelocityTracker velocityTracker) { super(base); mRunningTask = runningTaskInfo; @@ -111,6 +112,7 @@ public class OtherActivityTouchConsumer extends ContextWrapper implements TouchC mBackgroundThreadChoreographer = backgroundThreadChoreographer; mIsDeferredDownTarget = activityControl.deferStartingActivity(downHitTarget); mOverviewCallbacks = overviewCallbacks; + mTaskOverlayFactory = taskOverlayFactory; } @Override @@ -233,14 +235,22 @@ public class OtherActivityTouchConsumer extends ContextWrapper implements TouchC handler.initWhenReady(); TraceHelper.beginSection("RecentsController"); - Runnable startActivity = () -> ActivityManagerWrapper.getInstance().startRecentsActivity( - mHomeIntent, + + AssistDataReceiver assistDataReceiver = !mTaskOverlayFactory.needAssist() ? null : new AssistDataReceiver() { @Override public void onHandleAssistData(Bundle bundle) { - mRecentsModel.preloadAssistData(mRunningTask.id, bundle); + if (mInteractionHandler == null) { + // Interaction is probably complete + mRecentsModel.preloadAssistData(mRunningTask.id, bundle); + } else if (handler == mInteractionHandler) { + handler.onAssistDataReceived(bundle); + } } - }, animationState, null, null); + }; + + Runnable startActivity = () -> ActivityManagerWrapper.getInstance().startRecentsActivity( + mHomeIntent, assistDataReceiver, animationState, null, null); if (Looper.myLooper() != Looper.getMainLooper()) { startActivity.run(); diff --git a/quickstep/src/com/android/quickstep/RecentsModel.java b/quickstep/src/com/android/quickstep/RecentsModel.java index 9c2c8b313..0c8e47f2b 100644 --- a/quickstep/src/com/android/quickstep/RecentsModel.java +++ b/quickstep/src/com/android/quickstep/RecentsModel.java @@ -256,6 +256,10 @@ public class RecentsModel extends TaskStackChangeListener { } } + public void resetAssistCache() { + mCachedAssistData.clear(); + } + @WorkerThread public void preloadAssistData(int taskId, Bundle data) { mMainThreadExecutor.execute(() -> { diff --git a/quickstep/src/com/android/quickstep/TaskOverlayFactory.java b/quickstep/src/com/android/quickstep/TaskOverlayFactory.java index 66969c65a..9d3ac6af6 100644 --- a/quickstep/src/com/android/quickstep/TaskOverlayFactory.java +++ b/quickstep/src/com/android/quickstep/TaskOverlayFactory.java @@ -18,6 +18,7 @@ package com.android.quickstep; import android.content.Context; import android.graphics.Matrix; +import android.support.annotation.AnyThread; import android.view.View; import com.android.launcher3.R; @@ -42,6 +43,11 @@ public class TaskOverlayFactory { return sInstance; } + @AnyThread + public boolean needAssist() { + return false; + } + public TaskOverlay createOverlay(View thumbnailView) { return new TaskOverlay(); } diff --git a/quickstep/src/com/android/quickstep/TouchInteractionService.java b/quickstep/src/com/android/quickstep/TouchInteractionService.java index 49a4ac8ba..6c542628e 100644 --- a/quickstep/src/com/android/quickstep/TouchInteractionService.java +++ b/quickstep/src/com/android/quickstep/TouchInteractionService.java @@ -171,6 +171,7 @@ public class TouchInteractionService extends Service { private OverviewCommandHelper mOverviewCommandHelper; private OverviewInteractionState mOverviewInteractionState; private OverviewCallbacks mOverviewCallbacks; + private TaskOverlayFactory mTaskOverlayFactory; private Choreographer mMainThreadChoreographer; private Choreographer mBackgroundThreadChoreographer; @@ -187,6 +188,7 @@ public class TouchInteractionService extends Service { mEventQueue = new MotionEventQueue(mMainThreadChoreographer, mNoOpTouchConsumer); mOverviewInteractionState = OverviewInteractionState.getInstance(this); mOverviewCallbacks = OverviewCallbacks.get(this); + mTaskOverlayFactory = TaskOverlayFactory.get(this); sConnected = true; @@ -239,7 +241,7 @@ public class TouchInteractionService extends Service { mOverviewCommandHelper.overviewIntent, mOverviewCommandHelper.getActivityControlHelper(), mMainThreadExecutor, mBackgroundThreadChoreographer, downHitTarget, mOverviewCallbacks, - tracker); + mTaskOverlayFactory, tracker); } } diff --git a/quickstep/src/com/android/quickstep/WindowTransformSwipeHandler.java b/quickstep/src/com/android/quickstep/WindowTransformSwipeHandler.java index 703ea2ea2..ff3137d44 100644 --- a/quickstep/src/com/android/quickstep/WindowTransformSwipeHandler.java +++ b/quickstep/src/com/android/quickstep/WindowTransformSwipeHandler.java @@ -37,6 +37,7 @@ import android.graphics.Canvas; import android.graphics.Point; import android.graphics.Rect; import android.os.Build; +import android.os.Bundle; import android.os.Handler; import android.os.Looper; import android.os.SystemClock; @@ -109,19 +110,21 @@ public class WindowTransformSwipeHandler<T extends BaseDraggingActivity> { private static final int STATE_SCALED_CONTROLLER_APP = 1 << 6; private static final int STATE_HANDLER_INVALIDATED = 1 << 7; - private static final int STATE_GESTURE_STARTED = 1 << 8; - private static final int STATE_GESTURE_CANCELLED = 1 << 9; - private static final int STATE_GESTURE_COMPLETED = 1 << 10; + private static final int STATE_GESTURE_STARTED_QUICKSTEP = 1 << 8; + private static final int STATE_GESTURE_STARTED_QUICKSCRUB = 1 << 9; + private static final int STATE_GESTURE_CANCELLED = 1 << 10; + private static final int STATE_GESTURE_COMPLETED = 1 << 11; // States for quick switch/scrub - private static final int STATE_CURRENT_TASK_FINISHED = 1 << 11; - private static final int STATE_QUICK_SCRUB_START = 1 << 12; - private static final int STATE_QUICK_SCRUB_END = 1 << 13; + private static final int STATE_CURRENT_TASK_FINISHED = 1 << 12; + private static final int STATE_QUICK_SCRUB_START = 1 << 13; + private static final int STATE_QUICK_SCRUB_END = 1 << 14; - private static final int STATE_CAPTURE_SCREENSHOT = 1 << 14; - private static final int STATE_SCREENSHOT_CAPTURED = 1 << 15; + private static final int STATE_CAPTURE_SCREENSHOT = 1 << 15; + private static final int STATE_SCREENSHOT_CAPTURED = 1 << 16; - private static final int STATE_RESUME_LAST_TASK = 1 << 16; + private static final int STATE_RESUME_LAST_TASK = 1 << 17; + private static final int STATE_ASSIST_DATA_RECEIVED = 1 << 18; private static final int LAUNCHER_UI_STATES = STATE_LAUNCHER_PRESENT | STATE_LAUNCHER_DRAWN | STATE_ACTIVITY_MULTIPLIER_COMPLETE @@ -145,7 +148,8 @@ public class WindowTransformSwipeHandler<T extends BaseDraggingActivity> { "STATE_SCALED_CONTROLLER_RECENTS", "STATE_SCALED_CONTROLLER_APP", "STATE_HANDLER_INVALIDATED", - "STATE_GESTURE_STARTED", + "STATE_GESTURE_STARTED_QUICKSTEP", + "STATE_GESTURE_STARTED_QUICKSCRUB", "STATE_GESTURE_CANCELLED", "STATE_GESTURE_COMPLETED", "STATE_CURRENT_TASK_FINISHED", @@ -154,6 +158,7 @@ public class WindowTransformSwipeHandler<T extends BaseDraggingActivity> { "STATE_CAPTURE_SCREENSHOT", "STATE_SCREENSHOT_CAPTURED", "STATE_RESUME_LAST_TASK", + "STATE_ASSIST_DATA_RECEIVED", }; public static final long MAX_SWIPE_DURATION = 350; @@ -227,6 +232,8 @@ public class WindowTransformSwipeHandler<T extends BaseDraggingActivity> { private float mLongSwipeDisplacement = 0; private LongSwipeHelper mLongSwipeController; + private Bundle mAssistData; + WindowTransformSwipeHandler(int id, RunningTaskInfo runningTaskInfo, Context context, long touchTimeMs, ActivityControlHelper<T> controller) { this.id = id; @@ -253,12 +260,19 @@ public class WindowTransformSwipeHandler<T extends BaseDraggingActivity> { } }; - mStateCallback.addCallback(STATE_LAUNCHER_DRAWN | STATE_GESTURE_STARTED, + mStateCallback.addCallback(STATE_LAUNCHER_DRAWN | STATE_GESTURE_STARTED_QUICKSCRUB, + this::initializeLauncherAnimationController); + mStateCallback.addCallback(STATE_LAUNCHER_DRAWN | STATE_GESTURE_STARTED_QUICKSTEP, this::initializeLauncherAnimationController); + mStateCallback.addCallback(STATE_LAUNCHER_PRESENT | STATE_LAUNCHER_DRAWN, this::launcherFrameDrawn); - mStateCallback.addCallback(STATE_LAUNCHER_PRESENT | STATE_GESTURE_STARTED, + + mStateCallback.addCallback(STATE_LAUNCHER_PRESENT | STATE_GESTURE_STARTED_QUICKSTEP, this::notifyGestureStartedAsync); + mStateCallback.addCallback(STATE_LAUNCHER_PRESENT | STATE_GESTURE_STARTED_QUICKSCRUB, + this::notifyGestureStartedAsync); + mStateCallback.addCallback(STATE_LAUNCHER_PRESENT | STATE_LAUNCHER_STARTED | STATE_GESTURE_CANCELLED, this::resetStateForAnimationCancel); @@ -281,11 +295,15 @@ public class WindowTransformSwipeHandler<T extends BaseDraggingActivity> { this::finishCurrentTransitionToHome); mStateCallback.addCallback(STATE_LAUNCHER_PRESENT | STATE_APP_CONTROLLER_RECEIVED - | STATE_ACTIVITY_MULTIPLIER_COMPLETE - | STATE_SCALED_CONTROLLER_RECENTS - | STATE_CURRENT_TASK_FINISHED - | STATE_GESTURE_COMPLETED, + | STATE_ACTIVITY_MULTIPLIER_COMPLETE | STATE_SCALED_CONTROLLER_RECENTS + | STATE_CURRENT_TASK_FINISHED | STATE_GESTURE_COMPLETED + | STATE_GESTURE_STARTED_QUICKSTEP, this::setupLauncherUiAfterSwipeUpAnimation); + mStateCallback.addCallback(STATE_LAUNCHER_PRESENT | STATE_APP_CONTROLLER_RECEIVED + | STATE_ACTIVITY_MULTIPLIER_COMPLETE | STATE_SCALED_CONTROLLER_RECENTS + | STATE_CURRENT_TASK_FINISHED | STATE_GESTURE_COMPLETED + | STATE_GESTURE_STARTED_QUICKSTEP | STATE_ASSIST_DATA_RECEIVED, + this::preloadAssistData); mStateCallback.addCallback(STATE_HANDLER_INVALIDATED, this::invalidateHandler); mStateCallback.addCallback(STATE_LAUNCHER_PRESENT | STATE_HANDLER_INVALIDATED, @@ -641,7 +659,8 @@ public class WindowTransformSwipeHandler<T extends BaseDraggingActivity> { public void onGestureStarted() { notifyGestureStartedAsync(); - setStateOnUiThread(STATE_GESTURE_STARTED); + setStateOnUiThread(mInteractionType == INTERACTION_NORMAL + ? STATE_GESTURE_STARTED_QUICKSTEP : STATE_GESTURE_STARTED_QUICKSCRUB); mGestureStarted = true; mRecentsAnimationWrapper.hideCurrentInputMethod(); mRecentsAnimationWrapper.enableInputConsumer(); @@ -910,6 +929,9 @@ public class WindowTransformSwipeHandler<T extends BaseDraggingActivity> { return; } mQuickScrubController.onFinishedTransitionToQuickScrub(); + + mRecentsView.setRunningTaskIconScaledDown(false /* isScaledDown */, true /* animate */); + RecentsModel.getInstance(mContext).onOverviewShown(false, TAG); } public void onQuickScrubProgress(float progress) { @@ -1036,4 +1058,13 @@ public class WindowTransformSwipeHandler<T extends BaseDraggingActivity> { mClipAnimationHelper.setTaskAlphaCallback(provider); updateFinalShift(); } + + public void onAssistDataReceived(Bundle assistData) { + mAssistData = assistData; + setStateOnUiThread(STATE_ASSIST_DATA_RECEIVED); + } + + private void preloadAssistData() { + RecentsModel.getInstance(mContext).preloadAssistData(mRunningTaskId, mAssistData); + } } diff --git a/quickstep/src/com/android/quickstep/views/ClearAllButton.java b/quickstep/src/com/android/quickstep/views/ClearAllButton.java index 3911931b1..fbecd8486 100644 --- a/quickstep/src/com/android/quickstep/views/ClearAllButton.java +++ b/quickstep/src/com/android/quickstep/views/ClearAllButton.java @@ -54,7 +54,7 @@ public class ClearAllButton extends Button implements PageCallbacks { public void setContentAlpha(float alpha) { if (mContentAlpha != alpha) { mContentAlpha = alpha; - setAlpha(mScrollAlpha * mContentAlpha); + updateAlpha(); } } @@ -68,6 +68,12 @@ public class ClearAllButton extends Button implements PageCallbacks { float shift = Math.min(scrollState.scrollFromEdge, width); setTranslationX(mIsRtl ? (mScrollOffset - shift) : (mScrollOffset + shift)); mScrollAlpha = 1 - shift / width; - setAlpha(mScrollAlpha * mContentAlpha); + updateAlpha(); + } + + private void updateAlpha() { + final float alpha = mScrollAlpha * mContentAlpha; + setAlpha(alpha); + setClickable(alpha == 1); } } diff --git a/quickstep/src/com/android/quickstep/views/ShelfScrimView.java b/quickstep/src/com/android/quickstep/views/ShelfScrimView.java index d7e527c7c..8b5e83245 100644 --- a/quickstep/src/com/android/quickstep/views/ShelfScrimView.java +++ b/quickstep/src/com/android/quickstep/views/ShelfScrimView.java @@ -16,7 +16,6 @@ package com.android.quickstep.views; import static android.support.v4.graphics.ColorUtils.setAlphaComponent; - import static com.android.launcher3.LauncherState.OVERVIEW; import static com.android.launcher3.anim.Interpolators.ACCEL; import static com.android.launcher3.anim.Interpolators.LINEAR; @@ -33,6 +32,7 @@ import android.util.AttributeSet; import com.android.launcher3.DeviceProfile; import com.android.launcher3.R; import com.android.launcher3.Utilities; +import com.android.launcher3.anim.Interpolators; import com.android.launcher3.util.Themes; import com.android.launcher3.views.ScrimView; @@ -55,7 +55,7 @@ public class ShelfScrimView extends ScrimView { // For shelf mode private final int mEndAlpha; private final float mRadius; - private final float mMaxScrimAlpha; + private final int mMaxScrimAlpha; private final Paint mPaint; // Mid point where the alpha changes @@ -78,7 +78,7 @@ public class ShelfScrimView extends ScrimView { public ShelfScrimView(Context context, AttributeSet attrs) { super(context, attrs); - mMaxScrimAlpha = OVERVIEW.getWorkspaceScrimAlpha(mLauncher); + mMaxScrimAlpha = Math.round(OVERVIEW.getWorkspaceScrimAlpha(mLauncher) * 255); mEndAlpha = Color.alpha(mEndScrim); mRadius = mLauncher.getResources().getDimension(R.dimen.shelf_surface_radius); @@ -144,9 +144,10 @@ public class ShelfScrimView extends ScrimView { } else { mDragHandleOffset += mShiftRange * (mMidProgress - mProgress); + // Note that these ranges and interpolators are inverted because progress goes 1 to 0. int alpha = Math.round( Utilities.mapToRange(mProgress, (float) 0, mMidProgress, (float) mEndAlpha, - (float) mMidAlpha, LINEAR)); + (float) mMidAlpha, Interpolators.clampToProgress(ACCEL, 0.5f, 1f))); mShelfColor = setAlphaComponent(mEndScrim, alpha); int remainingScrimAlpha = Math.round( |