diff options
9 files changed, 73 insertions, 15 deletions
diff --git a/quickstep/res/values/dimens.xml b/quickstep/res/values/dimens.xml index 49c4492b6..e0c4e4baa 100644 --- a/quickstep/res/values/dimens.xml +++ b/quickstep/res/values/dimens.xml @@ -19,7 +19,7 @@ <dimen name="task_thumbnail_top_margin">24dp</dimen> <dimen name="task_thumbnail_half_top_margin">12dp</dimen> <dimen name="task_thumbnail_icon_size">48dp</dimen> - <dimen name="task_corner_radius">2dp</dimen> + <dimen name="task_corner_radius">8dp</dimen> <dimen name="recents_page_spacing">10dp</dimen> <dimen name="recents_clear_all_deadzone_vertical_margin">70dp</dimen> <dimen name="quickscrub_adjacent_visible_width">20dp</dimen> diff --git a/quickstep/src/com/android/launcher3/LauncherAppTransitionManagerImpl.java b/quickstep/src/com/android/launcher3/LauncherAppTransitionManagerImpl.java index 9e8546936..1049cca59 100644 --- a/quickstep/src/com/android/launcher3/LauncherAppTransitionManagerImpl.java +++ b/quickstep/src/com/android/launcher3/LauncherAppTransitionManagerImpl.java @@ -67,6 +67,7 @@ import com.android.launcher3.graphics.DrawableFactory; import com.android.launcher3.shortcuts.DeepShortcutView; import com.android.launcher3.util.MultiValueAlpha; import com.android.launcher3.util.MultiValueAlpha.AlphaProperty; +import com.android.quickstep.RecentsModel; import com.android.quickstep.util.ClipAnimationHelper; import com.android.quickstep.util.MultiValueUpdateListener; import com.android.quickstep.util.RemoteAnimationProvider; @@ -292,7 +293,7 @@ public class LauncherAppTransitionManagerImpl extends LauncherAppTransitionManag ? RECENTS_QUICKSCRUB_LAUNCH_DURATION : RECENTS_LAUNCH_DURATION; - ClipAnimationHelper helper = new ClipAnimationHelper(); + ClipAnimationHelper helper = new ClipAnimationHelper(mLauncher); target.play(getRecentsWindowAnimator(taskView, skipLauncherChanges, targets, helper) .setDuration(duration)); @@ -614,6 +615,13 @@ public class LauncherAppTransitionManagerImpl extends LauncherAppTransitionManag float transX0 = floatingViewBounds[0] - offsetX; float transY0 = floatingViewBounds[1] - offsetY; + // Animate window corner radius from 100% to windowCornerRadius. + float windowCornerRadius = RecentsModel.INSTANCE.get(mLauncher) + .getWindowCornerRadius(); + float circleRadius = scaledWindowWidth / 2f; + float windowRadius = Utilities.mapRange(easePercent, circleRadius, + windowCornerRadius); + // Animate the window crop so that it starts off as a square, and then reveals // horizontally. float cropHeight = windowHeight * easePercent + windowWidth * (1 - easePercent); @@ -628,20 +636,24 @@ public class LauncherAppTransitionManagerImpl extends LauncherAppTransitionManag RemoteAnimationTargetCompat target = targets[i]; Rect targetCrop; - float alpha; + final float alpha; + final float cornerRadius; if (target.mode == MODE_OPENING) { matrix.setScale(scale, scale); matrix.postTranslate(transX0, transY0); targetCrop = crop; alpha = mAlpha.value; + cornerRadius = windowRadius; } else { matrix.setTranslate(target.position.x, target.position.y); alpha = 1f; targetCrop = target.sourceContainerBounds; + cornerRadius = 0; } params[i] = new SurfaceParams(target.leash, alpha, matrix, targetCrop, - RemoteAnimationProvider.getLayer(target, MODE_OPENING)); + RemoteAnimationProvider.getLayer(target, MODE_OPENING), + cornerRadius); } surfaceApplier.scheduleApply(params); } @@ -733,6 +745,7 @@ public class LauncherAppTransitionManagerImpl extends LauncherAppTransitionManag Matrix matrix = new Matrix(); ValueAnimator closingAnimator = ValueAnimator.ofFloat(0, 1); int duration = CLOSING_TRANSITION_DURATION_MS; + float windowCornerRadius = RecentsModel.INSTANCE.get(mLauncher).getWindowCornerRadius(); closingAnimator.setDuration(duration); closingAnimator.addUpdateListener(new MultiValueUpdateListener() { FloatProp mDy = new FloatProp(0, mClosingWindowTransY, 0, duration, DEACCEL_1_7); @@ -744,7 +757,8 @@ public class LauncherAppTransitionManagerImpl extends LauncherAppTransitionManag SurfaceParams[] params = new SurfaceParams[targets.length]; for (int i = targets.length - 1; i >= 0; i--) { RemoteAnimationTargetCompat target = targets[i]; - float alpha; + final float alpha; + final float cornerRadius; if (target.mode == MODE_CLOSING) { matrix.setScale(mScale.value, mScale.value, target.sourceContainerBounds.centerX(), @@ -752,13 +766,16 @@ public class LauncherAppTransitionManagerImpl extends LauncherAppTransitionManag matrix.postTranslate(0, mDy.value); matrix.postTranslate(target.position.x, target.position.y); alpha = mAlpha.value; + cornerRadius = windowCornerRadius; } else { matrix.setTranslate(target.position.x, target.position.y); alpha = 1f; + cornerRadius = 0f; } params[i] = new SurfaceParams(target.leash, alpha, matrix, target.sourceContainerBounds, - RemoteAnimationProvider.getLayer(target, MODE_CLOSING)); + RemoteAnimationProvider.getLayer(target, MODE_CLOSING), + cornerRadius); } surfaceApplier.scheduleApply(params); } diff --git a/quickstep/src/com/android/quickstep/ActivityControlHelper.java b/quickstep/src/com/android/quickstep/ActivityControlHelper.java index b96f9f067..d78ba9c9f 100644 --- a/quickstep/src/com/android/quickstep/ActivityControlHelper.java +++ b/quickstep/src/com/android/quickstep/ActivityControlHelper.java @@ -332,7 +332,7 @@ public interface ActivityControlHelper<T extends BaseDraggingActivity> { float prevRvScale = recentsView.getScaleX(); float targetRvScale = endState.getOverviewScaleAndTranslationYFactor(launcher)[0]; SCALE_PROPERTY.set(recentsView, targetRvScale); - ClipAnimationHelper clipHelper = new ClipAnimationHelper(); + ClipAnimationHelper clipHelper = new ClipAnimationHelper(launcher); clipHelper.fromTaskThumbnailView(v.getThumbnail(), (RecentsView) v.getParent(), null); SCALE_PROPERTY.set(recentsView, prevRvScale); diff --git a/quickstep/src/com/android/quickstep/OverviewCommandHelper.java b/quickstep/src/com/android/quickstep/OverviewCommandHelper.java index f8f09055f..61bb75f85 100644 --- a/quickstep/src/com/android/quickstep/OverviewCommandHelper.java +++ b/quickstep/src/com/android/quickstep/OverviewCommandHelper.java @@ -326,7 +326,7 @@ public class OverviewCommandHelper { return anim; } - final ClipAnimationHelper clipHelper = new ClipAnimationHelper(); + final ClipAnimationHelper clipHelper = new ClipAnimationHelper(mActivity); // At this point, the activity is already started and laid-out. Get the home-bounds // relative to the screen using the rootView of the activity. diff --git a/quickstep/src/com/android/quickstep/RecentsActivity.java b/quickstep/src/com/android/quickstep/RecentsActivity.java index 9d01f7447..deedd324a 100644 --- a/quickstep/src/com/android/quickstep/RecentsActivity.java +++ b/quickstep/src/com/android/quickstep/RecentsActivity.java @@ -183,7 +183,7 @@ public class RecentsActivity extends BaseDraggingActivity { RemoteAnimationTargetCompat[] targets) { AnimatorSet target = new AnimatorSet(); boolean activityClosing = taskIsATargetWithMode(targets, getTaskId(), MODE_CLOSING); - ClipAnimationHelper helper = new ClipAnimationHelper(); + ClipAnimationHelper helper = new ClipAnimationHelper(this); target.play(getRecentsWindowAnimator(taskView, !activityClosing, targets, helper) .setDuration(RECENTS_LAUNCH_DURATION)); diff --git a/quickstep/src/com/android/quickstep/RecentsModel.java b/quickstep/src/com/android/quickstep/RecentsModel.java index 2e4d4d2b8..a62e6adfa 100644 --- a/quickstep/src/com/android/quickstep/RecentsModel.java +++ b/quickstep/src/com/android/quickstep/RecentsModel.java @@ -45,6 +45,9 @@ import androidx.annotation.WorkerThread; */ @TargetApi(Build.VERSION_CODES.O) public class RecentsModel extends TaskStackChangeListener { + + private static final String TAG = "RecentsModel"; + // We do not need any synchronization for this variable as its only written on UI thread. public static final MainThreadInitializedObject<RecentsModel> INSTANCE = new MainThreadInitializedObject<>(c -> new RecentsModel(c)); @@ -62,6 +65,9 @@ public class RecentsModel extends TaskStackChangeListener { private final TaskIconCache mIconCache; private final TaskThumbnailCache mThumbnailCache; + private float mWindowCornerRadius = -1; + + private RecentsModel(Context context) { mContext = context; @@ -174,6 +180,26 @@ public class RecentsModel extends TaskStackChangeListener { return mSystemUiProxy; } + public float getWindowCornerRadius() { + // The window corner radius is expressed in pixels and won't change if the + // display density changes. It's safe to cache the value. + if (mWindowCornerRadius == -1) { + if (mSystemUiProxy != null) { + try { + mWindowCornerRadius = mSystemUiProxy.getWindowCornerRadius(); + } catch (RemoteException e) { + Log.w(TAG, "Connection to ISystemUIProxy was lost, ignoring window corner " + + "radius"); + return 0; + } + } else { + Log.w(TAG, "ISystemUIProxy is null, ignoring window corner radius"); + return 0; + } + } + return mWindowCornerRadius; + } + public void onTrimMemory(int level) { if (level == ComponentCallbacks2.TRIM_MEMORY_UI_HIDDEN) { mThumbnailCache.getHighResLoadingState().setVisible(false); diff --git a/quickstep/src/com/android/quickstep/WindowTransformSwipeHandler.java b/quickstep/src/com/android/quickstep/WindowTransformSwipeHandler.java index fe3300d36..f4b2febe7 100644 --- a/quickstep/src/com/android/quickstep/WindowTransformSwipeHandler.java +++ b/quickstep/src/com/android/quickstep/WindowTransformSwipeHandler.java @@ -175,7 +175,7 @@ public class WindowTransformSwipeHandler<T extends BaseDraggingActivity> { private static final float SWIPE_DURATION_MULTIPLIER = Math.min(1 / MIN_PROGRESS_FOR_OVERVIEW, 1 / (1 - MIN_PROGRESS_FOR_OVERVIEW)); - private final ClipAnimationHelper mClipAnimationHelper = new ClipAnimationHelper(); + private final ClipAnimationHelper mClipAnimationHelper; protected Runnable mGestureEndCallback; protected boolean mIsGoingToHome; @@ -255,6 +255,7 @@ public class WindowTransformSwipeHandler<T extends BaseDraggingActivity> { mTouchInteractionLog = touchInteractionLog; mRecentsAnimationWrapper = new RecentsAnimationWrapper(inputConsumer, this::createNewTouchProxyHandler); + mClipAnimationHelper = new ClipAnimationHelper(context); initStateCallbacks(); } diff --git a/quickstep/src/com/android/quickstep/util/ClipAnimationHelper.java b/quickstep/src/com/android/quickstep/util/ClipAnimationHelper.java index 57a0e8f8f..f25424494 100644 --- a/quickstep/src/com/android/quickstep/util/ClipAnimationHelper.java +++ b/quickstep/src/com/android/quickstep/util/ClipAnimationHelper.java @@ -21,6 +21,7 @@ import static com.android.systemui.shared.system.RemoteAnimationTargetCompat.MOD import static com.android.systemui.shared.system.RemoteAnimationTargetCompat.MODE_OPENING; import android.annotation.TargetApi; +import android.content.Context; import android.graphics.Canvas; import android.graphics.Matrix; import android.graphics.Matrix.ScaleToFit; @@ -31,6 +32,8 @@ import android.os.Build; import android.os.RemoteException; import android.view.animation.Interpolator; +import androidx.annotation.Nullable; + import com.android.launcher3.BaseDraggingActivity; import com.android.launcher3.DeviceProfile; import com.android.launcher3.R; @@ -50,8 +53,6 @@ import com.android.systemui.shared.system.WindowManagerWrapper; import java.util.function.BiFunction; -import androidx.annotation.Nullable; - /** * Utility class to handle window clip animation */ @@ -82,6 +83,10 @@ public class ClipAnimationHelper { private final Matrix mTmpMatrix = new Matrix(); private final RectF mTmpRectF = new RectF(); private final RectF mCurrentRectWithInsets = new RectF(); + // Corner radius of windows, in pixels + private final float mWindowCornerRadius; + // Corner radius of windows when they're in overview mode. + private final float mTaskCornerRadius; private float mTargetScale = 1f; private float mOffsetScale = 1f; @@ -95,6 +100,11 @@ public class ClipAnimationHelper { private BiFunction<RemoteAnimationTargetCompat, Float, Float> mTaskAlphaCallback = (t, a1) -> a1; + public ClipAnimationHelper(Context context) { + mTaskCornerRadius = context.getResources().getDimension(R.dimen.task_corner_radius); + mWindowCornerRadius = RecentsModel.INSTANCE.get(context).getWindowCornerRadius(); + } + private void updateSourceStack(RemoteAnimationTargetCompat target) { mSourceInsets.set(target.contentInsets); mSourceStackBounds.set(target.sourceContainerBounds); @@ -168,11 +178,15 @@ public class ClipAnimationHelper { Rect crop = app.sourceContainerBounds; float alpha = 1f; int layer; + float cornerRadius = 0f; if (app.mode == targetSet.targetMode) { if (app.activityType != RemoteAnimationTargetCompat.ACTIVITY_TYPE_HOME) { mTmpMatrix.setRectToRect(mSourceRect, currentRect, ScaleToFit.FILL); mTmpMatrix.postTranslate(app.position.x, app.position.y); mClipRectF.roundOut(crop); + float scale = crop.width() / currentRect.width(); + cornerRadius = Utilities.mapRange(progress, mWindowCornerRadius, + mTaskCornerRadius * scale); } if (app.isNotInRecents @@ -186,7 +200,7 @@ public class ClipAnimationHelper { crop = null; layer = Integer.MAX_VALUE; } - params[i] = new SurfaceParams(app.leash, alpha, mTmpMatrix, crop, layer); + params[i] = new SurfaceParams(app.leash, alpha, mTmpMatrix, crop, layer, cornerRadius); } applyParams(syncTransactionApplier, params); return currentRect; @@ -315,7 +329,7 @@ public class ClipAnimationHelper { -mSourceWindowClipInsets.top * insetProgress, ttv.getMeasuredWidth() + mSourceWindowClipInsets.right * insetProgress, ttv.getMeasuredHeight() + mSourceWindowClipInsets.bottom * insetProgress, - ttv.getCornerRadius() * progress); + Utilities.mapRange(progress, mWindowCornerRadius, ttv.getCornerRadius())); } public RectF getTargetRect() { diff --git a/quickstep/src/com/android/quickstep/util/TaskViewDrawable.java b/quickstep/src/com/android/quickstep/util/TaskViewDrawable.java index 48b07a714..6ee305f80 100644 --- a/quickstep/src/com/android/quickstep/util/TaskViewDrawable.java +++ b/quickstep/src/com/android/quickstep/util/TaskViewDrawable.java @@ -71,7 +71,7 @@ public class TaskViewDrawable extends Drawable { Utilities.getDescendantCoordRelativeToAncestor(mIconView, parent, mIconPos, true); mThumbnailView = tv.getThumbnail(); - mClipAnimationHelper = new ClipAnimationHelper(); + mClipAnimationHelper = new ClipAnimationHelper(parent.getContext()); mClipAnimationHelper.fromTaskThumbnailView(mThumbnailView, parent); } |