Use SyncRtSurfaceTransactionApplier for app opening
To ensure 100% synchronization, fixing jank.
Test: Open and close apps
Bug: 78611607
Change-Id: I6843e88ab1de0b8e7d80e6a6f547b895b527d093
diff --git a/quickstep/libs/sysui_shared.jar b/quickstep/libs/sysui_shared.jar
index 53a6ceb..41bf729 100644
--- a/quickstep/libs/sysui_shared.jar
+++ b/quickstep/libs/sysui_shared.jar
Binary files differ
diff --git a/quickstep/src/com/android/launcher3/LauncherAppTransitionManagerImpl.java b/quickstep/src/com/android/launcher3/LauncherAppTransitionManagerImpl.java
index 3075c3f..2c5b815 100644
--- a/quickstep/src/com/android/launcher3/LauncherAppTransitionManagerImpl.java
+++ b/quickstep/src/com/android/launcher3/LauncherAppTransitionManagerImpl.java
@@ -71,6 +71,7 @@
import com.android.quickstep.util.ClipAnimationHelper;
import com.android.quickstep.util.MultiValueUpdateListener;
import com.android.quickstep.util.RemoteAnimationProvider;
+import com.android.quickstep.util.RemoteAnimationTargetSet;
import com.android.quickstep.views.RecentsView;
import com.android.quickstep.views.TaskView;
import com.android.systemui.shared.system.ActivityCompat;
@@ -79,7 +80,8 @@
import com.android.systemui.shared.system.RemoteAnimationDefinitionCompat;
import com.android.systemui.shared.system.RemoteAnimationRunnerCompat;
import com.android.systemui.shared.system.RemoteAnimationTargetCompat;
-import com.android.systemui.shared.system.TransactionCompat;
+import com.android.systemui.shared.system.SyncRtSurfaceTransactionApplier;
+import com.android.systemui.shared.system.SyncRtSurfaceTransactionApplier.SurfaceParams;
import com.android.systemui.shared.system.WindowManagerWrapper;
/**
@@ -545,22 +547,21 @@
Rect crop = new Rect();
Matrix matrix = new Matrix();
+ RemoteAnimationTargetSet openingTargets = new RemoteAnimationTargetSet(targets,
+ MODE_OPENING);
+ RemoteAnimationTargetSet closingTargets = new RemoteAnimationTargetSet(targets,
+ MODE_CLOSING);
+ SyncRtSurfaceTransactionApplier surfaceApplier = new SyncRtSurfaceTransactionApplier(
+ mFloatingView);
+
ValueAnimator appAnimator = ValueAnimator.ofFloat(0, 1);
appAnimator.setDuration(APP_LAUNCH_DURATION);
appAnimator.addUpdateListener(new MultiValueUpdateListener() {
// Fade alpha for the app window.
FloatProp mAlpha = new FloatProp(0f, 1f, 0, 60, LINEAR);
- boolean isFirstFrame = true;
@Override
public void onUpdate(float percent) {
- final Surface surface = getSurface(mFloatingView);
- final long frameNumber = surface != null ? getNextFrameNumber(surface) : -1;
- if (frameNumber == -1) {
- // Booo, not cool! Our surface got destroyed, so no reason to animate anything.
- Log.w(TAG, "Failed to animate, surface got destroyed.");
- return;
- }
final float easePercent = AGGRESSIVE_EASE.getInterpolation(percent);
// Calculate app icon size.
@@ -571,7 +572,6 @@
float scaleX = iconWidth / windowTargetBounds.width();
float scaleY = iconHeight / windowTargetBounds.height();
float scale = Math.min(1f, Math.min(scaleX, scaleY));
- matrix.setScale(scale, scale);
// Position the scaled window on top of the icon
int windowWidth = windowTargetBounds.width();
@@ -585,7 +585,6 @@
float transX0 = floatingViewBounds[0] - offsetX;
float transY0 = floatingViewBounds[1] - offsetY;
- matrix.postTranslate(transX0, transY0);
// Animate the window crop so that it starts off as a square, and then reveals
// horizontally.
@@ -596,23 +595,27 @@
crop.right = windowWidth;
crop.bottom = (int) (crop.top + cropHeight);
- TransactionCompat t = new TransactionCompat();
- if (isFirstFrame) {
- RemoteAnimationProvider.prepareTargetsForFirstFrame(targets, t, MODE_OPENING);
- isFirstFrame = false;
- }
- for (RemoteAnimationTargetCompat target : targets) {
- if (target.mode == MODE_OPENING) {
- t.setAlpha(target.leash, mAlpha.value);
- t.setMatrix(target.leash, matrix);
- t.setWindowCrop(target.leash, crop);
- t.deferTransactionUntil(target.leash, surface, getNextFrameNumber(surface));
- }
- }
- t.setEarlyWakeup();
- t.apply();
+ SurfaceParams[] params = new SurfaceParams[targets.length];
+ for (int i = targets.length - 1; i >= 0; i--) {
+ RemoteAnimationTargetCompat target = targets[i];
- matrix.reset();
+ Rect targetCrop;
+ float alpha;
+ if (target.mode == MODE_OPENING) {
+ matrix.setScale(scale, scale);
+ matrix.postTranslate(transX0, transY0);
+ targetCrop = crop;
+ alpha = mAlpha.value;
+ } else {
+ matrix.reset();
+ alpha = 1f;
+ targetCrop = target.sourceContainerBounds;
+ }
+
+ params[i] = new SurfaceParams(target.leash, alpha, matrix, targetCrop,
+ RemoteAnimationProvider.getLayer(target, MODE_OPENING));
+ }
+ surfaceApplier.scheduleApply(params);
}
});
return appAnimator;
@@ -692,6 +695,8 @@
* Animator that controls the transformations of the windows the targets that are closing.
*/
private Animator getClosingWindowAnimators(RemoteAnimationTargetCompat[] targets) {
+ SyncRtSurfaceTransactionApplier surfaceApplier =
+ new SyncRtSurfaceTransactionApplier(mDragLayer);
Matrix matrix = new Matrix();
ValueAnimator closingAnimator = ValueAnimator.ofFloat(0, 1);
int duration = CLOSING_TRANSITION_DURATION_MS;
@@ -701,30 +706,28 @@
FloatProp mScale = new FloatProp(1f, 1f, 0, duration, DEACCEL_1_7);
FloatProp mAlpha = new FloatProp(1f, 0f, 25, 125, LINEAR);
- boolean isFirstFrame = true;
-
@Override
public void onUpdate(float percent) {
- TransactionCompat t = new TransactionCompat();
- if (isFirstFrame) {
- RemoteAnimationProvider.prepareTargetsForFirstFrame(targets, t, MODE_CLOSING);
- isFirstFrame = false;
- }
- for (RemoteAnimationTargetCompat app : targets) {
- if (app.mode == RemoteAnimationTargetCompat.MODE_CLOSING) {
- t.setAlpha(app.leash, mAlpha.value);
+ SurfaceParams[] params = new SurfaceParams[targets.length];
+ for (int i = targets.length - 1; i >= 0; i--) {
+ RemoteAnimationTargetCompat target = targets[i];
+ float alpha;
+ if (target.mode == MODE_CLOSING) {
matrix.setScale(mScale.value, mScale.value,
- app.sourceContainerBounds.centerX(),
- app.sourceContainerBounds.centerY());
+ target.sourceContainerBounds.centerX(),
+ target.sourceContainerBounds.centerY());
matrix.postTranslate(0, mDy.value);
- matrix.postTranslate(app.position.x, app.position.y);
- t.setMatrix(app.leash, matrix);
+ matrix.postTranslate(target.position.x, target.position.y);
+ alpha = mAlpha.value;
+ } else {
+ matrix.reset();
+ alpha = 1f;
}
+ params[i] = new SurfaceParams(target.leash, alpha, matrix,
+ target.sourceContainerBounds,
+ RemoteAnimationProvider.getLayer(target, MODE_CLOSING));
}
- t.setEarlyWakeup();
- t.apply();
-
- matrix.reset();
+ surfaceApplier.scheduleApply(params);
}
});
diff --git a/quickstep/src/com/android/quickstep/util/RemoteAnimationProvider.java b/quickstep/src/com/android/quickstep/util/RemoteAnimationProvider.java
index bbf223d..a7e6d74 100644
--- a/quickstep/src/com/android/quickstep/util/RemoteAnimationProvider.java
+++ b/quickstep/src/com/android/quickstep/util/RemoteAnimationProvider.java
@@ -28,6 +28,8 @@
@FunctionalInterface
public interface RemoteAnimationProvider {
+ static final int Z_BOOST_BASE = 800570000;
+
AnimatorSet createWindowAnimation(RemoteAnimationTargetCompat[] targets);
default ActivityOptions toActivityOptions(Handler handler, long duration) {
@@ -54,11 +56,14 @@
static void prepareTargetsForFirstFrame(RemoteAnimationTargetCompat[] targets,
TransactionCompat t, int boostModeTargets) {
for (RemoteAnimationTargetCompat target : targets) {
- int layer = target.mode == boostModeTargets
- ? Integer.MAX_VALUE
- : target.prefixOrderIndex;
- t.setLayer(target.leash, layer);
+ t.setLayer(target.leash, getLayer(target, boostModeTargets));
t.show(target.leash);
}
}
+
+ static int getLayer(RemoteAnimationTargetCompat target, int boostModeTarget) {
+ return target.mode == boostModeTarget
+ ? Z_BOOST_BASE + target.prefixOrderIndex
+ : target.prefixOrderIndex;
+ }
}