Fix Launcher icons not animated during unfold

If icons are re-bound during the animation, they were not moved. I was able to reproduce this case 100% of times by folding, restarting launcher and unfolding. From a perfetto trace it seems that in this case `finishBindingItems` was called after the animation already started, therefore not registering any view.

With this cl, items are animated also after they are rebound.

Bug: 197834977
Test: folded -> restarted launcher -> unfolded -> verified icons are now moving towards the center
Change-Id: I5b001c502860c17d6ea5d54d099f04b2ddf1820a
This commit is contained in:
Nicolo' Mazzucato
2022-02-16 17:30:48 +01:00
parent e424f57dcb
commit d4a5bb244a
3 changed files with 52 additions and 11 deletions
@@ -65,6 +65,7 @@ import com.android.launcher3.util.ActivityOptionsWrapper;
import com.android.launcher3.util.DisplayController;
import com.android.launcher3.util.IntSet;
import com.android.launcher3.util.ObjectWrapper;
import com.android.launcher3.util.RunnableList;
import com.android.launcher3.util.SplitConfigurationOptions.SplitPositionOption;
import com.android.launcher3.util.UiThreadHelper;
import com.android.quickstep.OverviewCommandHelper;
@@ -496,6 +497,20 @@ public abstract class BaseQuickstepLauncher extends Launcher
WellbeingModel.INSTANCE.get(this);
}
@Override
public void onInitialBindComplete(IntSet boundPages, RunnableList pendingTasks) {
pendingTasks.add(() -> {
// This is added in pending task as we need to wait for views to be positioned
// correctly before registering them for the animation.
if (mLauncherUnfoldAnimationController != null) {
// This is needed in case items are rebound while the unfold animation is in
// progress.
mLauncherUnfoldAnimationController.updateRegisteredViewsIfNeeded();
}
});
super.onInitialBindComplete(boundPages, pendingTasks);
}
@Override
public Stream<SystemShortcut.Factory> getSupportedShortcuts() {
Stream<SystemShortcut.Factory> base = Stream.of(WellbeingModel.SHORTCUT_FACTORY);
@@ -36,6 +36,8 @@ public abstract class BaseUnfoldMoveFromCenterAnimator implements TransitionProg
private final Map<ViewGroup, Boolean> mOriginalClipToPadding = new HashMap<>();
private final Map<ViewGroup, Boolean> mOriginalClipChildren = new HashMap<>();
private boolean mAnimationInProgress = false;
public BaseUnfoldMoveFromCenterAnimator(WindowManager windowManager) {
mMoveFromCenterAnimation = new UnfoldMoveFromCenterAnimator(windowManager,
new LauncherViewsMoveFromCenterTranslationApplier());
@@ -44,6 +46,7 @@ public abstract class BaseUnfoldMoveFromCenterAnimator implements TransitionProg
@CallSuper
@Override
public void onTransitionStarted() {
mAnimationInProgress = true;
mMoveFromCenterAnimation.updateDisplayProperties();
onPrepareViewsForAnimation();
onTransitionProgress(0f);
@@ -58,7 +61,23 @@ public abstract class BaseUnfoldMoveFromCenterAnimator implements TransitionProg
@CallSuper
@Override
public void onTransitionFinished() {
mAnimationInProgress = false;
mMoveFromCenterAnimation.onTransitionFinished();
clearRegisteredViews();
}
/**
* Re-prepares views for animation. This is useful in case views are re-bound while the
* animation is in progress.
*/
public void updateRegisteredViewsIfNeeded() {
if (mAnimationInProgress) {
clearRegisteredViews();
onPrepareViewsForAnimation();
}
}
private void clearRegisteredViews() {
mMoveFromCenterAnimation.clearRegisteredViews();
mOriginalClipChildren.clear();
@@ -48,13 +48,14 @@ public class LauncherUnfoldAnimationController {
SCALE_PROPERTY_FACTORY.get(SCALE_INDEX_UNFOLD_ANIMATION);
private final Launcher mLauncher;
private final ScopedUnfoldTransitionProgressProvider mProgressProvider;
private final NaturalRotationUnfoldProgressProvider mNaturalOrientationProgressProvider;
private final UnfoldMoveFromCenterHotseatAnimator mUnfoldMoveFromCenterHotseatAnimator;
private final UnfoldMoveFromCenterWorkspaceAnimator mUnfoldMoveFromCenterWorkspaceAnimator;
@Nullable
private HorizontalInsettableView mQsbInsettable;
private final ScopedUnfoldTransitionProgressProvider mProgressProvider;
private final NaturalRotationUnfoldProgressProvider mNaturalOrientationProgressProvider;
public LauncherUnfoldAnimationController(
Launcher launcher,
WindowManager windowManager,
@@ -62,21 +63,21 @@ public class LauncherUnfoldAnimationController {
mLauncher = launcher;
mProgressProvider = new ScopedUnfoldTransitionProgressProvider(
unfoldTransitionProgressProvider);
mUnfoldMoveFromCenterHotseatAnimator = new UnfoldMoveFromCenterHotseatAnimator(launcher,
windowManager);
mUnfoldMoveFromCenterWorkspaceAnimator = new UnfoldMoveFromCenterWorkspaceAnimator(launcher,
windowManager);
mNaturalOrientationProgressProvider = new NaturalRotationUnfoldProgressProvider(launcher,
WindowManagerGlobal.getWindowManagerService(), mProgressProvider);
mNaturalOrientationProgressProvider.init();
// Animated in all orientations
mProgressProvider.addCallback(new UnfoldMoveFromCenterWorkspaceAnimator(launcher,
windowManager));
mProgressProvider
.addCallback(new LauncherScaleAnimationListener());
mProgressProvider.addCallback(mUnfoldMoveFromCenterWorkspaceAnimator);
mProgressProvider.addCallback(new LauncherScaleAnimationListener());
// Animated only in natural orientation
mNaturalOrientationProgressProvider
.addCallback(new QsbAnimationListener());
mNaturalOrientationProgressProvider
.addCallback(new UnfoldMoveFromCenterHotseatAnimator(launcher, windowManager));
mNaturalOrientationProgressProvider.addCallback(new QsbAnimationListener());
mNaturalOrientationProgressProvider.addCallback(mUnfoldMoveFromCenterHotseatAnimator);
}
/**
@@ -108,6 +109,12 @@ public class LauncherUnfoldAnimationController {
mNaturalOrientationProgressProvider.destroy();
}
/** Called when launcher finished binding its items. */
public void updateRegisteredViewsIfNeeded() {
mUnfoldMoveFromCenterHotseatAnimator.updateRegisteredViewsIfNeeded();
mUnfoldMoveFromCenterWorkspaceAnimator.updateRegisteredViewsIfNeeded();
}
private class QsbAnimationListener implements TransitionProgressListener {
@Override