diff --git a/quickstep/libs/sysui_shared.jar b/quickstep/libs/sysui_shared.jar index 41bf729974..308e92f666 100644 Binary files a/quickstep/libs/sysui_shared.jar and b/quickstep/libs/sysui_shared.jar differ diff --git a/quickstep/src/com/android/quickstep/OverviewCommandHelper.java b/quickstep/src/com/android/quickstep/OverviewCommandHelper.java index 41a45501d0..eff94fcb5c 100644 --- a/quickstep/src/com/android/quickstep/OverviewCommandHelper.java +++ b/quickstep/src/com/android/quickstep/OverviewCommandHelper.java @@ -67,6 +67,7 @@ import com.android.systemui.shared.system.ActivityManagerWrapper; import com.android.systemui.shared.system.LatencyTrackerCompat; import com.android.systemui.shared.system.PackageManagerWrapper; import com.android.systemui.shared.system.RemoteAnimationTargetCompat; +import com.android.systemui.shared.system.SyncRtSurfaceTransactionApplier; import com.android.systemui.shared.system.TransactionCompat; import java.util.ArrayList; @@ -350,11 +351,14 @@ public class OverviewCommandHelper { clipHelper.updateTargetRect(targetRect); clipHelper.prepareAnimation(false /* isOpening */); + SyncRtSurfaceTransactionApplier syncTransactionApplier = + new SyncRtSurfaceTransactionApplier(rootView); ValueAnimator valueAnimator = ValueAnimator.ofFloat(0, 1); valueAnimator.setDuration(RECENTS_LAUNCH_DURATION); valueAnimator.setInterpolator(TOUCH_RESPONSE_INTERPOLATOR); valueAnimator.addUpdateListener((v) -> - clipHelper.applyTransform(targetSet, (float) v.getAnimatedValue())); + clipHelper.applyTransform(targetSet, (float) v.getAnimatedValue(), + syncTransactionApplier)); if (targetSet.isAnimatingHome()) { // If we are animating home, fade in the opening targets diff --git a/quickstep/src/com/android/quickstep/TaskUtils.java b/quickstep/src/com/android/quickstep/TaskUtils.java index 2b0c98f939..ec2c318d35 100644 --- a/quickstep/src/com/android/quickstep/TaskUtils.java +++ b/quickstep/src/com/android/quickstep/TaskUtils.java @@ -46,6 +46,7 @@ import com.android.quickstep.views.RecentsView; import com.android.quickstep.views.TaskView; import com.android.systemui.shared.recents.model.Task; import com.android.systemui.shared.system.RemoteAnimationTargetCompat; +import com.android.systemui.shared.system.SyncRtSurfaceTransactionApplier; import java.util.List; @@ -144,6 +145,8 @@ public class TaskUtils { */ public static ValueAnimator getRecentsWindowAnimator(TaskView v, boolean skipViewChanges, RemoteAnimationTargetCompat[] targets, final ClipAnimationHelper inOutHelper) { + SyncRtSurfaceTransactionApplier syncTransactionApplier = + new SyncRtSurfaceTransactionApplier(v); final ValueAnimator appAnimator = ValueAnimator.ofFloat(0, 1); appAnimator.setInterpolator(TOUCH_RESPONSE_INTERPOLATOR); appAnimator.addUpdateListener(new MultiValueUpdateListener() { @@ -155,18 +158,10 @@ public class TaskUtils { final RemoteAnimationTargetSet mTargetSet; final RectF mThumbnailRect; - private Surface mSurface; - private long mFrameNumber; { mTargetSet = new RemoteAnimationTargetSet(targets, MODE_OPENING); - inOutHelper.setTaskTransformCallback((t, app) -> { - t.setAlpha(app.leash, mTaskAlpha.value); - - if (!skipViewChanges) { - t.deferTransactionUntil(app.leash, mSurface, mFrameNumber); - } - }); + inOutHelper.setTaskAlphaCallback((t, alpha) -> mTaskAlpha.value); inOutHelper.prepareAnimation(true /* isOpening */); inOutHelper.fromTaskThumbnailView(v.getThumbnail(), (RecentsView) v.getParent(), @@ -179,15 +174,8 @@ public class TaskUtils { @Override public void onUpdate(float percent) { - mSurface = getSurface(v); - mFrameNumber = mSurface != null ? getNextFrameNumber(mSurface) : -1; - if (mFrameNumber == -1) { - // Booo, not cool! Our surface got destroyed, so no reason to animate anything. - Log.w(TAG, "Failed to animate, surface got destroyed."); - return; - } - - RectF taskBounds = inOutHelper.applyTransform(mTargetSet, 1 - percent); + RectF taskBounds = inOutHelper.applyTransform(mTargetSet, 1 - percent, + syncTransactionApplier); if (!skipViewChanges) { float scale = taskBounds.width() / mThumbnailRect.width(); v.setScaleX(scale); diff --git a/quickstep/src/com/android/quickstep/TouchInteractionService.java b/quickstep/src/com/android/quickstep/TouchInteractionService.java index aecb66c77d..49a4ac8bab 100644 --- a/quickstep/src/com/android/quickstep/TouchInteractionService.java +++ b/quickstep/src/com/android/quickstep/TouchInteractionService.java @@ -49,6 +49,7 @@ import com.android.quickstep.views.RecentsView; import com.android.systemui.shared.recents.IOverviewProxy; import com.android.systemui.shared.recents.ISystemUiProxy; import com.android.systemui.shared.system.ActivityManagerWrapper; +import com.android.systemui.shared.system.ChoreographerCompat; import com.android.systemui.shared.system.NavigationBarCompat.HitTarget; /** @@ -406,6 +407,6 @@ public class TouchInteractionService extends Service { sRemoteUiThread.start(); } new Handler(sRemoteUiThread.getLooper()).post(() -> - mBackgroundThreadChoreographer = Choreographer.getInstance()); + mBackgroundThreadChoreographer = ChoreographerCompat.getSfInstance()); } } diff --git a/quickstep/src/com/android/quickstep/WindowTransformSwipeHandler.java b/quickstep/src/com/android/quickstep/WindowTransformSwipeHandler.java index d171f69452..cfa46b1a28 100644 --- a/quickstep/src/com/android/quickstep/WindowTransformSwipeHandler.java +++ b/quickstep/src/com/android/quickstep/WindowTransformSwipeHandler.java @@ -74,6 +74,7 @@ import com.android.systemui.shared.system.InputConsumerController; import com.android.systemui.shared.system.LatencyTrackerCompat; import com.android.systemui.shared.system.RecentsAnimationControllerCompat; import com.android.systemui.shared.system.RemoteAnimationTargetCompat; +import com.android.systemui.shared.system.SyncRtSurfaceTransactionApplier; import com.android.systemui.shared.system.WindowCallbacksCompat; import com.android.systemui.shared.system.WindowManagerWrapper; @@ -181,6 +182,7 @@ public class WindowTransformSwipeHandler { private T mActivity; private LayoutListener mLayoutListener; private RecentsView mRecentsView; + private SyncRtSurfaceTransactionApplier mSyncTransactionApplier; private QuickScrubController mQuickScrubController; private AnimationFactory mAnimationFactory = (t, i) -> { }; @@ -347,6 +349,7 @@ public class WindowTransformSwipeHandler { } mRecentsView = activity.getOverviewPanel(); + mSyncTransactionApplier = new SyncRtSurfaceTransactionApplier(mRecentsView); mQuickScrubController = mRecentsView.getQuickScrubController(); mLayoutListener = mActivityControlHelper.createLayoutListener(mActivity); @@ -504,7 +507,11 @@ public class WindowTransformSwipeHandler { RecentsAnimationControllerCompat controller = mRecentsAnimationWrapper.getController(); if (controller != null) { - mClipAnimationHelper.applyTransform(mRecentsAnimationWrapper.targetSet, shift); + + mClipAnimationHelper.applyTransform(mRecentsAnimationWrapper.targetSet, shift, + Looper.myLooper() == mMainThreadHandler.getLooper() + ? mSyncTransactionApplier + : null); // TODO: This logic is spartanic! boolean passedThreshold = shift > 0.12f; diff --git a/quickstep/src/com/android/quickstep/util/ClipAnimationHelper.java b/quickstep/src/com/android/quickstep/util/ClipAnimationHelper.java index a654482f97..df70a8a394 100644 --- a/quickstep/src/com/android/quickstep/util/ClipAnimationHelper.java +++ b/quickstep/src/com/android/quickstep/util/ClipAnimationHelper.java @@ -30,6 +30,7 @@ import android.graphics.RectF; import android.os.Build; import android.os.RemoteException; import android.support.annotation.Nullable; +import android.view.Surface; import android.view.animation.Interpolator; import com.android.launcher3.BaseDraggingActivity; @@ -44,10 +45,13 @@ import com.android.quickstep.views.TaskThumbnailView; import com.android.systemui.shared.recents.ISystemUiProxy; import com.android.systemui.shared.recents.utilities.RectFEvaluator; import com.android.systemui.shared.system.RemoteAnimationTargetCompat; +import com.android.systemui.shared.system.SyncRtSurfaceTransactionApplier; +import com.android.systemui.shared.system.SyncRtSurfaceTransactionApplier.SurfaceParams; import com.android.systemui.shared.system.TransactionCompat; import com.android.systemui.shared.system.WindowManagerWrapper; import java.util.function.BiConsumer; +import java.util.function.BiFunction; /** * Utility class to handle window clip animation @@ -90,8 +94,8 @@ public class ClipAnimationHelper { // Wether or not applyTransform has been called yet since prepareAnimation() private boolean mIsFirstFrame = true; - private BiConsumer mTaskTransformCallback = - (t, a) -> { }; + private BiFunction mTaskAlphaCallback = + (t, a1) -> a1; private void updateSourceStack(RemoteAnimationTargetCompat target) { mSourceInsets.set(target.contentInsets); @@ -134,11 +138,11 @@ public class ClipAnimationHelper { } public void prepareAnimation(boolean isOpening) { - mIsFirstFrame = true; mBoostModeTargetLayers = isOpening ? MODE_OPENING : MODE_CLOSING; } - public RectF applyTransform(RemoteAnimationTargetSet targetSet, float progress) { + public RectF applyTransform(RemoteAnimationTargetSet targetSet, float progress, + @Nullable SyncRtSurfaceTransactionApplier syncTransactionApplier) { RectF currentRect; mTmpRectF.set(mTargetRect); Utilities.scaleRectFAboutCenter(mTmpRectF, mTargetScale); @@ -159,35 +163,51 @@ public class ClipAnimationHelper { mClipRect.bottom = (int) (mSourceStackBounds.height() - (mSourceWindowClipInsets.bottom * progress)); - TransactionCompat transaction = new TransactionCompat(); - if (mIsFirstFrame) { - RemoteAnimationProvider.prepareTargetsForFirstFrame(targetSet.unfilteredApps, - transaction, mBoostModeTargetLayers); - mIsFirstFrame = false; - } - for (RemoteAnimationTargetCompat app : targetSet.apps) { - if (app.activityType != RemoteAnimationTargetCompat.ACTIVITY_TYPE_HOME) { - mTmpMatrix.setRectToRect(mSourceRect, currentRect, ScaleToFit.FILL); - mTmpMatrix.postTranslate(app.position.x, app.position.y); - transaction.setMatrix(app.leash, mTmpMatrix) - .setWindowCrop(app.leash, mClipRect); + SurfaceParams[] params = new SurfaceParams[targetSet.unfilteredApps.length]; + for (int i = 0; i < targetSet.unfilteredApps.length; i++) { + RemoteAnimationTargetCompat app = targetSet.unfilteredApps[i]; + mTmpMatrix.setTranslate(app.position.x, app.position.y); + Rect crop = app.sourceContainerBounds; + float alpha = 1f; + 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); + crop = mClipRect; + } + + if (app.isNotInRecents + || app.activityType == RemoteAnimationTargetCompat.ACTIVITY_TYPE_HOME) { + alpha = 1 - progress; + } + + alpha = mTaskAlphaCallback.apply(app, alpha); } - if (app.isNotInRecents - || app.activityType == RemoteAnimationTargetCompat.ACTIVITY_TYPE_HOME) { - transaction.setAlpha(app.leash, 1 - progress); - } - - mTaskTransformCallback.accept(transaction, app); + params[i] = new SurfaceParams(app.leash, alpha, mTmpMatrix, crop, + RemoteAnimationProvider.getLayer(app, mBoostModeTargetLayers)); } - transaction.setEarlyWakeup(); - transaction.apply(); + applyParams(syncTransactionApplier, params); return currentRect; } - public void setTaskTransformCallback - (BiConsumer callback) { - mTaskTransformCallback = callback; + private void applyParams(@Nullable SyncRtSurfaceTransactionApplier syncTransactionApplier, + SurfaceParams[] params) { + if (syncTransactionApplier != null) { + syncTransactionApplier.scheduleApply(params); + } else { + TransactionCompat t = new TransactionCompat(); + for (SurfaceParams param : params) { + SyncRtSurfaceTransactionApplier.applyParams(t, param); + } + t.setEarlyWakeup(); + t.apply(); + } + } + + public void setTaskAlphaCallback( + BiFunction callback) { + mTaskAlphaCallback = callback; } public void offsetTarget(float scale, float offsetX, float offsetY, Interpolator interpolator) { diff --git a/quickstep/src/com/android/quickstep/util/RemoteAnimationTargetSet.java b/quickstep/src/com/android/quickstep/util/RemoteAnimationTargetSet.java index 04b8be58bf..c3724853ae 100644 --- a/quickstep/src/com/android/quickstep/util/RemoteAnimationTargetSet.java +++ b/quickstep/src/com/android/quickstep/util/RemoteAnimationTargetSet.java @@ -26,6 +26,7 @@ public class RemoteAnimationTargetSet { public final RemoteAnimationTargetCompat[] unfilteredApps; public final RemoteAnimationTargetCompat[] apps; + public final int targetMode; public RemoteAnimationTargetSet(RemoteAnimationTargetCompat[] apps, int targetMode) { ArrayList filteredApps = new ArrayList<>(); @@ -39,6 +40,7 @@ public class RemoteAnimationTargetSet { this.unfilteredApps = apps; this.apps = filteredApps.toArray(new RemoteAnimationTargetCompat[filteredApps.size()]); + this.targetMode = targetMode; } public RemoteAnimationTargetCompat findTask(int taskId) {