mirror of
https://github.com/LawnchairLauncher/lawnchair.git
synced 2026-03-02 08:56:55 +00:00
Address LAUNCHER_APP_LAUNCH_FROM_ICON jank.
- Delay app launch animations by a frame, and skip logic to skip the first frame. - Note the icon pressed state animation still occurs, so there is still some visual feedback for the user that something is happening. Bug: 181901105 Test: ensure animation still looks smooth (using window animation scale & record in slow mo) Change-Id: Ia904b8b96301042c900e0589f33fc625c1c1148b Merged-In: Ia904b8b96301042c900e0589f33fc625c1c1148b
This commit is contained in:
committed by
Jonathan Miranda
parent
2f346b8666
commit
0750f03c96
@@ -38,6 +38,7 @@ import static com.android.launcher3.config.FeatureFlags.KEYGUARD_ANIMATION;
|
||||
import static com.android.launcher3.config.FeatureFlags.SEPARATE_RECENTS_ACTIVITY;
|
||||
import static com.android.launcher3.dragndrop.DragLayer.ALPHA_INDEX_TRANSITIONS;
|
||||
import static com.android.launcher3.statehandlers.DepthController.DEPTH;
|
||||
import static com.android.launcher3.util.DisplayController.getSingleFrameMs;
|
||||
import static com.android.quickstep.TaskUtils.taskIsATargetWithMode;
|
||||
import static com.android.quickstep.TaskViewUtils.findTaskViewToLaunch;
|
||||
import static com.android.systemui.shared.system.QuickStepContract.getWindowCornerRadius;
|
||||
@@ -340,12 +341,17 @@ public class QuickstepTransitionManager implements OnDeviceProfileChangeListener
|
||||
|
||||
final int rotationChange = getRotationChange(appTargets);
|
||||
// Note: the targetBounds are relative to the launcher
|
||||
int startDelay = getSingleFrameMs(mLauncher);
|
||||
Rect windowTargetBounds = getWindowTargetBounds(appTargets, rotationChange);
|
||||
anim.play(getOpeningWindowAnimators(v, appTargets, wallpaperTargets, nonAppTargets,
|
||||
windowTargetBounds, areAllTargetsTranslucent(appTargets), rotationChange));
|
||||
Animator windowAnimator = getOpeningWindowAnimators(v, appTargets, wallpaperTargets,
|
||||
nonAppTargets, windowTargetBounds, areAllTargetsTranslucent(appTargets),
|
||||
rotationChange);
|
||||
windowAnimator.setStartDelay(startDelay);
|
||||
anim.play(windowAnimator);
|
||||
if (launcherClosing) {
|
||||
// Delay animation by a frame to avoid jank.
|
||||
Pair<AnimatorSet, Runnable> launcherContentAnimator =
|
||||
getLauncherContentAnimator(true /* isAppOpening */);
|
||||
getLauncherContentAnimator(true /* isAppOpening */, startDelay);
|
||||
anim.play(launcherContentAnimator.first);
|
||||
anim.addListener(new AnimatorListenerAdapter() {
|
||||
@Override
|
||||
@@ -436,8 +442,10 @@ public class QuickstepTransitionManager implements OnDeviceProfileChangeListener
|
||||
*
|
||||
* @param isAppOpening True when this is called when an app is opening.
|
||||
* False when this is called when an app is closing.
|
||||
* @param startDelay Start delay duration.
|
||||
*/
|
||||
private Pair<AnimatorSet, Runnable> getLauncherContentAnimator(boolean isAppOpening) {
|
||||
private Pair<AnimatorSet, Runnable> getLauncherContentAnimator(boolean isAppOpening,
|
||||
int startDelay) {
|
||||
AnimatorSet launcherAnimator = new AnimatorSet();
|
||||
Runnable endListener;
|
||||
|
||||
@@ -528,6 +536,8 @@ public class QuickstepTransitionManager implements OnDeviceProfileChangeListener
|
||||
mLauncher.getWorkspace().getPageIndicator().skipAnimationsToEnd();
|
||||
};
|
||||
}
|
||||
|
||||
launcherAnimator.setStartDelay(startDelay);
|
||||
return new Pair<>(launcherAnimator, endListener);
|
||||
}
|
||||
|
||||
@@ -633,7 +643,7 @@ public class QuickstepTransitionManager implements OnDeviceProfileChangeListener
|
||||
? 0 : getWindowCornerRadius(mLauncher.getResources());
|
||||
final float finalShadowRadius = appTargetsAreTranslucent ? 0 : mMaxShadowRadius;
|
||||
|
||||
appAnimator.addUpdateListener(new MultiValueUpdateListener() {
|
||||
MultiValueUpdateListener listener = new MultiValueUpdateListener() {
|
||||
FloatProp mDx = new FloatProp(0, prop.dX, 0, prop.xDuration, AGGRESSIVE_EASE);
|
||||
FloatProp mDy = new FloatProp(0, prop.dY, 0, prop.yDuration, AGGRESSIVE_EASE);
|
||||
|
||||
@@ -662,7 +672,7 @@ public class QuickstepTransitionManager implements OnDeviceProfileChangeListener
|
||||
ANIMATION_NAV_FADE_IN_DURATION, NAV_FADE_IN_INTERPOLATOR);
|
||||
|
||||
@Override
|
||||
public void onUpdate(float percent) {
|
||||
public void onUpdate(float percent, boolean initOnly) {
|
||||
// Calculate the size of the scaled icon.
|
||||
float iconWidth = launcherIconBounds.width() * mIconScaleToFitScreen.value;
|
||||
float iconHeight = launcherIconBounds.height() * mIconScaleToFitScreen.value;
|
||||
@@ -707,6 +717,12 @@ public class QuickstepTransitionManager implements OnDeviceProfileChangeListener
|
||||
floatingIconBounds.right += offsetX;
|
||||
floatingIconBounds.bottom += offsetY;
|
||||
|
||||
if (initOnly) {
|
||||
floatingView.update(mIconAlpha.value, 255, floatingIconBounds, percent, 0f,
|
||||
mWindowRadius.value * scale, true /* isOpening */);
|
||||
return;
|
||||
}
|
||||
|
||||
ArrayList<SurfaceParams> params = new ArrayList<>();
|
||||
for (int i = appTargets.length - 1; i >= 0; i--) {
|
||||
RemoteAnimationTargetCompat target = appTargets[i];
|
||||
@@ -779,7 +795,10 @@ public class QuickstepTransitionManager implements OnDeviceProfileChangeListener
|
||||
|
||||
surfaceApplier.scheduleApply(params.toArray(new SurfaceParams[params.size()]));
|
||||
}
|
||||
});
|
||||
};
|
||||
appAnimator.addUpdateListener(listener);
|
||||
// Since we added a start delay, call update here to init the FloatingIconView properly.
|
||||
listener.onUpdate(0, true /* initOnly */);
|
||||
|
||||
animatorSet.playTogether(appAnimator, getBackgroundAnimator(appTargets));
|
||||
return animatorSet;
|
||||
@@ -869,7 +888,7 @@ public class QuickstepTransitionManager implements OnDeviceProfileChangeListener
|
||||
ANIMATION_NAV_FADE_IN_DURATION, NAV_FADE_IN_INTERPOLATOR);
|
||||
|
||||
@Override
|
||||
public void onUpdate(float percent) {
|
||||
public void onUpdate(float percent, boolean initOnly) {
|
||||
widgetBackgroundBounds.set(mDx.value - mWidth.value / 2f,
|
||||
mDy.value - mHeight.value / 2f, mDx.value + mWidth.value / 2f,
|
||||
mDy.value + mHeight.value / 2f);
|
||||
@@ -1128,7 +1147,7 @@ public class QuickstepTransitionManager implements OnDeviceProfileChangeListener
|
||||
DEACCEL_1_7);
|
||||
|
||||
@Override
|
||||
public void onUpdate(float percent) {
|
||||
public void onUpdate(float percent, boolean initOnly) {
|
||||
SurfaceParams[] params = new SurfaceParams[appTargets.length];
|
||||
for (int i = appTargets.length - 1; i >= 0; i--) {
|
||||
RemoteAnimationTargetCompat target = appTargets[i];
|
||||
@@ -1278,8 +1297,7 @@ public class QuickstepTransitionManager implements OnDeviceProfileChangeListener
|
||||
|
||||
if (mLauncher.isInState(LauncherState.ALL_APPS)) {
|
||||
Pair<AnimatorSet, Runnable> contentAnimator =
|
||||
getLauncherContentAnimator(false /* isAppOpening */);
|
||||
contentAnimator.first.setStartDelay(LAUNCHER_RESUME_START_DELAY);
|
||||
getLauncherContentAnimator(false, LAUNCHER_RESUME_START_DELAY);
|
||||
anim.play(contentAnimator.first);
|
||||
anim.addListener(new AnimatorListenerAdapter() {
|
||||
@Override
|
||||
@@ -1328,27 +1346,32 @@ public class QuickstepTransitionManager implements OnDeviceProfileChangeListener
|
||||
|
||||
final boolean launchingFromWidget = mV instanceof LauncherAppWidgetHostView;
|
||||
final boolean launchingFromRecents = isLaunchingFromRecents(mV, appTargets);
|
||||
final boolean skipFirstFrame;
|
||||
if (launchingFromWidget) {
|
||||
composeWidgetLaunchAnimator(anim, (LauncherAppWidgetHostView) mV, appTargets,
|
||||
wallpaperTargets, nonAppTargets);
|
||||
addCujInstrumentation(
|
||||
anim, InteractionJankMonitorWrapper.CUJ_APP_LAUNCH_FROM_WIDGET);
|
||||
skipFirstFrame = true;
|
||||
} else if (launchingFromRecents) {
|
||||
composeRecentsLaunchAnimator(anim, mV, appTargets, wallpaperTargets, nonAppTargets,
|
||||
launcherClosing);
|
||||
addCujInstrumentation(
|
||||
anim, InteractionJankMonitorWrapper.CUJ_APP_LAUNCH_FROM_RECENTS);
|
||||
skipFirstFrame = true;
|
||||
} else {
|
||||
composeIconLaunchAnimator(anim, mV, appTargets, wallpaperTargets, nonAppTargets,
|
||||
launcherClosing);
|
||||
addCujInstrumentation(anim, InteractionJankMonitorWrapper.CUJ_APP_LAUNCH_FROM_ICON);
|
||||
skipFirstFrame = false;
|
||||
}
|
||||
|
||||
if (launcherClosing) {
|
||||
anim.addListener(mForceInvisibleListener);
|
||||
}
|
||||
|
||||
result.setAnimation(anim, mLauncher, mOnEndCallback::executeAllAndDestroy);
|
||||
result.setAnimation(anim, mLauncher, mOnEndCallback::executeAllAndDestroy,
|
||||
skipFirstFrame);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user