diff options
author | Android Build Merger (Role) <noreply-android-build-merger@google.com> | 2018-04-19 23:30:48 +0000 |
---|---|---|
committer | Android Build Merger (Role) <noreply-android-build-merger@google.com> | 2018-04-19 23:30:48 +0000 |
commit | ee3c67cff0f742e76d26a80b1282dca1b37aa8f4 (patch) | |
tree | 3d65cab20ea98e2beed284203734e800a53321ce | |
parent | a60a34399d1509bf6cf5a5cca01632cfc32f4cfc (diff) | |
parent | 7d2e40912eb7007e8378f106556b4cbcbc24d661 (diff) | |
download | android_packages_apps_Trebuchet-ee3c67cff0f742e76d26a80b1282dca1b37aa8f4.tar.gz android_packages_apps_Trebuchet-ee3c67cff0f742e76d26a80b1282dca1b37aa8f4.tar.bz2 android_packages_apps_Trebuchet-ee3c67cff0f742e76d26a80b1282dca1b37aa8f4.zip |
[automerger] Updating the task swipe-down UI am: 7d2e40912e
Change-Id: I4fe2c0ca637b7952c78883a1517656b441badde5
7 files changed, 226 insertions, 24 deletions
diff --git a/quickstep/src/com/android/quickstep/fallback/FallbackRecentsView.java b/quickstep/src/com/android/quickstep/fallback/FallbackRecentsView.java index 5a8ce160a..3d64cc8c7 100644 --- a/quickstep/src/com/android/quickstep/fallback/FallbackRecentsView.java +++ b/quickstep/src/com/android/quickstep/fallback/FallbackRecentsView.java @@ -18,7 +18,6 @@ package com.android.quickstep.fallback; import android.content.Context; import android.graphics.Canvas; import android.graphics.Rect; -import android.support.annotation.AnyThread; import android.util.AttributeSet; import android.view.View; diff --git a/quickstep/src/com/android/quickstep/util/ClipAnimationHelper.java b/quickstep/src/com/android/quickstep/util/ClipAnimationHelper.java index 9276d2381..9dd83d20a 100644 --- a/quickstep/src/com/android/quickstep/util/ClipAnimationHelper.java +++ b/quickstep/src/com/android/quickstep/util/ClipAnimationHelper.java @@ -15,15 +15,23 @@ */ package com.android.quickstep.util; +import android.graphics.Canvas; import android.graphics.Matrix; import android.graphics.Matrix.ScaleToFit; import android.graphics.Rect; import android.graphics.RectF; +import com.android.launcher3.BaseDraggingActivity; +import com.android.launcher3.DeviceProfile; +import com.android.launcher3.R; import com.android.launcher3.Utilities; +import com.android.launcher3.dragndrop.DragLayer; +import com.android.launcher3.views.BaseDragLayer; +import com.android.quickstep.views.TaskThumbnailView; import com.android.systemui.shared.recents.utilities.RectFEvaluator; import com.android.systemui.shared.system.RemoteAnimationTargetCompat; import com.android.systemui.shared.system.TransactionCompat; +import com.android.systemui.shared.system.WindowManagerWrapper; /** * Utility class to handle window clip animation @@ -126,4 +134,73 @@ public class ClipAnimationHelper { mTargetRect.offset(offsetX, offsetY); } } + + public void fromTaskThumbnailView(TaskThumbnailView ttv) { + BaseDraggingActivity activity = BaseDraggingActivity.fromContext(ttv.getContext()); + BaseDragLayer dl = activity.getDragLayer(); + + int[] pos = new int[2]; + dl.getLocationOnScreen(pos); + mHomeStackBounds.set(0, 0, dl.getWidth(), dl.getHeight()); + mHomeStackBounds.offset(pos[0], pos[1]); + + if (activity.isInMultiWindowModeCompat()) { + // TODO: Fetch multi-window target bounds from system-ui + DeviceProfile fullDp = activity.getDeviceProfile().getFullScreenProfile(); + // Use availableWidthPx and availableHeightPx instead of widthPx and heightPx to + // account for system insets + int taskWidth = fullDp.availableWidthPx; + int taskHeight = fullDp.availableHeightPx; + int halfDividerSize = activity.getResources() + .getDimensionPixelSize(R.dimen.multi_window_task_divider_size) / 2; + + Rect insets = new Rect(); + WindowManagerWrapper.getInstance().getStableInsets(insets); + if (fullDp.isLandscape) { + taskWidth = taskWidth / 2 - halfDividerSize; + } else { + taskHeight = taskHeight / 2 - halfDividerSize; + } + + mSourceStackBounds.set(0, 0, taskWidth, taskHeight); + // Align the task to bottom right (probably not true for seascape). + mSourceStackBounds.offset(insets.left + fullDp.availableWidthPx - taskWidth, + insets.top + fullDp.availableHeightPx - taskHeight); + } else { + mSourceStackBounds.set(mHomeStackBounds); + mSourceInsets.set(activity.getDeviceProfile().getInsets()); + } + + Rect targetRect = new Rect(); + dl.getDescendantRectRelativeToSelf(ttv, targetRect); + updateTargetRect(targetRect); + + // Transform the clip relative to the target rect. + float scale = mTargetRect.width() / mSourceRect.width(); + mSourceWindowClipInsets.left = mSourceWindowClipInsets.left * scale; + mSourceWindowClipInsets.top = mSourceWindowClipInsets.top * scale; + mSourceWindowClipInsets.right = mSourceWindowClipInsets.right * scale; + mSourceWindowClipInsets.bottom = mSourceWindowClipInsets.bottom * scale; + } + + public void drawForProgress(TaskThumbnailView ttv, Canvas canvas, float progress) { + RectF currentRect; + synchronized (mTargetRect) { + currentRect = mRectFEvaluator.evaluate(progress, mSourceRect, mTargetRect); + } + + canvas.translate(mSourceStackBounds.left - mHomeStackBounds.left, + mSourceStackBounds.top - mHomeStackBounds.top); + mTmpMatrix.setRectToRect(mTargetRect, currentRect, ScaleToFit.FILL); + canvas.concat(mTmpMatrix); + canvas.translate(mTargetRect.left, mTargetRect.top); + + float insetProgress = (1 - progress); + ttv.drawOnCanvas(canvas, + -mSourceWindowClipInsets.left * insetProgress, + -mSourceWindowClipInsets.top * insetProgress, + ttv.getMeasuredWidth() + mSourceWindowClipInsets.right * insetProgress, + ttv.getMeasuredHeight() + mSourceWindowClipInsets.bottom * insetProgress, + ttv.getCornerRadius() * progress); + } } diff --git a/quickstep/src/com/android/quickstep/util/TaskViewDrawable.java b/quickstep/src/com/android/quickstep/util/TaskViewDrawable.java new file mode 100644 index 000000000..0fa0023aa --- /dev/null +++ b/quickstep/src/com/android/quickstep/util/TaskViewDrawable.java @@ -0,0 +1,100 @@ +/* + * Copyright (C) 2018 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.util; + +import android.animation.TimeInterpolator; +import android.graphics.Canvas; +import android.graphics.ColorFilter; +import android.graphics.PixelFormat; +import android.graphics.drawable.Drawable; +import android.util.FloatProperty; +import android.widget.ImageView; + +import com.android.launcher3.Utilities; +import com.android.quickstep.views.RecentsView; +import com.android.quickstep.views.TaskThumbnailView; +import com.android.quickstep.views.TaskView; + +public class TaskViewDrawable extends Drawable { + + public static FloatProperty<TaskViewDrawable> PROGRESS = + new FloatProperty<TaskViewDrawable>("progress") { + @Override + public void setValue(TaskViewDrawable taskViewDrawable, float v) { + taskViewDrawable.setProgress(v); + } + + @Override + public Float get(TaskViewDrawable taskViewDrawable) { + return taskViewDrawable.mProgress; + } + }; + + private static final TimeInterpolator ICON_SIZE_INTERPOLATOR = + (t) -> (Math.max(t, 0.3f) - 0.3f) / 0.7f; + + private final RecentsView mParent; + private final ImageView mIconView; + private final int[] mIconPos; + + private final TaskThumbnailView mThumbnailView; + + private final ClipAnimationHelper mClipAnimationHelper; + + private float mProgress = 1; + + public TaskViewDrawable(TaskView tv, RecentsView parent) { + mParent = parent; + mIconView = tv.getIconView(); + mIconPos = new int[2]; + Utilities.getDescendantCoordRelativeToAncestor(mIconView, parent, mIconPos, true); + + mThumbnailView = tv.getThumbnail(); + mClipAnimationHelper = new ClipAnimationHelper(); + mClipAnimationHelper.fromTaskThumbnailView(mThumbnailView); + } + + public void setProgress(float progress) { + mProgress = progress; + mParent.invalidate(); + } + + @Override + public void draw(Canvas canvas) { + canvas.save(); + canvas.translate(mParent.getScrollX(), mParent.getScrollY()); + mClipAnimationHelper.drawForProgress(mThumbnailView, canvas, mProgress); + canvas.restore(); + + canvas.save(); + canvas.translate(mIconPos[0], mIconPos[1]); + float scale = ICON_SIZE_INTERPOLATOR.getInterpolation(mProgress); + canvas.scale(scale, scale, mIconView.getWidth() / 2, mIconView.getHeight() / 2); + mIconView.draw(canvas); + canvas.restore(); + } + + @Override + public void setAlpha(int i) { } + + @Override + public void setColorFilter(ColorFilter colorFilter) { } + + @Override + public int getOpacity() { + return PixelFormat.TRANSLUCENT; + } +} diff --git a/quickstep/src/com/android/quickstep/views/LauncherRecentsView.java b/quickstep/src/com/android/quickstep/views/LauncherRecentsView.java index 280fd467b..90b4bd2c3 100644 --- a/quickstep/src/com/android/quickstep/views/LauncherRecentsView.java +++ b/quickstep/src/com/android/quickstep/views/LauncherRecentsView.java @@ -130,4 +130,12 @@ public class LauncherRecentsView extends RecentsView<Launcher> { protected void getTaskSize(DeviceProfile dp, Rect outRect) { LayoutUtils.calculateLauncherTaskSize(getContext(), dp, outRect); } + + @Override + protected void onTaskLaunched(boolean success) { + if (success) { + mActivity.getStateManager().goToState(NORMAL, false /* animate */); + } + super.onTaskLaunched(success); + } } diff --git a/quickstep/src/com/android/quickstep/views/RecentsView.java b/quickstep/src/com/android/quickstep/views/RecentsView.java index 5e55590d4..6a2df0b87 100644 --- a/quickstep/src/com/android/quickstep/views/RecentsView.java +++ b/quickstep/src/com/android/quickstep/views/RecentsView.java @@ -66,10 +66,10 @@ import com.android.launcher3.util.PendingAnimation; import com.android.launcher3.util.Themes; import com.android.quickstep.OverviewCallbacks; import com.android.quickstep.QuickScrubController; -import com.android.quickstep.RecentsAnimationInterpolator; import com.android.quickstep.RecentsAnimationInterpolator.TaskWindowBounds; import com.android.quickstep.RecentsModel; import com.android.quickstep.TaskUtils; +import com.android.quickstep.util.TaskViewDrawable; import com.android.systemui.shared.recents.model.RecentsTaskLoadPlan; import com.android.systemui.shared.recents.model.RecentsTaskLoader; import com.android.systemui.shared.recents.model.Task; @@ -79,6 +79,7 @@ import com.android.systemui.shared.system.ActivityManagerWrapper; import com.android.systemui.shared.system.TaskStackChangeListener; import java.util.ArrayList; +import java.util.function.Consumer; /** * A list of recent tasks. @@ -522,7 +523,6 @@ public abstract class RecentsView<T extends BaseActivity> mHasVisibleTaskData.clear(); } - protected abstract void onAllTasksRemoved(); public void reset() { @@ -1060,23 +1060,27 @@ public abstract class RecentsView<T extends BaseActivity> return new PendingAnimation(anim); } - final RecentsAnimationInterpolator recentsInterpolator = tv.getRecentsInterpolator(); - ValueAnimator targetViewAnim = ValueAnimator.ofFloat(0, 1); - targetViewAnim.addUpdateListener((animation) -> { - float percent = animation.getAnimatedFraction(); - TaskWindowBounds tw = recentsInterpolator.interpolate(percent); - tv.setScaleX(tw.taskScale); - tv.setScaleY(tw.taskScale); - tv.setTranslationX(tw.taskX); - tv.setTranslationY(tw.taskY); - }); - anim.play(targetViewAnim); + tv.setVisibility(INVISIBLE); + TaskViewDrawable drawable = new TaskViewDrawable(tv, this); + getOverlay().add(drawable); + + ObjectAnimator drawableAnim = + ObjectAnimator.ofFloat(drawable, TaskViewDrawable.PROGRESS, 1, 0); + drawableAnim.setInterpolator(LINEAR); + + anim.play(drawableAnim); anim.setDuration(duration); + Consumer<Boolean> onTaskLaunchFinish = (r) -> { + onTaskLaunched(r); + tv.setVisibility(VISIBLE); + getOverlay().remove(drawable); + }; + mPendingAnimation = new PendingAnimation(anim); mPendingAnimation.addEndListener((onEndListener) -> { if (onEndListener.isSuccess) { - tv.launchTask(false); + tv.launchTask(false, onTaskLaunchFinish, getHandler()); Task task = tv.getTask(); if (task != null) { mActivity.getUserEventDispatcher().logTaskLaunchOrDismiss( @@ -1084,13 +1088,17 @@ public abstract class RecentsView<T extends BaseActivity> TaskUtils.getComponentKeyForTask(task.key)); } } else { - resetTaskVisuals(); + onTaskLaunchFinish.accept(false); } mPendingAnimation = null; }); return mPendingAnimation; } + protected void onTaskLaunched(boolean success) { + resetTaskVisuals(); + } + @Override protected void notifyPageSwitchListener(int prevPage) { super.notifyPageSwitchListener(prevPage); diff --git a/quickstep/src/com/android/quickstep/views/TaskThumbnailView.java b/quickstep/src/com/android/quickstep/views/TaskThumbnailView.java index 2f7199be9..592166d80 100644 --- a/quickstep/src/com/android/quickstep/views/TaskThumbnailView.java +++ b/quickstep/src/com/android/quickstep/views/TaskThumbnailView.java @@ -143,22 +143,28 @@ public class TaskThumbnailView extends View { @Override protected void onDraw(Canvas canvas) { + drawOnCanvas(canvas, 0, 0, getMeasuredWidth(), getMeasuredHeight(), mCornerRadius); + } + + public float getCornerRadius() { + return mCornerRadius; + } + + public void drawOnCanvas(Canvas canvas, float x, float y, float width, float height, + float cornerRadius) { + // Always draw the background since the snapshots may be translucent + canvas.drawRoundRect(x, y, width, height, cornerRadius, cornerRadius, mBackgroundPaint); if (mTask == null) { return; } - int width = getMeasuredWidth(); - int height = getMeasuredHeight(); - - // Always draw the background since the snapshots may be translucent - canvas.drawRoundRect(0, 0, width, height, mCornerRadius, mCornerRadius, mBackgroundPaint); if (!mTask.isLocked) { if (mClipBottom > 0) { canvas.save(); - canvas.clipRect(0, 0, width, mClipBottom); - canvas.drawRoundRect(0, 0, width, height, mCornerRadius, mCornerRadius, mPaint); + canvas.clipRect(x, y, width, mClipBottom); + canvas.drawRoundRect(x, y, width, height, cornerRadius, cornerRadius, mPaint); canvas.restore(); } else { - canvas.drawRoundRect(0, 0, width, height, mCornerRadius, mCornerRadius, mPaint); + canvas.drawRoundRect(x, y, width, height, cornerRadius, cornerRadius, mPaint); } } } diff --git a/quickstep/src/com/android/quickstep/views/TaskView.java b/quickstep/src/com/android/quickstep/views/TaskView.java index 2c1318c48..b32d8dd45 100644 --- a/quickstep/src/com/android/quickstep/views/TaskView.java +++ b/quickstep/src/com/android/quickstep/views/TaskView.java @@ -131,6 +131,10 @@ public class TaskView extends FrameLayout implements TaskCallbacks, PageCallback return mSnapshotView; } + public ImageView getIconView() { + return mIconView; + } + public void launchTask(boolean animate) { launchTask(animate, null, null); } |