Merge "Revert "Exposing AnimatorListeners in StateManager to receive both success and failure callback"" into sc-dev

This commit is contained in:
TreeHugger Robot 2021-05-12 23:37:33 +00:00 committed by Android (Google) Code Review
commit 7c58b4c7dc
17 changed files with 134 additions and 183 deletions

View File

@ -17,7 +17,6 @@ package com.android.launcher3.hybridhotseat;
import static com.android.launcher3.LauncherAnimUtils.SCALE_PROPERTY; import static com.android.launcher3.LauncherAnimUtils.SCALE_PROPERTY;
import static com.android.launcher3.LauncherState.NORMAL; 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.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_PREDICTION_PINNED;
import static com.android.launcher3.logging.StatsLogManager.LauncherEvent.LAUNCHER_HOTSEAT_RANKED; import static com.android.launcher3.logging.StatsLogManager.LauncherEvent.LAUNCHER_HOTSEAT_RANKED;
@ -151,7 +150,7 @@ public class HotseatPredictionController implements DragController.DragListener,
* Shows appropriate hotseat education based on prediction enabled and migration states. * Shows appropriate hotseat education based on prediction enabled and migration states.
*/ */
public void showEdu() { public void showEdu() {
mLauncher.getStateManager().goToState(NORMAL, true, forSuccessCallback(() -> { mLauncher.getStateManager().goToState(NORMAL, true, () -> {
if (mPredictedItems.isEmpty()) { if (mPredictedItems.isEmpty()) {
// launcher has empty predictions set // launcher has empty predictions set
Snackbar.show(mLauncher, R.string.hotsaet_tip_prediction_disabled, Snackbar.show(mLauncher, R.string.hotsaet_tip_prediction_disabled,
@ -166,7 +165,7 @@ public class HotseatPredictionController implements DragController.DragListener,
.collect(Collectors.toList())); .collect(Collectors.toList()));
eduController.showEdu(); eduController.showEdu();
} }
})); });
} }
/** /**
@ -256,8 +255,8 @@ public class HotseatPredictionController implements DragController.DragListener,
} }
} }
if (animate) { if (animate) {
animationSet.addListener( animationSet.addListener(AnimationSuccessListener
forSuccessCallback(this::removeOutlineDrawings)); .forRunnable(this::removeOutlineDrawings));
animationSet.start(); animationSet.start();
} else { } else {
removeOutlineDrawings(); removeOutlineDrawings();

View File

@ -35,7 +35,7 @@ import androidx.annotation.NonNull;
import com.android.launcher3.BaseQuickstepLauncher; import com.android.launcher3.BaseQuickstepLauncher;
import com.android.launcher3.LauncherState; import com.android.launcher3.LauncherState;
import com.android.launcher3.anim.AnimatorListeners; import com.android.launcher3.anim.AnimationSuccessListener;
import com.android.launcher3.anim.PendingAnimation; import com.android.launcher3.anim.PendingAnimation;
import com.android.launcher3.anim.PropertySetter; import com.android.launcher3.anim.PropertySetter;
import com.android.launcher3.states.StateAnimationConfig; import com.android.launcher3.states.StateAnimationConfig;
@ -78,7 +78,7 @@ public final class RecentsViewStateController extends
mRecentsView.updateEmptyMessage(); mRecentsView.updateEmptyMessage();
} else { } else {
builder.addListener( builder.addListener(
AnimatorListeners.forSuccessCallback(mRecentsView::resetTaskVisuals)); AnimationSuccessListener.forRunnable(mRecentsView::resetTaskVisuals));
} }
// Create or dismiss split screen select animations // Create or dismiss split screen select animations

View File

@ -22,7 +22,6 @@ import static com.android.launcher3.LauncherAnimUtils.newCancelListener;
import static com.android.launcher3.LauncherState.ALL_APPS; import static com.android.launcher3.LauncherState.ALL_APPS;
import static com.android.launcher3.LauncherState.NORMAL; import static com.android.launcher3.LauncherState.NORMAL;
import static com.android.launcher3.allapps.AllAppsTransitionController.ALL_APPS_PROGRESS; 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.anim.Interpolators.DEACCEL_3;
import static com.android.launcher3.config.FeatureFlags.ENABLE_ALL_APPS_EDU; import static com.android.launcher3.config.FeatureFlags.ENABLE_ALL_APPS_EDU;
import static com.android.launcher3.logging.StatsLogManager.LauncherEvent.LAUNCHER_HOME_GESTURE; import static com.android.launcher3.logging.StatsLogManager.LauncherEvent.LAUNCHER_HOME_GESTURE;
@ -39,7 +38,7 @@ import com.android.launcher3.LauncherState;
import com.android.launcher3.R; import com.android.launcher3.R;
import com.android.launcher3.Utilities; import com.android.launcher3.Utilities;
import com.android.launcher3.allapps.AllAppsTransitionController; import com.android.launcher3.allapps.AllAppsTransitionController;
import com.android.launcher3.anim.AnimatorListeners; import com.android.launcher3.anim.AnimationSuccessListener;
import com.android.launcher3.anim.AnimatorPlaybackController; import com.android.launcher3.anim.AnimatorPlaybackController;
import com.android.launcher3.anim.Interpolators; import com.android.launcher3.anim.Interpolators;
import com.android.launcher3.anim.PendingAnimation; import com.android.launcher3.anim.PendingAnimation;
@ -200,7 +199,7 @@ public class NavBarToHomeTouchController implements TouchController,
.animateWithVelocity(velocity); .animateWithVelocity(velocity);
} else { } else {
mLauncher.getStateManager().goToState(mEndState, true, mLauncher.getStateManager().goToState(mEndState, true,
forEndCallback(() -> onSwipeInteractionCompleted(mEndState))); () -> onSwipeInteractionCompleted(mEndState));
} }
if (mStartState != mEndState) { if (mStartState != mEndState) {
logHomeGesture(); logHomeGesture();
@ -215,7 +214,7 @@ public class NavBarToHomeTouchController implements TouchController,
// Quickly return to the state we came from (we didn't move far). // Quickly return to the state we came from (we didn't move far).
ValueAnimator anim = mCurrentAnimation.getAnimationPlayer(); ValueAnimator anim = mCurrentAnimation.getAnimationPlayer();
anim.setFloatValues(progress, 0); anim.setFloatValues(progress, 0);
anim.addListener(AnimatorListeners.forSuccessCallback( anim.addListener(AnimationSuccessListener.forRunnable(
() -> onSwipeInteractionCompleted(mStartState))); () -> onSwipeInteractionCompleted(mStartState)));
anim.setDuration(80).start(); anim.setDuration(80).start();
} }

View File

@ -22,7 +22,6 @@ import static com.android.launcher3.LauncherState.HINT_STATE;
import static com.android.launcher3.LauncherState.NORMAL; import static com.android.launcher3.LauncherState.NORMAL;
import static com.android.launcher3.LauncherState.OVERVIEW; import static com.android.launcher3.LauncherState.OVERVIEW;
import static com.android.launcher3.Utilities.EDGE_NAV_BAR; 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.anim.Interpolators.ACCEL_DEACCEL;
import static com.android.launcher3.util.VibratorWrapper.OVERVIEW_HAPTIC; import static com.android.launcher3.util.VibratorWrapper.OVERVIEW_HAPTIC;
import static com.android.systemui.shared.system.QuickStepContract.SYSUI_STATE_OVERVIEW_DISABLED; import static com.android.systemui.shared.system.QuickStepContract.SYSUI_STATE_OVERVIEW_DISABLED;
@ -173,13 +172,13 @@ public class NoButtonNavbarToOverviewTouchController extends PortraitStatesTouch
} }
mNormalToHintOverviewScrimAnimator = null; mNormalToHintOverviewScrimAnimator = null;
mCurrentAnimation.getTarget().addListener(newCancelListener(() -> mCurrentAnimation.getTarget().addListener(newCancelListener(() ->
mLauncher.getStateManager().goToState(OVERVIEW, true, forSuccessCallback(() -> { mLauncher.getStateManager().goToState(OVERVIEW, true, () -> {
mOverviewResistYAnim = AnimatorControllerWithResistance mOverviewResistYAnim = AnimatorControllerWithResistance
.createRecentsResistanceFromOverviewAnim(mLauncher, null) .createRecentsResistanceFromOverviewAnim(mLauncher, null)
.createPlaybackController(); .createPlaybackController();
mReachedOverview = true; mReachedOverview = true;
maybeSwipeInteractionToOverviewComplete(); maybeSwipeInteractionToOverviewComplete();
})))); })));
mCurrentAnimation.getTarget().removeListener(mClearStateOnCancelListener); mCurrentAnimation.getTarget().removeListener(mClearStateOnCancelListener);
mCurrentAnimation.dispatchOnCancel(); mCurrentAnimation.dispatchOnCancel();

View File

@ -21,7 +21,6 @@ import static com.android.launcher3.LauncherState.OVERVIEW;
import static com.android.launcher3.LauncherState.OVERVIEW_ACTIONS; import static com.android.launcher3.LauncherState.OVERVIEW_ACTIONS;
import static com.android.launcher3.LauncherState.QUICK_SWITCH; import static com.android.launcher3.LauncherState.QUICK_SWITCH;
import static com.android.launcher3.anim.AlphaUpdateListener.ALPHA_CUTOFF_THRESHOLD; 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.ACCEL_0_75;
import static com.android.launcher3.anim.Interpolators.DEACCEL_3; import static com.android.launcher3.anim.Interpolators.DEACCEL_3;
import static com.android.launcher3.anim.Interpolators.LINEAR; import static com.android.launcher3.anim.Interpolators.LINEAR;
@ -419,7 +418,7 @@ public class NoButtonQuickSwitchTouchController implements TouchController,
targetState.ordinal > mStartState.ordinal targetState.ordinal > mStartState.ordinal
? LAUNCHER_UNKNOWN_SWIPEUP ? LAUNCHER_UNKNOWN_SWIPEUP
: LAUNCHER_UNKNOWN_SWIPEDOWN)); : LAUNCHER_UNKNOWN_SWIPEDOWN));
mLauncher.getStateManager().goToState(targetState, false, forEndCallback(this::clearState)); mLauncher.getStateManager().goToState(targetState, false, this::clearState);
} }
private void cancelAnimations() { private void cancelAnimations() {

View File

@ -19,7 +19,6 @@ import static com.android.launcher3.LauncherState.BACKGROUND_APP;
import static com.android.launcher3.LauncherState.NORMAL; import static com.android.launcher3.LauncherState.NORMAL;
import static com.android.launcher3.LauncherState.OVERVIEW; import static com.android.launcher3.LauncherState.OVERVIEW;
import static com.android.launcher3.LauncherState.QUICK_SWITCH; 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.launcher3.anim.Interpolators.LINEAR;
import static com.android.launcher3.util.Executors.MAIN_EXECUTOR; import static com.android.launcher3.util.Executors.MAIN_EXECUTOR;
import static com.android.systemui.shared.system.QuickStepContract.SYSUI_STATE_IME_SHOWING; import static com.android.systemui.shared.system.QuickStepContract.SYSUI_STATE_IME_SHOWING;
@ -198,8 +197,7 @@ public final class LauncherActivityInterface extends
closeOverlay(); closeOverlay();
launcher.getStateManager().goToState(OVERVIEW, launcher.getStateManager().goToState(OVERVIEW,
launcher.getStateManager().shouldAnimateStateChange(), launcher.getStateManager().shouldAnimateStateChange(), onCompleteCallback);
onCompleteCallback == null ? null : forEndCallback(onCompleteCallback));
return true; return true;
} }

View File

@ -43,7 +43,7 @@ import androidx.annotation.Nullable;
import com.android.launcher3.DeviceProfile; import com.android.launcher3.DeviceProfile;
import com.android.launcher3.InvariantDeviceProfile; import com.android.launcher3.InvariantDeviceProfile;
import com.android.launcher3.Utilities; import com.android.launcher3.Utilities;
import com.android.launcher3.anim.AnimatorListeners; import com.android.launcher3.anim.AnimationSuccessListener;
import com.android.launcher3.anim.AnimatorPlaybackController; import com.android.launcher3.anim.AnimatorPlaybackController;
import com.android.launcher3.anim.PendingAnimation; import com.android.launcher3.anim.PendingAnimation;
import com.android.quickstep.AnimatedFloat; import com.android.quickstep.AnimatedFloat;
@ -156,7 +156,7 @@ abstract class SwipeUpGestureTutorialController extends TutorialController {
fadeAnim.setViewAlpha(mFakePreviousTaskView, 0, ACCEL); fadeAnim.setViewAlpha(mFakePreviousTaskView, 0, ACCEL);
} }
if (onEndRunnable != null) { if (onEndRunnable != null) {
fadeAnim.addListener(AnimatorListeners.forSuccessCallback(onEndRunnable)); fadeAnim.addListener(AnimationSuccessListener.forRunnable(onEndRunnable));
} }
AnimatorSet animset = fadeAnim.buildAnim(); AnimatorSet animset = fadeAnim.buildAnim();
animset.setStartDelay(100); animset.setStartDelay(100);
@ -174,7 +174,7 @@ abstract class SwipeUpGestureTutorialController extends TutorialController {
anim.setViewAlpha(mFakePreviousTaskView, 0, ACCEL); anim.setViewAlpha(mFakePreviousTaskView, 0, ACCEL);
} }
if (onEndRunnable != null) { if (onEndRunnable != null) {
anim.addListener(AnimatorListeners.forSuccessCallback(onEndRunnable)); anim.addListener(AnimationSuccessListener.forRunnable(onEndRunnable));
} }
} }
AnimatorSet animset = anim.buildAnim(); AnimatorSet animset = anim.buildAnim();
@ -205,10 +205,10 @@ abstract class SwipeUpGestureTutorialController extends TutorialController {
PendingAnimation fadeAnim = new PendingAnimation(300); PendingAnimation fadeAnim = new PendingAnimation(300);
fadeAnim.setViewAlpha(mFakeIconView, 0, ACCEL); fadeAnim.setViewAlpha(mFakeIconView, 0, ACCEL);
if (onEndRunnable != null) { if (onEndRunnable != null) {
fadeAnim.addListener(AnimatorListeners.forSuccessCallback(onEndRunnable)); fadeAnim.addListener(AnimationSuccessListener.forRunnable(onEndRunnable));
} }
AnimatorSet animset = fadeAnim.buildAnim(); AnimatorSet animset = fadeAnim.buildAnim();
rectAnim.addAnimatorListener(AnimatorListeners.forSuccessCallback(animset::start)); rectAnim.addAnimatorListener(AnimationSuccessListener.forRunnable(animset::start));
mRunningWindowAnim = RunningWindowAnim.wrap(rectAnim); mRunningWindowAnim = RunningWindowAnim.wrap(rectAnim);
} }

View File

@ -38,7 +38,7 @@ import androidx.appcompat.app.AlertDialog;
import androidx.appcompat.content.res.AppCompatResources; import androidx.appcompat.content.res.AppCompatResources;
import com.android.launcher3.R; import com.android.launcher3.R;
import com.android.launcher3.anim.AnimatorListeners; import com.android.launcher3.anim.AnimationSuccessListener;
import com.android.launcher3.views.ClipIconView; import com.android.launcher3.views.ClipIconView;
import com.android.quickstep.interaction.EdgeBackGestureHandler.BackGestureAttemptCallback; import com.android.quickstep.interaction.EdgeBackGestureHandler.BackGestureAttemptCallback;
import com.android.quickstep.interaction.NavBarGestureHandler.NavBarGestureAttemptCallback; import com.android.quickstep.interaction.NavBarGestureHandler.NavBarGestureAttemptCallback;
@ -141,7 +141,7 @@ abstract class TutorialController implements BackGestureAttemptCallback,
} }
void fadeTaskViewAndRun(Runnable r) { void fadeTaskViewAndRun(Runnable r) {
mFakeTaskView.animate().alpha(0).setListener(AnimatorListeners.forSuccessCallback(r)); mFakeTaskView.animate().alpha(0).setListener(AnimationSuccessListener.forRunnable(r));
} }
@StringRes @StringRes
@ -359,8 +359,8 @@ abstract class TutorialController implements BackGestureAttemptCallback,
mContext, getMockLauncherResId())); mContext, getMockLauncherResId()));
mFakeTaskView.setBackground(AppCompatResources.getDrawable( mFakeTaskView.setBackground(AppCompatResources.getDrawable(
mContext, getMockAppTaskThumbnailResId())); mContext, getMockAppTaskThumbnailResId()));
mFakeTaskView.animate().alpha(1).setListener( mFakeTaskView.animate().alpha(1).setListener(AnimationSuccessListener.forRunnable(
AnimatorListeners.forSuccessCallback(() -> mFakeTaskView.animate().cancel())); () -> mFakeTaskView.animate().cancel()));
mFakePreviousTaskView.setBackground(AppCompatResources.getDrawable( mFakePreviousTaskView.setBackground(AppCompatResources.getDrawable(
mContext, getMockPreviousAppTaskThumbnailResId())); mContext, getMockPreviousAppTaskThumbnailResId()));
mFakeIconView.setBackground(AppCompatResources.getDrawable( mFakeIconView.setBackground(AppCompatResources.getDrawable(

View File

@ -111,7 +111,6 @@ import com.android.launcher3.PagedView;
import com.android.launcher3.R; import com.android.launcher3.R;
import com.android.launcher3.Utilities; import com.android.launcher3.Utilities;
import com.android.launcher3.anim.AnimationSuccessListener; import com.android.launcher3.anim.AnimationSuccessListener;
import com.android.launcher3.anim.AnimatorListeners;
import com.android.launcher3.anim.AnimatorPlaybackController; import com.android.launcher3.anim.AnimatorPlaybackController;
import com.android.launcher3.anim.PendingAnimation; import com.android.launcher3.anim.PendingAnimation;
import com.android.launcher3.anim.SpringProperty; import com.android.launcher3.anim.SpringProperty;
@ -121,6 +120,7 @@ import com.android.launcher3.icons.cache.HandlerRunnable;
import com.android.launcher3.statehandlers.DepthController; import com.android.launcher3.statehandlers.DepthController;
import com.android.launcher3.statemanager.BaseState; import com.android.launcher3.statemanager.BaseState;
import com.android.launcher3.statemanager.StatefulActivity; import com.android.launcher3.statemanager.StatefulActivity;
import com.android.launcher3.testing.TestProtocol;
import com.android.launcher3.touch.OverScroll; import com.android.launcher3.touch.OverScroll;
import com.android.launcher3.touch.PagedOrientationHandler; import com.android.launcher3.touch.PagedOrientationHandler;
import com.android.launcher3.util.DynamicResource; import com.android.launcher3.util.DynamicResource;
@ -1677,7 +1677,7 @@ public abstract class RecentsView<ACTIVITY_TYPE extends StatefulActivity<STATE_T
return; return;
} }
AnimatorSet pa = setRecentsChangedOrientation(true); AnimatorSet pa = setRecentsChangedOrientation(true);
pa.addListener(AnimatorListeners.forSuccessCallback(() -> { pa.addListener(AnimationSuccessListener.forRunnable(() -> {
setLayoutRotation(newRotation, mOrientationState.getDisplayRotation()); setLayoutRotation(newRotation, mOrientationState.getDisplayRotation());
mActivity.getDragLayer().recreateControllers(); mActivity.getDragLayer().recreateControllers();
updateChildTaskOrientations(); updateChildTaskOrientations();

View File

@ -25,7 +25,6 @@ import static com.android.launcher3.LauncherState.FLAG_WORKSPACE_INACCESSIBLE;
import static com.android.launcher3.LauncherState.HINT_STATE; import static com.android.launcher3.LauncherState.HINT_STATE;
import static com.android.launcher3.LauncherState.NORMAL; import static com.android.launcher3.LauncherState.NORMAL;
import static com.android.launcher3.LauncherState.SPRING_LOADED; 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.config.FeatureFlags.ADAPTIVE_ICON_WINDOW_ANIM;
import static com.android.launcher3.dragndrop.DragLayer.ALPHA_INDEX_OVERLAY; import static com.android.launcher3.dragndrop.DragLayer.ALPHA_INDEX_OVERLAY;
import static com.android.launcher3.logging.StatsLogManager.LAUNCHER_STATE_HOME; import static com.android.launcher3.logging.StatsLogManager.LAUNCHER_STATE_HOME;
@ -1947,8 +1946,8 @@ public class Workspace extends PagedView<WorkspacePageIndicator>
} }
parent.onDropChild(cell); parent.onDropChild(cell);
mLauncher.getStateManager().goToState(NORMAL, SPRING_LOADED_EXIT_DELAY, mLauncher.getStateManager().goToState(
onCompleteRunnable == null ? null : forSuccessCallback(onCompleteRunnable)); NORMAL, SPRING_LOADED_EXIT_DELAY, onCompleteRunnable);
mStatsLogManager.logger().withItemInfo(d.dragInfo).withInstanceId(d.logInstanceId) mStatsLogManager.logger().withItemInfo(d.dragInfo).withInstanceId(d.logInstanceId)
.log(LauncherEvent.LAUNCHER_ITEM_DROP_COMPLETED); .log(LauncherEvent.LAUNCHER_ITEM_DROP_COMPLETED);
} }

View File

@ -3,7 +3,6 @@ package com.android.launcher3.accessibility;
import static android.view.accessibility.AccessibilityNodeInfo.ACTION_LONG_CLICK; import static android.view.accessibility.AccessibilityNodeInfo.ACTION_LONG_CLICK;
import static com.android.launcher3.LauncherState.NORMAL; 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 static com.android.launcher3.logging.StatsLogManager.LauncherEvent.IGNORE;
import android.appwidget.AppWidgetProviderInfo; import android.appwidget.AppWidgetProviderInfo;
@ -221,26 +220,30 @@ public class LauncherAccessibilityDelegate extends AccessibilityDelegate impleme
} else if (action == ADD_TO_WORKSPACE) { } else if (action == ADD_TO_WORKSPACE) {
final int[] coordinates = new int[2]; final int[] coordinates = new int[2];
final int screenId = findSpaceOnWorkspace(item, coordinates); final int screenId = findSpaceOnWorkspace(item, coordinates);
mLauncher.getStateManager().goToState(NORMAL, true, forSuccessCallback(() -> { mLauncher.getStateManager().goToState(NORMAL, true, new Runnable() {
if (item instanceof AppInfo) {
WorkspaceItemInfo info = ((AppInfo) item).makeWorkspaceItem();
mLauncher.getModelWriter().addItemToDatabase(info,
Favorites.CONTAINER_DESKTOP,
screenId, coordinates[0], coordinates[1]);
mLauncher.bindItems( @Override
Collections.singletonList(info), public void run() {
/* forceAnimateIcons= */ true, if (item instanceof AppInfo) {
/* focusFirstItemForAccessibility= */ true); WorkspaceItemInfo info = ((AppInfo) item).makeWorkspaceItem();
announceConfirmation(R.string.item_added_to_workspace); mLauncher.getModelWriter().addItemToDatabase(info,
} else if (item instanceof PendingAddItemInfo) { Favorites.CONTAINER_DESKTOP,
PendingAddItemInfo info = (PendingAddItemInfo) item; screenId, coordinates[0], coordinates[1]);
Workspace workspace = mLauncher.getWorkspace();
workspace.snapToPage(workspace.getPageIndexForScreenId(screenId)); mLauncher.bindItems(
mLauncher.addPendingItem(info, Favorites.CONTAINER_DESKTOP, Collections.singletonList(info),
screenId, coordinates, info.spanX, info.spanY); /* 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; return true;
} else if (action == MOVE_TO_WORKSPACE) { } else if (action == MOVE_TO_WORKSPACE) {
Folder folder = Folder.getOpen(mLauncher); Folder folder = Folder.getOpen(mLauncher);

View File

@ -17,7 +17,6 @@
package com.android.launcher3.accessibility; package com.android.launcher3.accessibility;
import static com.android.launcher3.LauncherState.NORMAL; import static com.android.launcher3.LauncherState.NORMAL;
import static com.android.launcher3.anim.AnimatorListeners.forSuccessCallback;
import android.view.KeyEvent; import android.view.KeyEvent;
import android.view.View; import android.view.View;
@ -68,14 +67,19 @@ public class ShortcutMenuAccessibilityDelegate extends LauncherAccessibilityDele
final WorkspaceItemInfo info = ((DeepShortcutView) host.getParent()).getFinalInfo(); final WorkspaceItemInfo info = ((DeepShortcutView) host.getParent()).getFinalInfo();
final int[] coordinates = new int[2]; final int[] coordinates = new int[2];
final int screenId = findSpaceOnWorkspace(item, coordinates); final int screenId = findSpaceOnWorkspace(item, coordinates);
mLauncher.getStateManager().goToState(NORMAL, true, forSuccessCallback(() -> { Runnable onComplete = new Runnable() {
mLauncher.getModelWriter().addItemToDatabase(info, @Override
LauncherSettings.Favorites.CONTAINER_DESKTOP, public void run() {
screenId, coordinates[0], coordinates[1]); mLauncher.getModelWriter().addItemToDatabase(info,
mLauncher.bindItems(Collections.singletonList(info), true); LauncherSettings.Favorites.CONTAINER_DESKTOP,
AbstractFloatingView.closeAllOpenViews(mLauncher); screenId, coordinates[0], coordinates[1]);
announceConfirmation(R.string.item_added_to_workspace); mLauncher.bindItems(Collections.singletonList(info), true);
})); AbstractFloatingView.closeAllOpenViews(mLauncher);
announceConfirmation(R.string.item_added_to_workspace);
}
};
mLauncher.getStateManager().goToState(NORMAL, true, onComplete);
return true; return true;
} else if (action == DISMISS_NOTIFICATION) { } else if (action == DISMISS_NOTIFICATION) {
if (!(host instanceof NotificationMainView)) { if (!(host instanceof NotificationMainView)) {

View File

@ -25,7 +25,7 @@ import static com.android.launcher3.states.StateAnimationConfig.ANIM_VERTICAL_PR
import static com.android.launcher3.util.SystemUiController.UI_STATE_ALLAPPS; import static com.android.launcher3.util.SystemUiController.UI_STATE_ALLAPPS;
import android.animation.Animator; import android.animation.Animator;
import android.animation.Animator.AnimatorListener; import android.animation.AnimatorListenerAdapter;
import android.animation.ObjectAnimator; import android.animation.ObjectAnimator;
import android.util.FloatProperty; import android.util.FloatProperty;
import android.view.View; import android.view.View;
@ -36,7 +36,7 @@ import com.android.launcher3.DeviceProfile.OnDeviceProfileChangeListener;
import com.android.launcher3.Launcher; import com.android.launcher3.Launcher;
import com.android.launcher3.LauncherState; import com.android.launcher3.LauncherState;
import com.android.launcher3.Utilities; import com.android.launcher3.Utilities;
import com.android.launcher3.anim.AnimatorListeners; import com.android.launcher3.anim.AnimationSuccessListener;
import com.android.launcher3.anim.PendingAnimation; import com.android.launcher3.anim.PendingAnimation;
import com.android.launcher3.anim.PropertySetter; import com.android.launcher3.anim.PropertySetter;
import com.android.launcher3.config.FeatureFlags; import com.android.launcher3.config.FeatureFlags;
@ -185,8 +185,8 @@ public class AllAppsTransitionController
mScrimView.setDrawingController(shouldProtectHeader ? mAppsView : null); mScrimView.setDrawingController(shouldProtectHeader ? mAppsView : null);
} }
public AnimatorListener getProgressAnimatorListener() { public AnimatorListenerAdapter getProgressAnimatorListener() {
return AnimatorListeners.forSuccessCallback(this::onProgressAnimationEnd); return AnimationSuccessListener.forRunnable(this::onProgressAnimationEnd);
} }
/** /**

View File

@ -40,4 +40,24 @@ public abstract class AnimationSuccessListener extends AnimatorListenerAdapter {
public abstract void onAnimationSuccess(Animator animator); 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();
}
}
} }

View File

@ -1,98 +0,0 @@
/*
* 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<Boolean> 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<Boolean> mListener;
private boolean mListenerCalled = false;
EndStateCallbackWrapper(Consumer<Boolean> 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();
}
}
}

View File

@ -15,11 +15,13 @@
*/ */
package com.android.launcher3.anim; 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.LauncherAnimUtils.VIEW_BACKGROUND_COLOR;
import static com.android.launcher3.anim.AnimatorPlaybackController.addAnimationHoldersRecur; import static com.android.launcher3.anim.AnimatorPlaybackController.addAnimationHoldersRecur;
import android.animation.Animator; import android.animation.Animator;
import android.animation.Animator.AnimatorListener; import android.animation.Animator.AnimatorListener;
import android.animation.AnimatorListenerAdapter;
import android.animation.AnimatorSet; import android.animation.AnimatorSet;
import android.animation.ObjectAnimator; import android.animation.ObjectAnimator;
import android.animation.TimeInterpolator; import android.animation.TimeInterpolator;
@ -180,6 +182,32 @@ public class PendingAnimation implements PropertySetter {
if (mProgressAnimator == null) { if (mProgressAnimator == null) {
mProgressAnimator = ValueAnimator.ofFloat(0, 1); mProgressAnimator = ValueAnimator.ofFloat(0, 1);
} }
mProgressAnimator.addListener(AnimatorListeners.forEndCallback(listener)); mProgressAnimator.addListener(new EndStateCallbackWrapper(listener));
}
private static class EndStateCallbackWrapper extends AnimatorListenerAdapter {
private final Consumer<Boolean> mListener;
private boolean mCalled = false;
EndStateCallbackWrapper(Consumer<Boolean> 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);
}
}
} }
} }

View File

@ -129,14 +129,14 @@ public class StateManager<STATE_TYPE extends BaseState<STATE_TYPE>> {
} }
/** /**
* @see #goToState(STATE_TYPE, boolean, AnimatorListener) * @see #goToState(STATE_TYPE, boolean, Runnable)
*/ */
public void goToState(STATE_TYPE state) { public void goToState(STATE_TYPE state) {
goToState(state, shouldAnimateStateChange()); goToState(state, shouldAnimateStateChange());
} }
/** /**
* @see #goToState(STATE_TYPE, boolean, AnimatorListener) * @see #goToState(STATE_TYPE, boolean, Runnable)
*/ */
public void goToState(STATE_TYPE state, boolean animated) { public void goToState(STATE_TYPE state, boolean animated) {
goToState(state, animated, 0, null); goToState(state, animated, 0, null);
@ -149,15 +149,15 @@ public class StateManager<STATE_TYPE extends BaseState<STATE_TYPE>> {
* true otherwise * true otherwise
* @paras onCompleteRunnable any action to perform at the end of the transition, of null. * @paras onCompleteRunnable any action to perform at the end of the transition, of null.
*/ */
public void goToState(STATE_TYPE state, boolean animated, AnimatorListener listener) { public void goToState(STATE_TYPE state, boolean animated, Runnable onCompleteRunnable) {
goToState(state, animated, 0, listener); goToState(state, animated, 0, onCompleteRunnable);
} }
/** /**
* Changes the Launcher state to the provided state after the given delay. * Changes the Launcher state to the provided state after the given delay.
*/ */
public void goToState(STATE_TYPE state, long delay, AnimatorListener listener) { public void goToState(STATE_TYPE state, long delay, Runnable onCompleteRunnable) {
goToState(state, true, delay, listener); goToState(state, true, delay, onCompleteRunnable);
} }
/** /**
@ -187,20 +187,21 @@ public class StateManager<STATE_TYPE extends BaseState<STATE_TYPE>> {
} }
} }
private void goToState( private void goToState(STATE_TYPE state, boolean animated, long delay,
STATE_TYPE state, boolean animated, long delay, AnimatorListener listener) { final Runnable onCompleteRunnable) {
animated &= areAnimatorsEnabled(); animated &= areAnimatorsEnabled();
if (mActivity.isInState(state)) { if (mActivity.isInState(state)) {
if (mConfig.currentAnimation == null) { if (mConfig.currentAnimation == null) {
// Run any queued runnable // Run any queued runnable
if (listener != null) { if (onCompleteRunnable != null) {
listener.onAnimationEnd(null); onCompleteRunnable.run();
} }
return; return;
} else if (!mConfig.userControlled && animated && mConfig.targetState == state) { } else if (!mConfig.userControlled && animated && mConfig.targetState == state) {
// We are running the same animation as requested // We are running the same animation as requested
if (listener != null) { if (onCompleteRunnable != null) {
mConfig.currentAnimation.addListener(listener); mConfig.currentAnimation.addListener(
AnimationSuccessListener.forRunnable(onCompleteRunnable));
} }
return; return;
} }
@ -220,8 +221,8 @@ public class StateManager<STATE_TYPE extends BaseState<STATE_TYPE>> {
onStateTransitionEnd(state); onStateTransitionEnd(state);
// Run any queued runnable // Run any queued runnable
if (listener != null) { if (onCompleteRunnable != null) {
listener.onAnimationEnd(null); onCompleteRunnable.run();
} }
return; return;
} }
@ -232,16 +233,16 @@ public class StateManager<STATE_TYPE extends BaseState<STATE_TYPE>> {
int startChangeId = mConfig.changeId; int startChangeId = mConfig.changeId;
mUiHandler.postDelayed(() -> { mUiHandler.postDelayed(() -> {
if (mConfig.changeId == startChangeId) { if (mConfig.changeId == startChangeId) {
goToStateAnimated(state, fromState, listener); goToStateAnimated(state, fromState, onCompleteRunnable);
} }
}, delay); }, delay);
} else { } else {
goToStateAnimated(state, fromState, listener); goToStateAnimated(state, fromState, onCompleteRunnable);
} }
} }
private void goToStateAnimated(STATE_TYPE state, STATE_TYPE fromState, private void goToStateAnimated(STATE_TYPE state, STATE_TYPE fromState,
AnimatorListener listener) { Runnable onCompleteRunnable) {
// Since state mBaseState can be reached from multiple states, just assume that the // 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. // transition plays in reverse and use the same duration as previous state.
mConfig.duration = state == mBaseState mConfig.duration = state == mBaseState
@ -249,8 +250,8 @@ public class StateManager<STATE_TYPE extends BaseState<STATE_TYPE>> {
: state.getTransitionDuration(mActivity); : state.getTransitionDuration(mActivity);
prepareForAtomicAnimation(fromState, state, mConfig); prepareForAtomicAnimation(fromState, state, mConfig);
AnimatorSet animation = createAnimationToNewWorkspaceInternal(state).buildAnim(); AnimatorSet animation = createAnimationToNewWorkspaceInternal(state).buildAnim();
if (listener != null) { if (onCompleteRunnable != null) {
animation.addListener(listener); animation.addListener(AnimationSuccessListener.forRunnable(onCompleteRunnable));
} }
mUiHandler.post(new StartAnimRunnable(animation)); mUiHandler.post(new StartAnimRunnable(animation));
} }