Loading quickstep/recents_ui_overrides/src/com/android/quickstep/WindowTransformSwipeHandler.java +3 −1 Original line number Diff line number Diff line Loading @@ -415,6 +415,7 @@ public class WindowTransformSwipeHandler<T extends BaseDraggingActivity> }); mRecentsView.setRecentsAnimationWrapper(mRecentsAnimationWrapper); mRecentsView.setClipAnimationHelper(mClipAnimationHelper); mRecentsView.setLiveTileOverlay(mLiveTileOverlay); mActivity.getRootView().getOverlay().add(mLiveTileOverlay); mStateCallback.setState(STATE_LAUNCHER_PRESENT); Loading Loading @@ -822,6 +823,7 @@ public class WindowTransformSwipeHandler<T extends BaseDraggingActivity> setShelfState(ShelfAnimState.CANCEL, LINEAR, 0); duration = Math.max(MIN_OVERSHOOT_DURATION, duration); } else if (endTarget == RECENTS) { mLiveTileOverlay.startIconAnimation(); mRecentsAnimationWrapper.enableInputProxy(); if (mRecentsView != null) { duration = Math.max(duration, mRecentsView.getScroller().getDuration()); Loading Loading @@ -1172,7 +1174,7 @@ public class WindowTransformSwipeHandler<T extends BaseDraggingActivity> mActivityControlHelper.onSwipeUpComplete(mActivity); // Animate the first icon. mRecentsView.animateUpRunningTaskIconScale(); mRecentsView.animateUpRunningTaskIconScale(mLiveTileOverlay.cancelIconAnimation()); mRecentsView.setSwipeDownShouldLaunchApp(true); RecentsModel.INSTANCE.get(mContext).onOverviewShown(false, TAG); Loading quickstep/recents_ui_overrides/src/com/android/quickstep/views/LiveTileOverlay.java +69 −0 Original line number Diff line number Diff line package com.android.quickstep.views; import static com.android.launcher3.anim.Interpolators.FAST_OUT_SLOW_IN; import static com.android.launcher3.anim.Interpolators.LINEAR; import android.animation.Animator; import android.animation.AnimatorListenerAdapter; import android.animation.ObjectAnimator; import android.graphics.Canvas; import android.graphics.ColorFilter; import android.graphics.Paint; Loading @@ -9,16 +15,37 @@ import android.graphics.PorterDuffXfermode; import android.graphics.Rect; import android.graphics.RectF; import android.graphics.drawable.Drawable; import android.util.FloatProperty; import com.android.launcher3.anim.Interpolators; public class LiveTileOverlay extends Drawable { private static final long ICON_ANIM_DURATION = 120; private static final FloatProperty<LiveTileOverlay> PROGRESS = new FloatProperty<LiveTileOverlay>("progress") { @Override public void setValue(LiveTileOverlay liveTileOverlay, float progress) { liveTileOverlay.setIconAnimationProgress(progress); } @Override public Float get(LiveTileOverlay liveTileOverlay) { return liveTileOverlay.mIconAnimationProgress; } }; private final Paint mPaint = new Paint(); private Rect mBoundsRect = new Rect(); private RectF mCurrentRect; private float mCornerRadius; private Drawable mIcon; private Animator mIconAnimator; private boolean mDrawEnabled = true; private float mIconAnimationProgress = 0f; public LiveTileOverlay() { mPaint.setXfermode(new PorterDuffXfermode(PorterDuff.Mode.CLEAR)); Loading @@ -35,6 +62,33 @@ public class LiveTileOverlay extends Drawable { invalidateSelf(); } public void setIcon(Drawable icon) { mIcon = icon; } public void startIconAnimation() { if (mIconAnimator != null) { mIconAnimator.cancel(); } // This animator must match the icon part of {@link TaskView#FOCUS_TRANSITION} animation. mIconAnimator = ObjectAnimator.ofFloat(this, PROGRESS, 1); mIconAnimator.setDuration(ICON_ANIM_DURATION).setInterpolator(LINEAR); mIconAnimator.addListener(new AnimatorListenerAdapter() { @Override public void onAnimationEnd(Animator animation) { mIconAnimator = null; } }); mIconAnimator.start(); } public float cancelIconAnimation() { if (mIconAnimator != null) { mIconAnimator.cancel(); } return mIconAnimationProgress; } public void setDrawEnabled(boolean drawEnabled) { if (mDrawEnabled != drawEnabled) { mDrawEnabled = drawEnabled; Loading @@ -46,6 +100,16 @@ public class LiveTileOverlay extends Drawable { public void draw(Canvas canvas) { if (mCurrentRect != null && mDrawEnabled) { canvas.drawRoundRect(mCurrentRect, mCornerRadius, mCornerRadius, mPaint); if (mIcon != null && mIconAnimationProgress > 0f) { canvas.save(); float scale = Interpolators.clampToProgress(FAST_OUT_SLOW_IN, 0f, 1f).getInterpolation(mIconAnimationProgress); canvas.translate(mCurrentRect.centerX() - mIcon.getBounds().width() / 2 * scale, mCurrentRect.top - mIcon.getBounds().height() / 2 * scale); canvas.scale(scale, scale); mIcon.draw(canvas); canvas.restore(); } } } Loading @@ -59,4 +123,9 @@ public class LiveTileOverlay extends Drawable { public int getOpacity() { return PixelFormat.TRANSLUCENT; } private void setIconAnimationProgress(float progress) { mIconAnimationProgress = progress; invalidateSelf(); } } quickstep/recents_ui_overrides/src/com/android/quickstep/views/RecentsView.java +14 −0 Original line number Diff line number Diff line Loading @@ -278,6 +278,7 @@ public abstract class RecentsView<T extends BaseActivity> extends PagedView impl private final int mEmptyMessagePadding; private boolean mShowEmptyMessage; private Layout mEmptyTextLayout; private LiveTileOverlay mLiveTileOverlay; private BaseActivity.MultiWindowModeChangedListener mMultiWindowModeChangedListener = (inMultiWindowMode) -> { Loading Loading @@ -855,10 +856,15 @@ public abstract class RecentsView<T extends BaseActivity> extends PagedView impl } public void animateUpRunningTaskIconScale() { animateUpRunningTaskIconScale(0); } public void animateUpRunningTaskIconScale(float startProgress) { mRunningTaskIconScaledDown = false; TaskView firstTask = getRunningTaskView(); if (firstTask != null) { firstTask.animateIconScaleAndDimIntoView(); firstTask.setIconScaleAnimStartProgress(startProgress); } } Loading Loading @@ -1567,6 +1573,14 @@ public abstract class RecentsView<T extends BaseActivity> extends PagedView impl mClipAnimationHelper = clipAnimationHelper; } public void setLiveTileOverlay(LiveTileOverlay liveTileOverlay) { mLiveTileOverlay = liveTileOverlay; } public void updateLiveTileIcon(Drawable icon) { mLiveTileOverlay.setIcon(icon); } public void finishRecentsAnimation(boolean toRecents, Runnable onFinishComplete) { if (mRecentsAnimationWrapper == null) { if (onFinishComplete != null) { Loading quickstep/recents_ui_overrides/src/com/android/quickstep/views/TaskView.java +10 −1 Original line number Diff line number Diff line Loading @@ -156,7 +156,8 @@ public class TaskView extends FrameLayout implements PageCallbacks, Reusable { private float mZoomScale; private float mFullscreenProgress; private Animator mIconAndDimAnimator; private ObjectAnimator mIconAndDimAnimator; private float mIconScaleAnimStartProgress = 0; private float mFocusTransitionProgress = 1; private boolean mShowScreenshot; Loading Loading @@ -317,6 +318,9 @@ public class TaskView extends FrameLayout implements PageCallbacks, Reusable { mIconLoadRequest = iconCache.updateIconInBackground(mTask, (task) -> { setIcon(task.icon); if (isRunningTask()) { getRecentsView().updateLiveTileIcon(task.icon); } mDigitalWellBeingToast.initialize( mTask, (saturation, contentDescription) -> { Loading Loading @@ -380,11 +384,16 @@ public class TaskView extends FrameLayout implements PageCallbacks, Reusable { mIconView.setScaleY(scale); } public void setIconScaleAnimStartProgress(float startProgress) { mIconScaleAnimStartProgress = startProgress; } public void animateIconScaleAndDimIntoView() { if (mIconAndDimAnimator != null) { mIconAndDimAnimator.cancel(); } mIconAndDimAnimator = ObjectAnimator.ofFloat(this, FOCUS_TRANSITION, 1); mIconAndDimAnimator.setCurrentFraction(mIconScaleAnimStartProgress); mIconAndDimAnimator.setDuration(DIM_ANIM_DURATION).setInterpolator(LINEAR); mIconAndDimAnimator.addListener(new AnimatorListenerAdapter() { @Override Loading Loading
quickstep/recents_ui_overrides/src/com/android/quickstep/WindowTransformSwipeHandler.java +3 −1 Original line number Diff line number Diff line Loading @@ -415,6 +415,7 @@ public class WindowTransformSwipeHandler<T extends BaseDraggingActivity> }); mRecentsView.setRecentsAnimationWrapper(mRecentsAnimationWrapper); mRecentsView.setClipAnimationHelper(mClipAnimationHelper); mRecentsView.setLiveTileOverlay(mLiveTileOverlay); mActivity.getRootView().getOverlay().add(mLiveTileOverlay); mStateCallback.setState(STATE_LAUNCHER_PRESENT); Loading Loading @@ -822,6 +823,7 @@ public class WindowTransformSwipeHandler<T extends BaseDraggingActivity> setShelfState(ShelfAnimState.CANCEL, LINEAR, 0); duration = Math.max(MIN_OVERSHOOT_DURATION, duration); } else if (endTarget == RECENTS) { mLiveTileOverlay.startIconAnimation(); mRecentsAnimationWrapper.enableInputProxy(); if (mRecentsView != null) { duration = Math.max(duration, mRecentsView.getScroller().getDuration()); Loading Loading @@ -1172,7 +1174,7 @@ public class WindowTransformSwipeHandler<T extends BaseDraggingActivity> mActivityControlHelper.onSwipeUpComplete(mActivity); // Animate the first icon. mRecentsView.animateUpRunningTaskIconScale(); mRecentsView.animateUpRunningTaskIconScale(mLiveTileOverlay.cancelIconAnimation()); mRecentsView.setSwipeDownShouldLaunchApp(true); RecentsModel.INSTANCE.get(mContext).onOverviewShown(false, TAG); Loading
quickstep/recents_ui_overrides/src/com/android/quickstep/views/LiveTileOverlay.java +69 −0 Original line number Diff line number Diff line package com.android.quickstep.views; import static com.android.launcher3.anim.Interpolators.FAST_OUT_SLOW_IN; import static com.android.launcher3.anim.Interpolators.LINEAR; import android.animation.Animator; import android.animation.AnimatorListenerAdapter; import android.animation.ObjectAnimator; import android.graphics.Canvas; import android.graphics.ColorFilter; import android.graphics.Paint; Loading @@ -9,16 +15,37 @@ import android.graphics.PorterDuffXfermode; import android.graphics.Rect; import android.graphics.RectF; import android.graphics.drawable.Drawable; import android.util.FloatProperty; import com.android.launcher3.anim.Interpolators; public class LiveTileOverlay extends Drawable { private static final long ICON_ANIM_DURATION = 120; private static final FloatProperty<LiveTileOverlay> PROGRESS = new FloatProperty<LiveTileOverlay>("progress") { @Override public void setValue(LiveTileOverlay liveTileOverlay, float progress) { liveTileOverlay.setIconAnimationProgress(progress); } @Override public Float get(LiveTileOverlay liveTileOverlay) { return liveTileOverlay.mIconAnimationProgress; } }; private final Paint mPaint = new Paint(); private Rect mBoundsRect = new Rect(); private RectF mCurrentRect; private float mCornerRadius; private Drawable mIcon; private Animator mIconAnimator; private boolean mDrawEnabled = true; private float mIconAnimationProgress = 0f; public LiveTileOverlay() { mPaint.setXfermode(new PorterDuffXfermode(PorterDuff.Mode.CLEAR)); Loading @@ -35,6 +62,33 @@ public class LiveTileOverlay extends Drawable { invalidateSelf(); } public void setIcon(Drawable icon) { mIcon = icon; } public void startIconAnimation() { if (mIconAnimator != null) { mIconAnimator.cancel(); } // This animator must match the icon part of {@link TaskView#FOCUS_TRANSITION} animation. mIconAnimator = ObjectAnimator.ofFloat(this, PROGRESS, 1); mIconAnimator.setDuration(ICON_ANIM_DURATION).setInterpolator(LINEAR); mIconAnimator.addListener(new AnimatorListenerAdapter() { @Override public void onAnimationEnd(Animator animation) { mIconAnimator = null; } }); mIconAnimator.start(); } public float cancelIconAnimation() { if (mIconAnimator != null) { mIconAnimator.cancel(); } return mIconAnimationProgress; } public void setDrawEnabled(boolean drawEnabled) { if (mDrawEnabled != drawEnabled) { mDrawEnabled = drawEnabled; Loading @@ -46,6 +100,16 @@ public class LiveTileOverlay extends Drawable { public void draw(Canvas canvas) { if (mCurrentRect != null && mDrawEnabled) { canvas.drawRoundRect(mCurrentRect, mCornerRadius, mCornerRadius, mPaint); if (mIcon != null && mIconAnimationProgress > 0f) { canvas.save(); float scale = Interpolators.clampToProgress(FAST_OUT_SLOW_IN, 0f, 1f).getInterpolation(mIconAnimationProgress); canvas.translate(mCurrentRect.centerX() - mIcon.getBounds().width() / 2 * scale, mCurrentRect.top - mIcon.getBounds().height() / 2 * scale); canvas.scale(scale, scale); mIcon.draw(canvas); canvas.restore(); } } } Loading @@ -59,4 +123,9 @@ public class LiveTileOverlay extends Drawable { public int getOpacity() { return PixelFormat.TRANSLUCENT; } private void setIconAnimationProgress(float progress) { mIconAnimationProgress = progress; invalidateSelf(); } }
quickstep/recents_ui_overrides/src/com/android/quickstep/views/RecentsView.java +14 −0 Original line number Diff line number Diff line Loading @@ -278,6 +278,7 @@ public abstract class RecentsView<T extends BaseActivity> extends PagedView impl private final int mEmptyMessagePadding; private boolean mShowEmptyMessage; private Layout mEmptyTextLayout; private LiveTileOverlay mLiveTileOverlay; private BaseActivity.MultiWindowModeChangedListener mMultiWindowModeChangedListener = (inMultiWindowMode) -> { Loading Loading @@ -855,10 +856,15 @@ public abstract class RecentsView<T extends BaseActivity> extends PagedView impl } public void animateUpRunningTaskIconScale() { animateUpRunningTaskIconScale(0); } public void animateUpRunningTaskIconScale(float startProgress) { mRunningTaskIconScaledDown = false; TaskView firstTask = getRunningTaskView(); if (firstTask != null) { firstTask.animateIconScaleAndDimIntoView(); firstTask.setIconScaleAnimStartProgress(startProgress); } } Loading Loading @@ -1567,6 +1573,14 @@ public abstract class RecentsView<T extends BaseActivity> extends PagedView impl mClipAnimationHelper = clipAnimationHelper; } public void setLiveTileOverlay(LiveTileOverlay liveTileOverlay) { mLiveTileOverlay = liveTileOverlay; } public void updateLiveTileIcon(Drawable icon) { mLiveTileOverlay.setIcon(icon); } public void finishRecentsAnimation(boolean toRecents, Runnable onFinishComplete) { if (mRecentsAnimationWrapper == null) { if (onFinishComplete != null) { Loading
quickstep/recents_ui_overrides/src/com/android/quickstep/views/TaskView.java +10 −1 Original line number Diff line number Diff line Loading @@ -156,7 +156,8 @@ public class TaskView extends FrameLayout implements PageCallbacks, Reusable { private float mZoomScale; private float mFullscreenProgress; private Animator mIconAndDimAnimator; private ObjectAnimator mIconAndDimAnimator; private float mIconScaleAnimStartProgress = 0; private float mFocusTransitionProgress = 1; private boolean mShowScreenshot; Loading Loading @@ -317,6 +318,9 @@ public class TaskView extends FrameLayout implements PageCallbacks, Reusable { mIconLoadRequest = iconCache.updateIconInBackground(mTask, (task) -> { setIcon(task.icon); if (isRunningTask()) { getRecentsView().updateLiveTileIcon(task.icon); } mDigitalWellBeingToast.initialize( mTask, (saturation, contentDescription) -> { Loading Loading @@ -380,11 +384,16 @@ public class TaskView extends FrameLayout implements PageCallbacks, Reusable { mIconView.setScaleY(scale); } public void setIconScaleAnimStartProgress(float startProgress) { mIconScaleAnimStartProgress = startProgress; } public void animateIconScaleAndDimIntoView() { if (mIconAndDimAnimator != null) { mIconAndDimAnimator.cancel(); } mIconAndDimAnimator = ObjectAnimator.ofFloat(this, FOCUS_TRANSITION, 1); mIconAndDimAnimator.setCurrentFraction(mIconScaleAnimStartProgress); mIconAndDimAnimator.setDuration(DIM_ANIM_DURATION).setInterpolator(LINEAR); mIconAndDimAnimator.addListener(new AnimatorListenerAdapter() { @Override Loading