diff --git a/quickstep/src/com/android/launcher3/hybridhotseat/HotseatPredictionController.java b/quickstep/src/com/android/launcher3/hybridhotseat/HotseatPredictionController.java index 67ed5fb5e5..5dcf84c249 100644 --- a/quickstep/src/com/android/launcher3/hybridhotseat/HotseatPredictionController.java +++ b/quickstep/src/com/android/launcher3/hybridhotseat/HotseatPredictionController.java @@ -17,6 +17,7 @@ package com.android.launcher3.hybridhotseat; import static com.android.launcher3.LauncherAnimUtils.SCALE_PROPERTY; import static com.android.launcher3.LauncherState.NORMAL; +import static com.android.launcher3.anim.AnimatorListeners.forSuccessCallback; import static com.android.launcher3.hybridhotseat.HotseatEduController.getSettingsIntent; import static com.android.launcher3.logging.StatsLogManager.LauncherEvent.LAUNCHER_HOTSEAT_PREDICTION_PINNED; import static com.android.launcher3.logging.StatsLogManager.LauncherEvent.LAUNCHER_HOTSEAT_RANKED; @@ -150,7 +151,7 @@ public class HotseatPredictionController implements DragController.DragListener, * Shows appropriate hotseat education based on prediction enabled and migration states. */ public void showEdu() { - mLauncher.getStateManager().goToState(NORMAL, true, () -> { + mLauncher.getStateManager().goToState(NORMAL, true, forSuccessCallback(() -> { if (mPredictedItems.isEmpty()) { // launcher has empty predictions set Snackbar.show(mLauncher, R.string.hotsaet_tip_prediction_disabled, @@ -165,7 +166,7 @@ public class HotseatPredictionController implements DragController.DragListener, .collect(Collectors.toList())); eduController.showEdu(); } - }); + })); } /** @@ -255,8 +256,8 @@ public class HotseatPredictionController implements DragController.DragListener, } } if (animate) { - animationSet.addListener(AnimationSuccessListener - .forRunnable(this::removeOutlineDrawings)); + animationSet.addListener( + forSuccessCallback(this::removeOutlineDrawings)); animationSet.start(); } else { removeOutlineDrawings(); diff --git a/quickstep/src/com/android/launcher3/uioverrides/RecentsViewStateController.java b/quickstep/src/com/android/launcher3/uioverrides/RecentsViewStateController.java index 0652d48c11..996d36aadc 100644 --- a/quickstep/src/com/android/launcher3/uioverrides/RecentsViewStateController.java +++ b/quickstep/src/com/android/launcher3/uioverrides/RecentsViewStateController.java @@ -35,7 +35,7 @@ import androidx.annotation.NonNull; import com.android.launcher3.BaseQuickstepLauncher; import com.android.launcher3.LauncherState; -import com.android.launcher3.anim.AnimationSuccessListener; +import com.android.launcher3.anim.AnimatorListeners; import com.android.launcher3.anim.PendingAnimation; import com.android.launcher3.anim.PropertySetter; import com.android.launcher3.states.StateAnimationConfig; @@ -78,7 +78,7 @@ public final class RecentsViewStateController extends mRecentsView.updateEmptyMessage(); } else { builder.addListener( - AnimationSuccessListener.forRunnable(mRecentsView::resetTaskVisuals)); + AnimatorListeners.forSuccessCallback(mRecentsView::resetTaskVisuals)); } // Create or dismiss split screen select animations diff --git a/quickstep/src/com/android/launcher3/uioverrides/touchcontrollers/NavBarToHomeTouchController.java b/quickstep/src/com/android/launcher3/uioverrides/touchcontrollers/NavBarToHomeTouchController.java index b8caf81f14..19d1b32a1b 100644 --- a/quickstep/src/com/android/launcher3/uioverrides/touchcontrollers/NavBarToHomeTouchController.java +++ b/quickstep/src/com/android/launcher3/uioverrides/touchcontrollers/NavBarToHomeTouchController.java @@ -22,6 +22,7 @@ import static com.android.launcher3.LauncherAnimUtils.newCancelListener; import static com.android.launcher3.LauncherState.ALL_APPS; import static com.android.launcher3.LauncherState.NORMAL; import static com.android.launcher3.allapps.AllAppsTransitionController.ALL_APPS_PROGRESS; +import static com.android.launcher3.anim.AnimatorListeners.forEndCallback; import static com.android.launcher3.anim.Interpolators.DEACCEL_3; import static com.android.launcher3.config.FeatureFlags.ENABLE_ALL_APPS_EDU; import static com.android.launcher3.logging.StatsLogManager.LauncherEvent.LAUNCHER_HOME_GESTURE; @@ -38,7 +39,7 @@ import com.android.launcher3.LauncherState; import com.android.launcher3.R; import com.android.launcher3.Utilities; import com.android.launcher3.allapps.AllAppsTransitionController; -import com.android.launcher3.anim.AnimationSuccessListener; +import com.android.launcher3.anim.AnimatorListeners; import com.android.launcher3.anim.AnimatorPlaybackController; import com.android.launcher3.anim.Interpolators; import com.android.launcher3.anim.PendingAnimation; @@ -199,7 +200,7 @@ public class NavBarToHomeTouchController implements TouchController, .animateWithVelocity(velocity); } else { mLauncher.getStateManager().goToState(mEndState, true, - () -> onSwipeInteractionCompleted(mEndState)); + forEndCallback(() -> onSwipeInteractionCompleted(mEndState))); } if (mStartState != mEndState) { logHomeGesture(); @@ -214,7 +215,7 @@ public class NavBarToHomeTouchController implements TouchController, // Quickly return to the state we came from (we didn't move far). ValueAnimator anim = mCurrentAnimation.getAnimationPlayer(); anim.setFloatValues(progress, 0); - anim.addListener(AnimationSuccessListener.forRunnable( + anim.addListener(AnimatorListeners.forSuccessCallback( () -> onSwipeInteractionCompleted(mStartState))); anim.setDuration(80).start(); } diff --git a/quickstep/src/com/android/launcher3/uioverrides/touchcontrollers/NoButtonNavbarToOverviewTouchController.java b/quickstep/src/com/android/launcher3/uioverrides/touchcontrollers/NoButtonNavbarToOverviewTouchController.java index 729e2cb5c6..eb62110065 100644 --- a/quickstep/src/com/android/launcher3/uioverrides/touchcontrollers/NoButtonNavbarToOverviewTouchController.java +++ b/quickstep/src/com/android/launcher3/uioverrides/touchcontrollers/NoButtonNavbarToOverviewTouchController.java @@ -22,6 +22,7 @@ import static com.android.launcher3.LauncherState.HINT_STATE; import static com.android.launcher3.LauncherState.NORMAL; import static com.android.launcher3.LauncherState.OVERVIEW; import static com.android.launcher3.Utilities.EDGE_NAV_BAR; +import static com.android.launcher3.anim.AnimatorListeners.forSuccessCallback; import static com.android.launcher3.anim.Interpolators.ACCEL_DEACCEL; import static com.android.launcher3.util.VibratorWrapper.OVERVIEW_HAPTIC; import static com.android.systemui.shared.system.QuickStepContract.SYSUI_STATE_OVERVIEW_DISABLED; @@ -172,13 +173,13 @@ public class NoButtonNavbarToOverviewTouchController extends PortraitStatesTouch } mNormalToHintOverviewScrimAnimator = null; mCurrentAnimation.getTarget().addListener(newCancelListener(() -> - mLauncher.getStateManager().goToState(OVERVIEW, true, () -> { + mLauncher.getStateManager().goToState(OVERVIEW, true, forSuccessCallback(() -> { mOverviewResistYAnim = AnimatorControllerWithResistance .createRecentsResistanceFromOverviewAnim(mLauncher, null) .createPlaybackController(); mReachedOverview = true; maybeSwipeInteractionToOverviewComplete(); - }))); + })))); mCurrentAnimation.getTarget().removeListener(mClearStateOnCancelListener); mCurrentAnimation.dispatchOnCancel(); diff --git a/quickstep/src/com/android/launcher3/uioverrides/touchcontrollers/NoButtonQuickSwitchTouchController.java b/quickstep/src/com/android/launcher3/uioverrides/touchcontrollers/NoButtonQuickSwitchTouchController.java index 0f64abca61..62687c5f35 100644 --- a/quickstep/src/com/android/launcher3/uioverrides/touchcontrollers/NoButtonQuickSwitchTouchController.java +++ b/quickstep/src/com/android/launcher3/uioverrides/touchcontrollers/NoButtonQuickSwitchTouchController.java @@ -21,6 +21,7 @@ import static com.android.launcher3.LauncherState.OVERVIEW; import static com.android.launcher3.LauncherState.OVERVIEW_ACTIONS; import static com.android.launcher3.LauncherState.QUICK_SWITCH; import static com.android.launcher3.anim.AlphaUpdateListener.ALPHA_CUTOFF_THRESHOLD; +import static com.android.launcher3.anim.AnimatorListeners.forEndCallback; import static com.android.launcher3.anim.Interpolators.ACCEL_0_75; import static com.android.launcher3.anim.Interpolators.DEACCEL_3; import static com.android.launcher3.anim.Interpolators.LINEAR; @@ -418,7 +419,7 @@ public class NoButtonQuickSwitchTouchController implements TouchController, targetState.ordinal > mStartState.ordinal ? LAUNCHER_UNKNOWN_SWIPEUP : LAUNCHER_UNKNOWN_SWIPEDOWN)); - mLauncher.getStateManager().goToState(targetState, false, this::clearState); + mLauncher.getStateManager().goToState(targetState, false, forEndCallback(this::clearState)); } private void cancelAnimations() { diff --git a/quickstep/src/com/android/quickstep/LauncherActivityInterface.java b/quickstep/src/com/android/quickstep/LauncherActivityInterface.java index dffee7fda8..c43d3c9653 100644 --- a/quickstep/src/com/android/quickstep/LauncherActivityInterface.java +++ b/quickstep/src/com/android/quickstep/LauncherActivityInterface.java @@ -19,6 +19,7 @@ import static com.android.launcher3.LauncherState.BACKGROUND_APP; import static com.android.launcher3.LauncherState.NORMAL; import static com.android.launcher3.LauncherState.OVERVIEW; import static com.android.launcher3.LauncherState.QUICK_SWITCH; +import static com.android.launcher3.anim.AnimatorListeners.forEndCallback; import static com.android.launcher3.anim.Interpolators.LINEAR; import static com.android.systemui.shared.system.QuickStepContract.SYSUI_STATE_IME_SHOWING; @@ -192,7 +193,8 @@ public final class LauncherActivityInterface extends closeOverlay(); launcher.getStateManager().goToState(OVERVIEW, - launcher.getStateManager().shouldAnimateStateChange(), onCompleteCallback); + launcher.getStateManager().shouldAnimateStateChange(), + onCompleteCallback == null ? null : forEndCallback(onCompleteCallback)); return true; } diff --git a/quickstep/src/com/android/quickstep/interaction/SwipeUpGestureTutorialController.java b/quickstep/src/com/android/quickstep/interaction/SwipeUpGestureTutorialController.java index 1aa64fae1c..66e04008f6 100644 --- a/quickstep/src/com/android/quickstep/interaction/SwipeUpGestureTutorialController.java +++ b/quickstep/src/com/android/quickstep/interaction/SwipeUpGestureTutorialController.java @@ -43,7 +43,7 @@ import androidx.annotation.Nullable; import com.android.launcher3.DeviceProfile; import com.android.launcher3.InvariantDeviceProfile; import com.android.launcher3.Utilities; -import com.android.launcher3.anim.AnimationSuccessListener; +import com.android.launcher3.anim.AnimatorListeners; import com.android.launcher3.anim.AnimatorPlaybackController; import com.android.launcher3.anim.PendingAnimation; import com.android.quickstep.AnimatedFloat; @@ -156,7 +156,7 @@ abstract class SwipeUpGestureTutorialController extends TutorialController { fadeAnim.setViewAlpha(mFakePreviousTaskView, 0, ACCEL); } if (onEndRunnable != null) { - fadeAnim.addListener(AnimationSuccessListener.forRunnable(onEndRunnable)); + fadeAnim.addListener(AnimatorListeners.forSuccessCallback(onEndRunnable)); } AnimatorSet animset = fadeAnim.buildAnim(); animset.setStartDelay(100); @@ -174,7 +174,7 @@ abstract class SwipeUpGestureTutorialController extends TutorialController { anim.setViewAlpha(mFakePreviousTaskView, 0, ACCEL); } if (onEndRunnable != null) { - anim.addListener(AnimationSuccessListener.forRunnable(onEndRunnable)); + anim.addListener(AnimatorListeners.forSuccessCallback(onEndRunnable)); } } AnimatorSet animset = anim.buildAnim(); @@ -205,10 +205,10 @@ abstract class SwipeUpGestureTutorialController extends TutorialController { PendingAnimation fadeAnim = new PendingAnimation(300); fadeAnim.setViewAlpha(mFakeIconView, 0, ACCEL); if (onEndRunnable != null) { - fadeAnim.addListener(AnimationSuccessListener.forRunnable(onEndRunnable)); + fadeAnim.addListener(AnimatorListeners.forSuccessCallback(onEndRunnable)); } AnimatorSet animset = fadeAnim.buildAnim(); - rectAnim.addAnimatorListener(AnimationSuccessListener.forRunnable(animset::start)); + rectAnim.addAnimatorListener(AnimatorListeners.forSuccessCallback(animset::start)); mRunningWindowAnim = RunningWindowAnim.wrap(rectAnim); } diff --git a/quickstep/src/com/android/quickstep/interaction/TutorialController.java b/quickstep/src/com/android/quickstep/interaction/TutorialController.java index 55972adcbe..1128a7ca24 100644 --- a/quickstep/src/com/android/quickstep/interaction/TutorialController.java +++ b/quickstep/src/com/android/quickstep/interaction/TutorialController.java @@ -38,7 +38,7 @@ import androidx.appcompat.app.AlertDialog; import androidx.appcompat.content.res.AppCompatResources; import com.android.launcher3.R; -import com.android.launcher3.anim.AnimationSuccessListener; +import com.android.launcher3.anim.AnimatorListeners; import com.android.launcher3.views.ClipIconView; import com.android.quickstep.interaction.EdgeBackGestureHandler.BackGestureAttemptCallback; import com.android.quickstep.interaction.NavBarGestureHandler.NavBarGestureAttemptCallback; @@ -139,7 +139,7 @@ abstract class TutorialController implements BackGestureAttemptCallback, } void fadeTaskViewAndRun(Runnable r) { - mFakeTaskView.animate().alpha(0).setListener(AnimationSuccessListener.forRunnable(r)); + mFakeTaskView.animate().alpha(0).setListener(AnimatorListeners.forSuccessCallback(r)); } @StringRes @@ -348,8 +348,8 @@ abstract class TutorialController implements BackGestureAttemptCallback, mContext, getMockLauncherResId())); mFakeTaskView.setBackground(AppCompatResources.getDrawable( mContext, getMockAppTaskThumbnailResId())); - mFakeTaskView.animate().alpha(1).setListener(AnimationSuccessListener.forRunnable( - () -> mFakeTaskView.animate().cancel())); + mFakeTaskView.animate().alpha(1).setListener( + AnimatorListeners.forSuccessCallback(() -> mFakeTaskView.animate().cancel())); mFakePreviousTaskView.setBackground(AppCompatResources.getDrawable( mContext, getMockPreviousAppTaskThumbnailResId())); mFakeIconView.setBackground(AppCompatResources.getDrawable( diff --git a/quickstep/src/com/android/quickstep/views/RecentsView.java b/quickstep/src/com/android/quickstep/views/RecentsView.java index 4800596bde..a36c9af5fa 100644 --- a/quickstep/src/com/android/quickstep/views/RecentsView.java +++ b/quickstep/src/com/android/quickstep/views/RecentsView.java @@ -111,6 +111,7 @@ import com.android.launcher3.PagedView; import com.android.launcher3.R; import com.android.launcher3.Utilities; import com.android.launcher3.anim.AnimationSuccessListener; +import com.android.launcher3.anim.AnimatorListeners; import com.android.launcher3.anim.AnimatorPlaybackController; import com.android.launcher3.anim.PendingAnimation; import com.android.launcher3.anim.SpringProperty; @@ -120,7 +121,6 @@ import com.android.launcher3.icons.cache.HandlerRunnable; import com.android.launcher3.statehandlers.DepthController; import com.android.launcher3.statemanager.BaseState; import com.android.launcher3.statemanager.StatefulActivity; -import com.android.launcher3.testing.TestProtocol; import com.android.launcher3.touch.OverScroll; import com.android.launcher3.touch.PagedOrientationHandler; import com.android.launcher3.util.DynamicResource; @@ -1672,7 +1672,7 @@ public abstract class RecentsView { + pa.addListener(AnimatorListeners.forSuccessCallback(() -> { setLayoutRotation(newRotation, mOrientationState.getDisplayRotation()); mActivity.getDragLayer().recreateControllers(); updateChildTaskOrientations(); diff --git a/src/com/android/launcher3/Workspace.java b/src/com/android/launcher3/Workspace.java index 47c67b9796..5ba7623ece 100644 --- a/src/com/android/launcher3/Workspace.java +++ b/src/com/android/launcher3/Workspace.java @@ -25,6 +25,7 @@ import static com.android.launcher3.LauncherState.FLAG_WORKSPACE_INACCESSIBLE; import static com.android.launcher3.LauncherState.HINT_STATE; import static com.android.launcher3.LauncherState.NORMAL; import static com.android.launcher3.LauncherState.SPRING_LOADED; +import static com.android.launcher3.anim.AnimatorListeners.forSuccessCallback; import static com.android.launcher3.config.FeatureFlags.ADAPTIVE_ICON_WINDOW_ANIM; import static com.android.launcher3.dragndrop.DragLayer.ALPHA_INDEX_OVERLAY; import static com.android.launcher3.logging.StatsLogManager.LAUNCHER_STATE_HOME; @@ -1946,8 +1947,8 @@ public class Workspace extends PagedView } parent.onDropChild(cell); - mLauncher.getStateManager().goToState( - NORMAL, SPRING_LOADED_EXIT_DELAY, onCompleteRunnable); + mLauncher.getStateManager().goToState(NORMAL, SPRING_LOADED_EXIT_DELAY, + onCompleteRunnable == null ? null : forSuccessCallback(onCompleteRunnable)); mStatsLogManager.logger().withItemInfo(d.dragInfo).withInstanceId(d.logInstanceId) .log(LauncherEvent.LAUNCHER_ITEM_DROP_COMPLETED); } diff --git a/src/com/android/launcher3/accessibility/LauncherAccessibilityDelegate.java b/src/com/android/launcher3/accessibility/LauncherAccessibilityDelegate.java index c580d47994..2b36f19226 100644 --- a/src/com/android/launcher3/accessibility/LauncherAccessibilityDelegate.java +++ b/src/com/android/launcher3/accessibility/LauncherAccessibilityDelegate.java @@ -3,6 +3,7 @@ package com.android.launcher3.accessibility; import static android.view.accessibility.AccessibilityNodeInfo.ACTION_LONG_CLICK; import static com.android.launcher3.LauncherState.NORMAL; +import static com.android.launcher3.anim.AnimatorListeners.forSuccessCallback; import static com.android.launcher3.logging.StatsLogManager.LauncherEvent.IGNORE; import android.appwidget.AppWidgetProviderInfo; @@ -220,30 +221,26 @@ public class LauncherAccessibilityDelegate extends AccessibilityDelegate impleme } else if (action == ADD_TO_WORKSPACE) { final int[] coordinates = new int[2]; final int screenId = findSpaceOnWorkspace(item, coordinates); - mLauncher.getStateManager().goToState(NORMAL, true, new Runnable() { + mLauncher.getStateManager().goToState(NORMAL, true, forSuccessCallback(() -> { + if (item instanceof AppInfo) { + WorkspaceItemInfo info = ((AppInfo) item).makeWorkspaceItem(); + mLauncher.getModelWriter().addItemToDatabase(info, + Favorites.CONTAINER_DESKTOP, + screenId, coordinates[0], coordinates[1]); - @Override - public void run() { - if (item instanceof AppInfo) { - WorkspaceItemInfo info = ((AppInfo) item).makeWorkspaceItem(); - mLauncher.getModelWriter().addItemToDatabase(info, - Favorites.CONTAINER_DESKTOP, - screenId, coordinates[0], coordinates[1]); - - mLauncher.bindItems( - Collections.singletonList(info), - /* forceAnimateIcons= */ true, - /* focusFirstItemForAccessibility= */ true); - announceConfirmation(R.string.item_added_to_workspace); - } else if (item instanceof PendingAddItemInfo) { - PendingAddItemInfo info = (PendingAddItemInfo) item; - Workspace workspace = mLauncher.getWorkspace(); - workspace.snapToPage(workspace.getPageIndexForScreenId(screenId)); - mLauncher.addPendingItem(info, Favorites.CONTAINER_DESKTOP, - screenId, coordinates, info.spanX, info.spanY); - } + mLauncher.bindItems( + Collections.singletonList(info), + /* forceAnimateIcons= */ true, + /* focusFirstItemForAccessibility= */ true); + announceConfirmation(R.string.item_added_to_workspace); + } else if (item instanceof PendingAddItemInfo) { + PendingAddItemInfo info = (PendingAddItemInfo) item; + Workspace workspace = mLauncher.getWorkspace(); + workspace.snapToPage(workspace.getPageIndexForScreenId(screenId)); + mLauncher.addPendingItem(info, Favorites.CONTAINER_DESKTOP, + screenId, coordinates, info.spanX, info.spanY); } - }); + })); return true; } else if (action == MOVE_TO_WORKSPACE) { Folder folder = Folder.getOpen(mLauncher); diff --git a/src/com/android/launcher3/accessibility/ShortcutMenuAccessibilityDelegate.java b/src/com/android/launcher3/accessibility/ShortcutMenuAccessibilityDelegate.java index 1733e5dd41..f96afa856b 100644 --- a/src/com/android/launcher3/accessibility/ShortcutMenuAccessibilityDelegate.java +++ b/src/com/android/launcher3/accessibility/ShortcutMenuAccessibilityDelegate.java @@ -17,6 +17,7 @@ package com.android.launcher3.accessibility; import static com.android.launcher3.LauncherState.NORMAL; +import static com.android.launcher3.anim.AnimatorListeners.forSuccessCallback; import android.view.KeyEvent; import android.view.View; @@ -67,19 +68,14 @@ public class ShortcutMenuAccessibilityDelegate extends LauncherAccessibilityDele final WorkspaceItemInfo info = ((DeepShortcutView) host.getParent()).getFinalInfo(); final int[] coordinates = new int[2]; final int screenId = findSpaceOnWorkspace(item, coordinates); - Runnable onComplete = new Runnable() { - @Override - public void run() { - mLauncher.getModelWriter().addItemToDatabase(info, - LauncherSettings.Favorites.CONTAINER_DESKTOP, - screenId, coordinates[0], coordinates[1]); - mLauncher.bindItems(Collections.singletonList(info), true); - AbstractFloatingView.closeAllOpenViews(mLauncher); - announceConfirmation(R.string.item_added_to_workspace); - } - }; - - mLauncher.getStateManager().goToState(NORMAL, true, onComplete); + mLauncher.getStateManager().goToState(NORMAL, true, forSuccessCallback(() -> { + mLauncher.getModelWriter().addItemToDatabase(info, + LauncherSettings.Favorites.CONTAINER_DESKTOP, + screenId, coordinates[0], coordinates[1]); + mLauncher.bindItems(Collections.singletonList(info), true); + AbstractFloatingView.closeAllOpenViews(mLauncher); + announceConfirmation(R.string.item_added_to_workspace); + })); return true; } else if (action == DISMISS_NOTIFICATION) { if (!(host instanceof NotificationMainView)) { diff --git a/src/com/android/launcher3/allapps/AllAppsTransitionController.java b/src/com/android/launcher3/allapps/AllAppsTransitionController.java index 90f2d7cde5..2cfbdf9d59 100644 --- a/src/com/android/launcher3/allapps/AllAppsTransitionController.java +++ b/src/com/android/launcher3/allapps/AllAppsTransitionController.java @@ -28,7 +28,7 @@ import static com.android.launcher3.states.StateAnimationConfig.ANIM_VERTICAL_PR import static com.android.launcher3.util.SystemUiController.UI_STATE_ALLAPPS; import android.animation.Animator; -import android.animation.AnimatorListenerAdapter; +import android.animation.Animator.AnimatorListener; import android.animation.ObjectAnimator; import android.util.FloatProperty; import android.view.View; @@ -39,7 +39,7 @@ import com.android.launcher3.DeviceProfile.OnDeviceProfileChangeListener; import com.android.launcher3.Launcher; import com.android.launcher3.LauncherState; import com.android.launcher3.Utilities; -import com.android.launcher3.anim.AnimationSuccessListener; +import com.android.launcher3.anim.AnimatorListeners; import com.android.launcher3.anim.PendingAnimation; import com.android.launcher3.anim.PropertySetter; import com.android.launcher3.config.FeatureFlags; @@ -189,8 +189,8 @@ public class AllAppsTransitionController mScrimView.setDrawingController(shouldProtectHeader ? mAppsView : null); } - public AnimatorListenerAdapter getProgressAnimatorListener() { - return AnimationSuccessListener.forRunnable(this::onProgressAnimationEnd); + public AnimatorListener getProgressAnimatorListener() { + return AnimatorListeners.forSuccessCallback(this::onProgressAnimationEnd); } /** diff --git a/src/com/android/launcher3/anim/AnimationSuccessListener.java b/src/com/android/launcher3/anim/AnimationSuccessListener.java index 9905e81638..a312070e58 100644 --- a/src/com/android/launcher3/anim/AnimationSuccessListener.java +++ b/src/com/android/launcher3/anim/AnimationSuccessListener.java @@ -40,24 +40,4 @@ public abstract class AnimationSuccessListener extends AnimatorListenerAdapter { public abstract void onAnimationSuccess(Animator animator); - /** - * Returns an AnimationSuccessListener which runs the provided action on success - */ - public static AnimationSuccessListener forRunnable(Runnable r) { - return new RunnableSuccessListener(r); - } - - private static class RunnableSuccessListener extends AnimationSuccessListener { - - private final Runnable mRunnable; - - private RunnableSuccessListener(Runnable r) { - mRunnable = r; - } - - @Override - public void onAnimationSuccess(Animator animator) { - mRunnable.run(); - } - } } diff --git a/src/com/android/launcher3/anim/AnimatorListeners.java b/src/com/android/launcher3/anim/AnimatorListeners.java new file mode 100644 index 0000000000..379970049a --- /dev/null +++ b/src/com/android/launcher3/anim/AnimatorListeners.java @@ -0,0 +1,98 @@ +/* + * Copyright (C) 2021 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package com.android.launcher3.anim; + +import static com.android.launcher3.LauncherAnimUtils.SUCCESS_TRANSITION_PROGRESS; + +import android.animation.Animator; +import android.animation.Animator.AnimatorListener; +import android.animation.AnimatorListenerAdapter; +import android.animation.ValueAnimator; + +import java.util.function.Consumer; + +/** + * Utility class for creating common {@link AnimatorListener} + */ +public class AnimatorListeners { + + /** + * Returns an AnimatorListener which executes the callback on successful animation completion + */ + public static AnimatorListener forSuccessCallback(Runnable callback) { + return new RunnableSuccessListener(callback); + } + + /** + * Returns an AnimatorListener which executes the callback on animation completion, + * with the boolean representing success + */ + public static AnimatorListener forEndCallback(Consumer callback) { + return new EndStateCallbackWrapper(callback); + } + + /** + * Returns an AnimatorListener which executes the callback on animation completion + */ + public static AnimatorListener forEndCallback(Runnable callback) { + return new AnimatorListenerAdapter() { + @Override + public void onAnimationEnd(Animator animation, boolean isReverse) { + callback.run(); + } + }; + } + + private static class EndStateCallbackWrapper extends AnimatorListenerAdapter { + + private final Consumer mListener; + private boolean mListenerCalled = false; + + EndStateCallbackWrapper(Consumer listener) { + mListener = listener; + } + + @Override + public void onAnimationCancel(Animator animation) { + if (!mListenerCalled) { + mListenerCalled = true; + mListener.accept(false); + } + } + + @Override + public void onAnimationEnd(Animator animation) { + if (!mListenerCalled) { + ValueAnimator anim = (ValueAnimator) animation; + mListener.accept(anim.getAnimatedFraction() > SUCCESS_TRANSITION_PROGRESS); + } + } + } + + private static class RunnableSuccessListener extends AnimationSuccessListener { + + private final Runnable mRunnable; + + private RunnableSuccessListener(Runnable r) { + mRunnable = r; + } + + @Override + public void onAnimationSuccess(Animator animator) { + mRunnable.run(); + } + } +} diff --git a/src/com/android/launcher3/anim/PendingAnimation.java b/src/com/android/launcher3/anim/PendingAnimation.java index 8057475fb4..01f7de66ce 100644 --- a/src/com/android/launcher3/anim/PendingAnimation.java +++ b/src/com/android/launcher3/anim/PendingAnimation.java @@ -15,13 +15,11 @@ */ package com.android.launcher3.anim; -import static com.android.launcher3.LauncherAnimUtils.SUCCESS_TRANSITION_PROGRESS; import static com.android.launcher3.LauncherAnimUtils.VIEW_BACKGROUND_COLOR; import static com.android.launcher3.anim.AnimatorPlaybackController.addAnimationHoldersRecur; import android.animation.Animator; import android.animation.Animator.AnimatorListener; -import android.animation.AnimatorListenerAdapter; import android.animation.AnimatorSet; import android.animation.ObjectAnimator; import android.animation.TimeInterpolator; @@ -182,32 +180,6 @@ public class PendingAnimation implements PropertySetter { if (mProgressAnimator == null) { mProgressAnimator = ValueAnimator.ofFloat(0, 1); } - mProgressAnimator.addListener(new EndStateCallbackWrapper(listener)); - } - - private static class EndStateCallbackWrapper extends AnimatorListenerAdapter { - - private final Consumer mListener; - private boolean mCalled = false; - - EndStateCallbackWrapper(Consumer listener) { - mListener = listener; - } - - @Override - public void onAnimationCancel(Animator animation) { - if (!mCalled) { - mCalled = true; - mListener.accept(false); - } - } - - @Override - public void onAnimationEnd(Animator animation) { - if (!mCalled) { - ValueAnimator anim = (ValueAnimator) animation; - mListener.accept(anim.getAnimatedFraction() > SUCCESS_TRANSITION_PROGRESS); - } - } + mProgressAnimator.addListener(AnimatorListeners.forEndCallback(listener)); } } diff --git a/src/com/android/launcher3/statemanager/StateManager.java b/src/com/android/launcher3/statemanager/StateManager.java index 14ef2dc652..03b68535bc 100644 --- a/src/com/android/launcher3/statemanager/StateManager.java +++ b/src/com/android/launcher3/statemanager/StateManager.java @@ -129,14 +129,14 @@ public class StateManager> { } /** - * @see #goToState(STATE_TYPE, boolean, Runnable) + * @see #goToState(STATE_TYPE, boolean, AnimatorListener) */ public void goToState(STATE_TYPE state) { goToState(state, shouldAnimateStateChange()); } /** - * @see #goToState(STATE_TYPE, boolean, Runnable) + * @see #goToState(STATE_TYPE, boolean, AnimatorListener) */ public void goToState(STATE_TYPE state, boolean animated) { goToState(state, animated, 0, null); @@ -149,15 +149,15 @@ public class StateManager> { * true otherwise * @paras onCompleteRunnable any action to perform at the end of the transition, of null. */ - public void goToState(STATE_TYPE state, boolean animated, Runnable onCompleteRunnable) { - goToState(state, animated, 0, onCompleteRunnable); + public void goToState(STATE_TYPE state, boolean animated, AnimatorListener listener) { + goToState(state, animated, 0, listener); } /** * Changes the Launcher state to the provided state after the given delay. */ - public void goToState(STATE_TYPE state, long delay, Runnable onCompleteRunnable) { - goToState(state, true, delay, onCompleteRunnable); + public void goToState(STATE_TYPE state, long delay, AnimatorListener listener) { + goToState(state, true, delay, listener); } /** @@ -187,21 +187,20 @@ public class StateManager> { } } - private void goToState(STATE_TYPE state, boolean animated, long delay, - final Runnable onCompleteRunnable) { + private void goToState( + STATE_TYPE state, boolean animated, long delay, AnimatorListener listener) { animated &= areAnimatorsEnabled(); if (mActivity.isInState(state)) { if (mConfig.currentAnimation == null) { // Run any queued runnable - if (onCompleteRunnable != null) { - onCompleteRunnable.run(); + if (listener != null) { + listener.onAnimationEnd(null); } return; } else if (!mConfig.userControlled && animated && mConfig.targetState == state) { // We are running the same animation as requested - if (onCompleteRunnable != null) { - mConfig.currentAnimation.addListener( - AnimationSuccessListener.forRunnable(onCompleteRunnable)); + if (listener != null) { + mConfig.currentAnimation.addListener(listener); } return; } @@ -221,8 +220,8 @@ public class StateManager> { onStateTransitionEnd(state); // Run any queued runnable - if (onCompleteRunnable != null) { - onCompleteRunnable.run(); + if (listener != null) { + listener.onAnimationEnd(null); } return; } @@ -233,16 +232,16 @@ public class StateManager> { int startChangeId = mConfig.changeId; mUiHandler.postDelayed(() -> { if (mConfig.changeId == startChangeId) { - goToStateAnimated(state, fromState, onCompleteRunnable); + goToStateAnimated(state, fromState, listener); } }, delay); } else { - goToStateAnimated(state, fromState, onCompleteRunnable); + goToStateAnimated(state, fromState, listener); } } private void goToStateAnimated(STATE_TYPE state, STATE_TYPE fromState, - Runnable onCompleteRunnable) { + AnimatorListener listener) { // Since state mBaseState can be reached from multiple states, just assume that the // transition plays in reverse and use the same duration as previous state. mConfig.duration = state == mBaseState @@ -250,8 +249,8 @@ public class StateManager> { : state.getTransitionDuration(mActivity); prepareForAtomicAnimation(fromState, state, mConfig); AnimatorSet animation = createAnimationToNewWorkspaceInternal(state).buildAnim(); - if (onCompleteRunnable != null) { - animation.addListener(AnimationSuccessListener.forRunnable(onCompleteRunnable)); + if (listener != null) { + animation.addListener(listener); } mUiHandler.post(new StartAnimRunnable(animation)); }