Merge changes I2af1792e,Ice314d46,Ib17d4a5e into sc-dev
* changes: Invert StateAnimationConfig.PLAY_ANIMATION as SKIP_ALL_ANIMATIONS Remove Overview atomic animation support In 2 button mode, animate to HINT_STATE instead of OVERVIEW directly
This commit is contained in:
@@ -48,10 +48,6 @@ public class BackButtonAlphaHandler implements StateHandler<LauncherState> {
|
||||
@Override
|
||||
public void setStateWithAnimation(LauncherState toState, StateAnimationConfig config,
|
||||
PendingAnimation animation) {
|
||||
if (config.onlyPlayAtomicComponent()) {
|
||||
return;
|
||||
}
|
||||
|
||||
if (SysUINavigationMode.getMode(mLauncher) != TWO_BUTTONS) {
|
||||
return;
|
||||
}
|
||||
|
||||
@@ -193,7 +193,6 @@ public class DepthController implements StateHandler<LauncherState>,
|
||||
public void setStateWithAnimation(LauncherState toState, StateAnimationConfig config,
|
||||
PendingAnimation animation) {
|
||||
if (mSurface == null
|
||||
|| config.onlyPlayAtomicComponent()
|
||||
|| config.hasAnimationFlag(SKIP_DEPTH_CONTROLLER)
|
||||
|| mIgnoreStateChangesDuringMultiWindowAnimation) {
|
||||
return;
|
||||
|
||||
@@ -26,8 +26,6 @@ import static com.android.launcher3.states.StateAnimationConfig.ANIM_OVERVIEW_SC
|
||||
import static com.android.launcher3.states.StateAnimationConfig.ANIM_OVERVIEW_SCRIM_FADE;
|
||||
import static com.android.launcher3.states.StateAnimationConfig.ANIM_OVERVIEW_TRANSLATE_X;
|
||||
import static com.android.launcher3.states.StateAnimationConfig.ANIM_OVERVIEW_TRANSLATE_Y;
|
||||
import static com.android.launcher3.states.StateAnimationConfig.PLAY_ATOMIC_OVERVIEW_PEEK;
|
||||
import static com.android.launcher3.states.StateAnimationConfig.PLAY_ATOMIC_OVERVIEW_SCALE;
|
||||
import static com.android.launcher3.states.StateAnimationConfig.SKIP_OVERVIEW;
|
||||
import static com.android.quickstep.views.RecentsView.ADJACENT_PAGE_OFFSET;
|
||||
import static com.android.quickstep.views.RecentsView.RECENTS_GRID_PROGRESS;
|
||||
@@ -83,10 +81,6 @@ public abstract class BaseRecentsViewStateController<T extends RecentsView>
|
||||
@Override
|
||||
public void setStateWithAnimation(LauncherState toState, StateAnimationConfig config,
|
||||
PendingAnimation builder) {
|
||||
if (!config.hasAnimationFlag(PLAY_ATOMIC_OVERVIEW_PEEK | PLAY_ATOMIC_OVERVIEW_SCALE)) {
|
||||
// The entire recents animation is played atomically.
|
||||
return;
|
||||
}
|
||||
if (config.hasAnimationFlag(SKIP_OVERVIEW)) {
|
||||
return;
|
||||
}
|
||||
|
||||
@@ -28,6 +28,7 @@ import static com.android.launcher3.LauncherState.OVERVIEW_MODAL_TASK;
|
||||
import static com.android.launcher3.compat.AccessibilityManagerCompat.sendCustomAccessibilityEvent;
|
||||
import static com.android.launcher3.logging.StatsLogManager.LauncherEvent.LAUNCHER_APP_LAUNCH_TAP;
|
||||
import static com.android.launcher3.testing.TestProtocol.HINT_STATE_ORDINAL;
|
||||
import static com.android.launcher3.testing.TestProtocol.HINT_STATE_TWO_BUTTON_ORDINAL;
|
||||
import static com.android.launcher3.testing.TestProtocol.OVERVIEW_STATE_ORDINAL;
|
||||
import static com.android.launcher3.testing.TestProtocol.QUICK_SWITCH_STATE_ORDINAL;
|
||||
import static com.android.systemui.shared.system.ActivityManagerWrapper.CLOSE_SYSTEM_WINDOWS_REASON_HOME_KEY;
|
||||
@@ -35,6 +36,7 @@ import static com.android.systemui.shared.system.ActivityManagerWrapper.CLOSE_SY
|
||||
import android.content.Intent;
|
||||
import android.content.SharedPreferences;
|
||||
import android.content.res.Configuration;
|
||||
import android.view.HapticFeedbackConstants;
|
||||
import android.view.View;
|
||||
|
||||
import com.android.launcher3.BaseQuickstepLauncher;
|
||||
@@ -250,6 +252,11 @@ public class QuickstepLauncher extends BaseQuickstepLauncher {
|
||||
}
|
||||
break;
|
||||
}
|
||||
case HINT_STATE_TWO_BUTTON_ORDINAL: {
|
||||
getStateManager().goToState(OVERVIEW);
|
||||
getDragLayer().performHapticFeedback(HapticFeedbackConstants.VIRTUAL_KEY);
|
||||
break;
|
||||
}
|
||||
case OVERVIEW_STATE_ORDINAL: {
|
||||
RecentsView rv = getOverviewPanel();
|
||||
sendCustomAccessibilityEvent(
|
||||
|
||||
+3
-1
@@ -18,6 +18,7 @@ package com.android.launcher3.uioverrides.states;
|
||||
import static android.view.View.VISIBLE;
|
||||
|
||||
import static com.android.launcher3.LauncherState.HINT_STATE;
|
||||
import static com.android.launcher3.LauncherState.HINT_STATE_TWO_BUTTON;
|
||||
import static com.android.launcher3.LauncherState.NORMAL;
|
||||
import static com.android.launcher3.LauncherState.OVERVIEW;
|
||||
import static com.android.launcher3.WorkspaceStateTransitionAnimation.getSpringScaleAnimator;
|
||||
@@ -115,7 +116,8 @@ public class QuickstepAtomicAnimationFactory extends
|
||||
qsbContainer.setScaleY(0.92f);
|
||||
}
|
||||
}
|
||||
} else if ((fromState == NORMAL || fromState == HINT_STATE) && toState == OVERVIEW) {
|
||||
} else if ((fromState == NORMAL || fromState == HINT_STATE
|
||||
|| fromState == HINT_STATE_TWO_BUTTON) && toState == OVERVIEW) {
|
||||
if (SysUINavigationMode.getMode(mActivity) == NO_BUTTON) {
|
||||
config.setInterpolator(ANIM_WORKSPACE_SCALE,
|
||||
fromState == NORMAL ? ACCEL : OVERSHOOT_1_2);
|
||||
|
||||
+2
-2
@@ -108,8 +108,8 @@ public class NoButtonNavbarToOverviewTouchController extends PortraitStatesTouch
|
||||
}
|
||||
|
||||
@Override
|
||||
protected float initCurrentAnimation(int animComponents) {
|
||||
float progressMultiplier = super.initCurrentAnimation(animComponents);
|
||||
protected float initCurrentAnimation() {
|
||||
float progressMultiplier = super.initCurrentAnimation();
|
||||
if (mToState == HINT_STATE) {
|
||||
// Track the drag across the entire height of the screen.
|
||||
progressMultiplier = -1 / getShiftRange();
|
||||
|
||||
+2
-1
@@ -33,6 +33,7 @@ import static com.android.launcher3.states.StateAnimationConfig.ANIM_ALL_APPS_FA
|
||||
import static com.android.launcher3.states.StateAnimationConfig.ANIM_VERTICAL_PROGRESS;
|
||||
import static com.android.launcher3.states.StateAnimationConfig.ANIM_WORKSPACE_FADE;
|
||||
import static com.android.launcher3.states.StateAnimationConfig.ANIM_WORKSPACE_TRANSLATE;
|
||||
import static com.android.launcher3.states.StateAnimationConfig.SKIP_ALL_ANIMATIONS;
|
||||
import static com.android.launcher3.states.StateAnimationConfig.SKIP_OVERVIEW;
|
||||
import static com.android.launcher3.touch.BothAxesSwipeDetector.DIRECTION_RIGHT;
|
||||
import static com.android.launcher3.touch.BothAxesSwipeDetector.DIRECTION_UP;
|
||||
@@ -372,7 +373,7 @@ public class NoButtonQuickSwitchTouchController implements TouchController,
|
||||
// animation as from an app.
|
||||
StateAnimationConfig config = new StateAnimationConfig();
|
||||
// Update mNonOverviewAnim to do nothing so it doesn't interfere.
|
||||
config.animFlags = 0;
|
||||
config.animFlags = SKIP_ALL_ANIMATIONS;
|
||||
updateNonOverviewAnim(targetState, config);
|
||||
nonOverviewAnim = mNonOverviewAnim.getAnimationPlayer();
|
||||
|
||||
|
||||
+3
-98
@@ -23,17 +23,9 @@ import static com.android.launcher3.LauncherState.NORMAL;
|
||||
import static com.android.launcher3.LauncherState.OVERVIEW;
|
||||
import static com.android.launcher3.anim.Interpolators.ACCEL;
|
||||
import static com.android.launcher3.anim.Interpolators.DEACCEL;
|
||||
import static com.android.launcher3.anim.Interpolators.LINEAR;
|
||||
import static com.android.launcher3.config.FeatureFlags.UNSTABLE_SPRINGS;
|
||||
import static com.android.launcher3.states.StateAnimationConfig.ANIM_ALL_APPS_FADE;
|
||||
import static com.android.launcher3.states.StateAnimationConfig.ANIM_OVERVIEW_FADE;
|
||||
import static com.android.launcher3.states.StateAnimationConfig.ANIM_VERTICAL_PROGRESS;
|
||||
|
||||
import android.animation.TimeInterpolator;
|
||||
import android.animation.ValueAnimator;
|
||||
import android.util.Log;
|
||||
import android.view.MotionEvent;
|
||||
import android.view.animation.Interpolator;
|
||||
|
||||
import com.android.launcher3.DeviceProfile;
|
||||
import com.android.launcher3.Launcher;
|
||||
@@ -41,8 +33,6 @@ import com.android.launcher3.LauncherState;
|
||||
import com.android.launcher3.allapps.AllAppsTransitionController;
|
||||
import com.android.launcher3.anim.Interpolators;
|
||||
import com.android.launcher3.states.StateAnimationConfig;
|
||||
import com.android.launcher3.states.StateAnimationConfig.AnimationFlags;
|
||||
import com.android.launcher3.testing.TestProtocol;
|
||||
import com.android.launcher3.touch.AbstractStateChangeTouchController;
|
||||
import com.android.launcher3.touch.SingleAxisSwipeDetector;
|
||||
import com.android.launcher3.uioverrides.states.OverviewState;
|
||||
@@ -70,11 +60,6 @@ public class PortraitStatesTouchController extends AbstractStateChangeTouchContr
|
||||
|
||||
private final PortraitOverviewStateTouchHelper mOverviewPortraitStateTouchHelper;
|
||||
|
||||
private final InterpolatorWrapper mAllAppsInterpolatorWrapper = new InterpolatorWrapper();
|
||||
|
||||
// If true, we will finish the current animation instantly on second touch.
|
||||
private boolean mFinishFastOnSecondTouch;
|
||||
|
||||
public PortraitStatesTouchController(Launcher l) {
|
||||
super(l, SingleAxisSwipeDetector.VERTICAL);
|
||||
mOverviewPortraitStateTouchHelper = new PortraitOverviewStateTouchHelper(l);
|
||||
@@ -85,10 +70,6 @@ public class PortraitStatesTouchController extends AbstractStateChangeTouchContr
|
||||
// If we are swiping to all apps instead of overview, allow it from anywhere.
|
||||
boolean interceptAnywhere = mLauncher.isInState(NORMAL);
|
||||
if (mCurrentAnimation != null) {
|
||||
if (mFinishFastOnSecondTouch) {
|
||||
mCurrentAnimation.getAnimationPlayer().end();
|
||||
}
|
||||
|
||||
AllAppsTransitionController allAppsController = mLauncher.getAllAppsController();
|
||||
if (ev.getY() >= allAppsController.getShiftRange() * allAppsController.getProgress()
|
||||
|| interceptAnywhere) {
|
||||
@@ -96,11 +77,7 @@ public class PortraitStatesTouchController extends AbstractStateChangeTouchContr
|
||||
// the touch is below the current all apps progress (to allow for double swipe).
|
||||
return true;
|
||||
}
|
||||
// Otherwise, make sure everything is settled and don't intercept so they can scroll
|
||||
// recents, dismiss a task, etc.
|
||||
if (mAtomicAnim != null) {
|
||||
mAtomicAnim.end();
|
||||
}
|
||||
// Otherwise, don't intercept so they can scroll recents, dismiss a task, etc.
|
||||
return false;
|
||||
}
|
||||
if (mLauncher.isInState(ALL_APPS)) {
|
||||
@@ -136,32 +113,6 @@ public class PortraitStatesTouchController extends AbstractStateChangeTouchContr
|
||||
return fromState;
|
||||
}
|
||||
|
||||
private StateAnimationConfig getNormalToOverviewAnimation() {
|
||||
mAllAppsInterpolatorWrapper.baseInterpolator = LINEAR;
|
||||
|
||||
StateAnimationConfig builder = new StateAnimationConfig();
|
||||
builder.setInterpolator(ANIM_VERTICAL_PROGRESS, mAllAppsInterpolatorWrapper);
|
||||
return builder;
|
||||
}
|
||||
|
||||
private static StateAnimationConfig getOverviewToAllAppsAnimation() {
|
||||
StateAnimationConfig builder = new StateAnimationConfig();
|
||||
builder.setInterpolator(ANIM_ALL_APPS_FADE, Interpolators.clampToProgress(ACCEL,
|
||||
0, ALL_APPS_CONTENT_FADE_THRESHOLD));
|
||||
builder.setInterpolator(ANIM_OVERVIEW_FADE, Interpolators.clampToProgress(DEACCEL,
|
||||
RECENTS_FADE_THRESHOLD, 1));
|
||||
return builder;
|
||||
}
|
||||
|
||||
private StateAnimationConfig getAllAppsToOverviewAnimation() {
|
||||
StateAnimationConfig builder = new StateAnimationConfig();
|
||||
builder.setInterpolator(ANIM_ALL_APPS_FADE, Interpolators.clampToProgress(DEACCEL,
|
||||
1 - ALL_APPS_CONTENT_FADE_THRESHOLD, 1));
|
||||
builder.setInterpolator(ANIM_OVERVIEW_FADE, Interpolators.clampToProgress(ACCEL,
|
||||
0f, 1 - RECENTS_FADE_THRESHOLD));
|
||||
return builder;
|
||||
}
|
||||
|
||||
private StateAnimationConfig getNormalToAllAppsAnimation() {
|
||||
StateAnimationConfig builder = new StateAnimationConfig();
|
||||
builder.setInterpolator(ANIM_ALL_APPS_FADE, Interpolators.clampToProgress(ACCEL,
|
||||
@@ -180,13 +131,7 @@ public class PortraitStatesTouchController extends AbstractStateChangeTouchContr
|
||||
protected StateAnimationConfig getConfigForStates(
|
||||
LauncherState fromState, LauncherState toState) {
|
||||
final StateAnimationConfig config;
|
||||
if (fromState == NORMAL && toState == OVERVIEW) {
|
||||
config = getNormalToOverviewAnimation();
|
||||
} else if (fromState == OVERVIEW && toState == ALL_APPS) {
|
||||
config = getOverviewToAllAppsAnimation();
|
||||
} else if (fromState == ALL_APPS && toState == OVERVIEW) {
|
||||
config = getAllAppsToOverviewAnimation();
|
||||
} else if (fromState == NORMAL && toState == ALL_APPS) {
|
||||
if (fromState == NORMAL && toState == ALL_APPS) {
|
||||
config = getNormalToAllAppsAnimation();
|
||||
} else if (fromState == ALL_APPS && toState == NORMAL) {
|
||||
config = getAllAppsToNormalAnimation();
|
||||
@@ -197,7 +142,7 @@ public class PortraitStatesTouchController extends AbstractStateChangeTouchContr
|
||||
}
|
||||
|
||||
@Override
|
||||
protected float initCurrentAnimation(@AnimationFlags int animFlags) {
|
||||
protected float initCurrentAnimation() {
|
||||
float range = getShiftRange();
|
||||
long maxAccuracy = (long) (2 * range);
|
||||
|
||||
@@ -208,7 +153,6 @@ public class PortraitStatesTouchController extends AbstractStateChangeTouchContr
|
||||
|
||||
final StateAnimationConfig config = totalShift == 0 ? new StateAnimationConfig()
|
||||
: getConfigForStates(mFromState, mToState);
|
||||
config.animFlags = animFlags;
|
||||
config.duration = maxAccuracy;
|
||||
|
||||
if (mCurrentAnimation != null) {
|
||||
@@ -242,35 +186,6 @@ public class PortraitStatesTouchController extends AbstractStateChangeTouchContr
|
||||
return 1 / totalShift;
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void updateSwipeCompleteAnimation(ValueAnimator animator, long expectedDuration,
|
||||
LauncherState targetState, float velocity, boolean isFling) {
|
||||
super.updateSwipeCompleteAnimation(animator, expectedDuration, targetState,
|
||||
velocity, isFling);
|
||||
handleFirstSwipeToOverview(animator, expectedDuration, targetState, velocity, isFling);
|
||||
}
|
||||
|
||||
private void handleFirstSwipeToOverview(final ValueAnimator animator,
|
||||
final long expectedDuration, final LauncherState targetState, final float velocity,
|
||||
final boolean isFling) {
|
||||
if (UNSTABLE_SPRINGS.get() && mFromState == OVERVIEW && mToState == ALL_APPS
|
||||
&& targetState == OVERVIEW) {
|
||||
mFinishFastOnSecondTouch = true;
|
||||
} else if (mFromState == NORMAL && mToState == OVERVIEW && targetState == OVERVIEW) {
|
||||
mFinishFastOnSecondTouch = true;
|
||||
if (isFling && expectedDuration != 0) {
|
||||
// Update all apps interpolator to add a bit of overshoot starting from currFraction
|
||||
final float currFraction = mCurrentAnimation.getProgressFraction();
|
||||
mAllAppsInterpolatorWrapper.baseInterpolator = Interpolators.clampToProgress(
|
||||
Interpolators.overshootInterpolatorForVelocity(velocity), currFraction, 1);
|
||||
animator.setDuration(Math.min(expectedDuration, ATOMIC_DURATION))
|
||||
.setInterpolator(LINEAR);
|
||||
}
|
||||
} else {
|
||||
mFinishFastOnSecondTouch = false;
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void onSwipeInteractionCompleted(LauncherState targetState) {
|
||||
super.onSwipeInteractionCompleted(targetState);
|
||||
@@ -296,16 +211,6 @@ public class PortraitStatesTouchController extends AbstractStateChangeTouchContr
|
||||
return launcher.getDragLayer().getHeight() - hotseatHeight;
|
||||
}
|
||||
|
||||
private static class InterpolatorWrapper implements Interpolator {
|
||||
|
||||
public TimeInterpolator baseInterpolator = LINEAR;
|
||||
|
||||
@Override
|
||||
public float getInterpolation(float v) {
|
||||
return baseInterpolator.getInterpolation(v);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean onControllerInterceptTouchEvent(MotionEvent ev) {
|
||||
switch (ev.getAction()) {
|
||||
|
||||
+1
-1
@@ -101,7 +101,7 @@ public class QuickSwitchTouchController extends AbstractStateChangeTouchControll
|
||||
}
|
||||
|
||||
@Override
|
||||
protected float initCurrentAnimation(int animComponents) {
|
||||
protected float initCurrentAnimation() {
|
||||
StateAnimationConfig config = new StateAnimationConfig();
|
||||
setupInterpolators(config);
|
||||
config.duration = (long) (getShiftRange() * 2);
|
||||
|
||||
+2
-2
@@ -32,8 +32,8 @@ public class TransposedQuickSwitchTouchController extends QuickSwitchTouchContro
|
||||
}
|
||||
|
||||
@Override
|
||||
protected float initCurrentAnimation(int animComponents) {
|
||||
float multiplier = super.initCurrentAnimation(animComponents);
|
||||
protected float initCurrentAnimation() {
|
||||
float multiplier = super.initCurrentAnimation();
|
||||
return mLauncher.getDeviceProfile().isSeascape() ? multiplier : -multiplier;
|
||||
}
|
||||
|
||||
|
||||
+27
-6
@@ -17,17 +17,18 @@ package com.android.launcher3.uioverrides.touchcontrollers;
|
||||
|
||||
import static com.android.launcher3.AbstractFloatingView.TYPE_ALL_APPS_EDU;
|
||||
import static com.android.launcher3.AbstractFloatingView.getOpenView;
|
||||
import static com.android.launcher3.LauncherState.HINT_STATE_TWO_BUTTON;
|
||||
import static com.android.launcher3.LauncherState.NORMAL;
|
||||
import static com.android.launcher3.LauncherState.OVERVIEW;
|
||||
import static com.android.launcher3.Utilities.EDGE_NAV_BAR;
|
||||
|
||||
import android.animation.ValueAnimator;
|
||||
import android.os.SystemClock;
|
||||
import android.view.MotionEvent;
|
||||
|
||||
import com.android.launcher3.AbstractFloatingView;
|
||||
import com.android.launcher3.Launcher;
|
||||
import com.android.launcher3.LauncherState;
|
||||
import com.android.launcher3.states.StateAnimationConfig.AnimationFlags;
|
||||
import com.android.launcher3.touch.AbstractStateChangeTouchController;
|
||||
import com.android.launcher3.touch.SingleAxisSwipeDetector;
|
||||
import com.android.quickstep.SystemUiProxy;
|
||||
@@ -91,10 +92,10 @@ public class TwoButtonNavbarTouchController extends AbstractStateChangeTouchCont
|
||||
if (mIsTransposed) {
|
||||
boolean draggingFromNav =
|
||||
mLauncher.getDeviceProfile().isSeascape() == isDragTowardPositive;
|
||||
return draggingFromNav ? OVERVIEW : NORMAL;
|
||||
return draggingFromNav ? HINT_STATE_TWO_BUTTON : NORMAL;
|
||||
} else {
|
||||
LauncherState startState = mStartState != null ? mStartState : fromState;
|
||||
return isDragTowardPositive ^ (startState == OVERVIEW) ? OVERVIEW : NORMAL;
|
||||
return isDragTowardPositive ^ (startState == OVERVIEW) ? HINT_STATE_TWO_BUTTON : NORMAL;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -104,6 +105,12 @@ public class TwoButtonNavbarTouchController extends AbstractStateChangeTouchCont
|
||||
super.updateSwipeCompleteAnimation(animator, expectedDuration, targetState,
|
||||
velocity, isFling);
|
||||
mFinishFastOnSecondTouch = !mIsTransposed && mFromState == NORMAL;
|
||||
|
||||
if (targetState == HINT_STATE_TWO_BUTTON) {
|
||||
// We were going to HINT_STATE_TWO_BUTTON, but end that animation immediately so we go
|
||||
// to OVERVIEW instead.
|
||||
animator.setDuration(0);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -113,21 +120,35 @@ public class TwoButtonNavbarTouchController extends AbstractStateChangeTouchCont
|
||||
}
|
||||
|
||||
@Override
|
||||
protected float initCurrentAnimation(@AnimationFlags int animComponent) {
|
||||
protected float initCurrentAnimation() {
|
||||
float range = getShiftRange();
|
||||
long maxAccuracy = (long) (2 * range);
|
||||
mCurrentAnimation = mLauncher.getStateManager().createAnimationToNewWorkspace(mToState,
|
||||
maxAccuracy, animComponent);
|
||||
maxAccuracy);
|
||||
return (mLauncher.getDeviceProfile().isSeascape() ? 1 : -1) / range;
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void updateProgress(float fraction) {
|
||||
super.updateProgress(fraction);
|
||||
|
||||
// We have reached HINT_STATE, end the gesture now to go to OVERVIEW.
|
||||
if (fraction >= 1 && mToState == HINT_STATE_TWO_BUTTON) {
|
||||
final long now = SystemClock.uptimeMillis();
|
||||
MotionEvent event = MotionEvent.obtain(now, now,
|
||||
MotionEvent.ACTION_UP, 0.0f, 0.0f, 0);
|
||||
mDetector.onTouchEvent(event);
|
||||
event.recycle();
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void onSwipeInteractionCompleted(LauncherState targetState) {
|
||||
super.onSwipeInteractionCompleted(targetState);
|
||||
if (!mIsTransposed) {
|
||||
mContinuousTouchCount++;
|
||||
}
|
||||
if (mStartState == NORMAL && targetState == OVERVIEW) {
|
||||
if (mStartState == NORMAL && targetState == HINT_STATE_TWO_BUTTON) {
|
||||
SystemUiProxy.INSTANCE.get(mLauncher).onOverviewShown(true, TAG);
|
||||
} else if (targetState == NORMAL
|
||||
&& mContinuousTouchCount >= MAX_NUM_SWIPES_TO_TRIGGER_EDU) {
|
||||
|
||||
@@ -29,6 +29,7 @@ import androidx.annotation.NonNull;
|
||||
import com.android.launcher3.BaseQuickstepLauncher;
|
||||
import com.android.launcher3.LauncherState;
|
||||
import com.android.launcher3.anim.AnimatorPlaybackController;
|
||||
import com.android.launcher3.states.StateAnimationConfig;
|
||||
import com.android.launcher3.views.FloatingIconView;
|
||||
import com.android.quickstep.util.RectFSpringAnim;
|
||||
import com.android.quickstep.util.StaggeredWorkspaceAnim;
|
||||
@@ -134,7 +135,7 @@ public class LauncherSwipeHandlerV2 extends
|
||||
// to home.
|
||||
long accuracy = 2 * Math.max(mDp.widthPx, mDp.heightPx);
|
||||
return mActivity.getStateManager().createAnimationToNewWorkspace(
|
||||
NORMAL, accuracy, 0 /* animComponents */);
|
||||
NORMAL, accuracy, StateAnimationConfig.SKIP_ALL_ANIMATIONS);
|
||||
}
|
||||
|
||||
@Override
|
||||
|
||||
@@ -20,8 +20,6 @@ import static com.android.launcher3.states.StateAnimationConfig.ANIM_OVERVIEW_MO
|
||||
import static com.android.launcher3.states.StateAnimationConfig.ANIM_OVERVIEW_SCALE;
|
||||
import static com.android.launcher3.states.StateAnimationConfig.ANIM_OVERVIEW_TRANSLATE_X;
|
||||
import static com.android.launcher3.states.StateAnimationConfig.ANIM_OVERVIEW_TRANSLATE_Y;
|
||||
import static com.android.launcher3.states.StateAnimationConfig.PLAY_ATOMIC_OVERVIEW_PEEK;
|
||||
import static com.android.launcher3.states.StateAnimationConfig.PLAY_ATOMIC_OVERVIEW_SCALE;
|
||||
import static com.android.launcher3.states.StateAnimationConfig.SKIP_OVERVIEW;
|
||||
import static com.android.quickstep.views.RecentsView.ADJACENT_PAGE_OFFSET;
|
||||
import static com.android.quickstep.views.RecentsView.FULLSCREEN_PROGRESS;
|
||||
@@ -63,10 +61,6 @@ public class FallbackRecentsStateController implements StateHandler<RecentsState
|
||||
@Override
|
||||
public void setStateWithAnimation(RecentsState toState, StateAnimationConfig config,
|
||||
PendingAnimation setter) {
|
||||
if (!config.hasAnimationFlag(PLAY_ATOMIC_OVERVIEW_PEEK | PLAY_ATOMIC_OVERVIEW_SCALE)) {
|
||||
// The entire recents animation is played atomically.
|
||||
return;
|
||||
}
|
||||
if (config.hasAnimationFlag(SKIP_OVERVIEW)) {
|
||||
return;
|
||||
}
|
||||
|
||||
@@ -22,13 +22,11 @@ import static com.android.launcher3.anim.Interpolators.FAST_OUT_SLOW_IN;
|
||||
import static com.android.launcher3.anim.Interpolators.FINAL_FRAME;
|
||||
import static com.android.launcher3.anim.Interpolators.INSTANT;
|
||||
import static com.android.launcher3.anim.Interpolators.clampToProgress;
|
||||
import static com.android.launcher3.states.StateAnimationConfig.ANIM_ALL_COMPONENTS;
|
||||
import static com.android.launcher3.states.StateAnimationConfig.ANIM_OVERVIEW_ACTIONS_FADE;
|
||||
import static com.android.launcher3.states.StateAnimationConfig.ANIM_OVERVIEW_FADE;
|
||||
import static com.android.launcher3.states.StateAnimationConfig.ANIM_OVERVIEW_SCALE;
|
||||
import static com.android.launcher3.states.StateAnimationConfig.ANIM_OVERVIEW_TRANSLATE_X;
|
||||
import static com.android.launcher3.states.StateAnimationConfig.ANIM_OVERVIEW_TRANSLATE_Y;
|
||||
import static com.android.launcher3.states.StateAnimationConfig.PLAY_ATOMIC_OVERVIEW_PEEK;
|
||||
|
||||
import android.animation.Animator;
|
||||
import android.animation.AnimatorSet;
|
||||
@@ -105,10 +103,6 @@ public class OverviewToHomeAnim {
|
||||
|
||||
StateAnimationConfig config = new UseFirstInterpolatorStateAnimConfig();
|
||||
config.duration = duration;
|
||||
config.animFlags = playStaggeredWorkspaceAnim
|
||||
// StaggeredWorkspaceAnim doesn't animate overview, so we handle it here.
|
||||
? PLAY_ATOMIC_OVERVIEW_PEEK
|
||||
: ANIM_ALL_COMPONENTS;
|
||||
boolean isLayoutNaturalToLauncher = recentsView.getPagedOrientationHandler()
|
||||
.isLayoutNaturalToLauncher();
|
||||
config.setInterpolator(ANIM_OVERVIEW_TRANSLATE_X, isLayoutNaturalToLauncher
|
||||
|
||||
@@ -21,7 +21,6 @@ import static com.android.launcher3.LauncherState.NORMAL;
|
||||
import static com.android.launcher3.anim.Interpolators.ACCEL_DEACCEL;
|
||||
import static com.android.launcher3.anim.Interpolators.LINEAR;
|
||||
import static com.android.launcher3.anim.PropertySetter.NO_ANIM_PROPERTY_SETTER;
|
||||
import static com.android.launcher3.states.StateAnimationConfig.ANIM_ALL_COMPONENTS;
|
||||
import static com.android.launcher3.states.StateAnimationConfig.SKIP_DEPTH_CONTROLLER;
|
||||
import static com.android.launcher3.states.StateAnimationConfig.SKIP_OVERVIEW;
|
||||
|
||||
@@ -184,7 +183,7 @@ public class StaggeredWorkspaceAnim {
|
||||
*/
|
||||
private void prepareToAnimate(Launcher launcher, boolean animateOverviewScrim) {
|
||||
StateAnimationConfig config = new StateAnimationConfig();
|
||||
config.animFlags = ANIM_ALL_COMPONENTS | SKIP_OVERVIEW | SKIP_DEPTH_CONTROLLER;
|
||||
config.animFlags = SKIP_OVERVIEW | SKIP_DEPTH_CONTROLLER;
|
||||
config.duration = 0;
|
||||
// setRecentsAttachedToAppWindow() will animate recents out.
|
||||
launcher.getStateManager().createAtomicAnimation(BACKGROUND_APP, NORMAL, config).start();
|
||||
|
||||
@@ -17,9 +17,11 @@ package com.android.launcher3;
|
||||
|
||||
import static com.android.launcher3.anim.Interpolators.ACCEL_2;
|
||||
import static com.android.launcher3.logging.StatsLogManager.LAUNCHER_STATE_HOME;
|
||||
import static com.android.launcher3.logging.StatsLogManager.LAUNCHER_STATE_OVERVIEW;
|
||||
import static com.android.launcher3.testing.TestProtocol.ALL_APPS_STATE_ORDINAL;
|
||||
import static com.android.launcher3.testing.TestProtocol.BACKGROUND_APP_STATE_ORDINAL;
|
||||
import static com.android.launcher3.testing.TestProtocol.HINT_STATE_ORDINAL;
|
||||
import static com.android.launcher3.testing.TestProtocol.HINT_STATE_TWO_BUTTON_ORDINAL;
|
||||
import static com.android.launcher3.testing.TestProtocol.NORMAL_STATE_ORDINAL;
|
||||
import static com.android.launcher3.testing.TestProtocol.OVERVIEW_MODAL_TASK_STATE_ORDINAL;
|
||||
import static com.android.launcher3.testing.TestProtocol.OVERVIEW_SPLIT_SELECT_ORDINAL;
|
||||
@@ -89,7 +91,7 @@ public abstract class LauncherState implements BaseState<LauncherState> {
|
||||
}
|
||||
};
|
||||
|
||||
private static final LauncherState[] sAllStates = new LauncherState[9];
|
||||
private static final LauncherState[] sAllStates = new LauncherState[10];
|
||||
|
||||
/**
|
||||
* TODO: Create a separate class for NORMAL state.
|
||||
@@ -112,6 +114,8 @@ public abstract class LauncherState implements BaseState<LauncherState> {
|
||||
SPRING_LOADED_STATE_ORDINAL);
|
||||
public static final LauncherState ALL_APPS = new AllAppsState(ALL_APPS_STATE_ORDINAL);
|
||||
public static final LauncherState HINT_STATE = new HintState(HINT_STATE_ORDINAL);
|
||||
public static final LauncherState HINT_STATE_TWO_BUTTON = new HintState(
|
||||
HINT_STATE_TWO_BUTTON_ORDINAL, LAUNCHER_STATE_OVERVIEW);
|
||||
|
||||
public static final LauncherState OVERVIEW = new OverviewState(OVERVIEW_STATE_ORDINAL);
|
||||
public static final LauncherState OVERVIEW_MODAL_TASK = OverviewState.newModalTaskState(
|
||||
|
||||
@@ -105,47 +105,39 @@ public class WorkspaceStateTransitionAnimation {
|
||||
int elements = state.getVisibleElements(mLauncher);
|
||||
Interpolator fadeInterpolator = config.getInterpolator(ANIM_WORKSPACE_FADE,
|
||||
pageAlphaProvider.interpolator);
|
||||
boolean playAtomicComponent = config.playAtomicOverviewScaleComponent();
|
||||
Hotseat hotseat = mWorkspace.getHotseat();
|
||||
if (playAtomicComponent) {
|
||||
Interpolator scaleInterpolator = config.getInterpolator(ANIM_WORKSPACE_SCALE, ZOOM_OUT);
|
||||
LauncherState fromState = mLauncher.getStateManager().getState();
|
||||
boolean shouldSpring = propertySetter instanceof PendingAnimation
|
||||
&& fromState == HINT_STATE && state == NORMAL;
|
||||
if (shouldSpring) {
|
||||
((PendingAnimation) propertySetter).add(getSpringScaleAnimator(mLauncher,
|
||||
mWorkspace, mNewScale));
|
||||
} else {
|
||||
propertySetter.setFloat(mWorkspace, SCALE_PROPERTY, mNewScale, scaleInterpolator);
|
||||
}
|
||||
Interpolator scaleInterpolator = config.getInterpolator(ANIM_WORKSPACE_SCALE, ZOOM_OUT);
|
||||
LauncherState fromState = mLauncher.getStateManager().getState();
|
||||
|
||||
setPivotToScaleWithWorkspace(hotseat);
|
||||
float hotseatScale = hotseatScaleAndTranslation.scale;
|
||||
if (shouldSpring) {
|
||||
PendingAnimation pa = (PendingAnimation) propertySetter;
|
||||
pa.add(getSpringScaleAnimator(mLauncher, hotseat, hotseatScale));
|
||||
} else {
|
||||
Interpolator hotseatScaleInterpolator = config.getInterpolator(ANIM_HOTSEAT_SCALE,
|
||||
scaleInterpolator);
|
||||
propertySetter.setFloat(hotseat, SCALE_PROPERTY, hotseatScale,
|
||||
hotseatScaleInterpolator);
|
||||
}
|
||||
|
||||
float hotseatIconsAlpha = (elements & HOTSEAT_ICONS) != 0 ? 1 : 0;
|
||||
propertySetter.setViewAlpha(hotseat, hotseatIconsAlpha, fadeInterpolator);
|
||||
float workspacePageIndicatorAlpha = (elements & WORKSPACE_PAGE_INDICATOR) != 0 ? 1 : 0;
|
||||
propertySetter.setViewAlpha(mLauncher.getWorkspace().getPageIndicator(),
|
||||
workspacePageIndicatorAlpha, fadeInterpolator);
|
||||
boolean shouldSpring = propertySetter instanceof PendingAnimation
|
||||
&& fromState == HINT_STATE && state == NORMAL;
|
||||
if (shouldSpring) {
|
||||
((PendingAnimation) propertySetter).add(getSpringScaleAnimator(mLauncher,
|
||||
mWorkspace, mNewScale));
|
||||
} else {
|
||||
propertySetter.setFloat(mWorkspace, SCALE_PROPERTY, mNewScale, scaleInterpolator);
|
||||
}
|
||||
|
||||
if (config.onlyPlayAtomicComponent()) {
|
||||
// Only the alpha and scale, handled above, are included in the atomic animation.
|
||||
return;
|
||||
setPivotToScaleWithWorkspace(hotseat);
|
||||
float hotseatScale = hotseatScaleAndTranslation.scale;
|
||||
if (shouldSpring) {
|
||||
PendingAnimation pa = (PendingAnimation) propertySetter;
|
||||
pa.add(getSpringScaleAnimator(mLauncher, hotseat, hotseatScale));
|
||||
} else {
|
||||
Interpolator hotseatScaleInterpolator = config.getInterpolator(ANIM_HOTSEAT_SCALE,
|
||||
scaleInterpolator);
|
||||
propertySetter.setFloat(hotseat, SCALE_PROPERTY, hotseatScale,
|
||||
hotseatScaleInterpolator);
|
||||
}
|
||||
|
||||
Interpolator translationInterpolator = !playAtomicComponent
|
||||
? LINEAR
|
||||
: config.getInterpolator(ANIM_WORKSPACE_TRANSLATE, ZOOM_OUT);
|
||||
float hotseatIconsAlpha = (elements & HOTSEAT_ICONS) != 0 ? 1 : 0;
|
||||
propertySetter.setViewAlpha(hotseat, hotseatIconsAlpha, fadeInterpolator);
|
||||
float workspacePageIndicatorAlpha = (elements & WORKSPACE_PAGE_INDICATOR) != 0 ? 1 : 0;
|
||||
propertySetter.setViewAlpha(mLauncher.getWorkspace().getPageIndicator(),
|
||||
workspacePageIndicatorAlpha, fadeInterpolator);
|
||||
|
||||
Interpolator translationInterpolator =
|
||||
config.getInterpolator(ANIM_WORKSPACE_TRANSLATE, ZOOM_OUT);
|
||||
propertySetter.setFloat(mWorkspace, VIEW_TRANSLATE_X,
|
||||
scaleAndTranslation.translationX, translationInterpolator);
|
||||
propertySetter.setFloat(mWorkspace, VIEW_TRANSLATE_Y,
|
||||
@@ -195,17 +187,12 @@ public class WorkspaceStateTransitionAnimation {
|
||||
int drawableAlpha = state.hasFlag(FLAG_WORKSPACE_HAS_BACKGROUNDS)
|
||||
? Math.round(pageAlpha * 255) : 0;
|
||||
|
||||
if (!config.onlyPlayAtomicComponent()) {
|
||||
// Don't update the scrim during the atomic animation.
|
||||
propertySetter.setInt(cl.getScrimBackground(),
|
||||
DRAWABLE_ALPHA, drawableAlpha, ZOOM_OUT);
|
||||
}
|
||||
if (config.playAtomicOverviewScaleComponent()) {
|
||||
Interpolator fadeInterpolator = config.getInterpolator(ANIM_WORKSPACE_FADE,
|
||||
pageAlphaProvider.interpolator);
|
||||
propertySetter.setFloat(cl.getShortcutsAndWidgets(), VIEW_ALPHA,
|
||||
pageAlpha, fadeInterpolator);
|
||||
}
|
||||
propertySetter.setInt(cl.getScrimBackground(),
|
||||
DRAWABLE_ALPHA, drawableAlpha, ZOOM_OUT);
|
||||
Interpolator fadeInterpolator = config.getInterpolator(ANIM_WORKSPACE_FADE,
|
||||
pageAlphaProvider.interpolator);
|
||||
propertySetter.setFloat(cl.getShortcutsAndWidgets(), VIEW_ALPHA,
|
||||
pageAlpha, fadeInterpolator);
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
@@ -155,19 +155,12 @@ public class AllAppsTransitionController
|
||||
StateAnimationConfig config, PendingAnimation builder) {
|
||||
float targetProgress = toState.getVerticalProgress(mLauncher);
|
||||
if (Float.compare(mProgress, targetProgress) == 0) {
|
||||
if (!config.onlyPlayAtomicComponent()) {
|
||||
setAlphas(toState, config, builder);
|
||||
}
|
||||
setAlphas(toState, config, builder);
|
||||
// Fail fast
|
||||
onProgressAnimationEnd();
|
||||
return;
|
||||
}
|
||||
|
||||
if (config.onlyPlayAtomicComponent()) {
|
||||
// There is no atomic component for the all apps transition, so just return early.
|
||||
return;
|
||||
}
|
||||
|
||||
Interpolator interpolator = config.userControlled ? LINEAR : toState == OVERVIEW
|
||||
? config.getInterpolator(ANIM_OVERVIEW_SCALE, FAST_OUT_SLOW_IN)
|
||||
: FAST_OUT_SLOW_IN;
|
||||
|
||||
@@ -18,7 +18,7 @@ package com.android.launcher3.statemanager;
|
||||
|
||||
import static android.animation.ValueAnimator.areAnimatorsEnabled;
|
||||
|
||||
import static com.android.launcher3.states.StateAnimationConfig.ANIM_ALL_COMPONENTS;
|
||||
import static com.android.launcher3.states.StateAnimationConfig.SKIP_ALL_ANIMATIONS;
|
||||
|
||||
import android.animation.Animator;
|
||||
import android.animation.Animator.AnimatorListener;
|
||||
@@ -289,14 +289,14 @@ public class StateManager<STATE_TYPE extends BaseState<STATE_TYPE>> {
|
||||
*/
|
||||
public AnimatorPlaybackController createAnimationToNewWorkspace(
|
||||
STATE_TYPE state, long duration) {
|
||||
return createAnimationToNewWorkspace(state, duration, ANIM_ALL_COMPONENTS);
|
||||
return createAnimationToNewWorkspace(state, duration, 0 /* animFlags */);
|
||||
}
|
||||
|
||||
public AnimatorPlaybackController createAnimationToNewWorkspace(
|
||||
STATE_TYPE state, long duration, @AnimationFlags int animComponents) {
|
||||
STATE_TYPE state, long duration, @AnimationFlags int animFlags) {
|
||||
StateAnimationConfig config = new StateAnimationConfig();
|
||||
config.duration = duration;
|
||||
config.animFlags = animComponents;
|
||||
config.animFlags = animFlags;
|
||||
return createAnimationToNewWorkspace(state, config);
|
||||
}
|
||||
|
||||
@@ -312,7 +312,7 @@ public class StateManager<STATE_TYPE extends BaseState<STATE_TYPE>> {
|
||||
|
||||
private PendingAnimation createAnimationToNewWorkspaceInternal(final STATE_TYPE state) {
|
||||
PendingAnimation builder = new PendingAnimation(mConfig.duration);
|
||||
if (mConfig.getAnimComponents() != 0) {
|
||||
if (!mConfig.hasAnimationFlag(SKIP_ALL_ANIMATIONS)) {
|
||||
for (StateHandler handler : getStateHandlers()) {
|
||||
handler.setStateWithAnimation(state, mConfig, builder);
|
||||
}
|
||||
|
||||
@@ -31,7 +31,11 @@ public class HintState extends LauncherState {
|
||||
| FLAG_HAS_SYS_UI_SCRIM;
|
||||
|
||||
public HintState(int id) {
|
||||
super(id, LAUNCHER_STATE_HOME, STATE_FLAGS);
|
||||
this(id, LAUNCHER_STATE_HOME);
|
||||
}
|
||||
|
||||
public HintState(int id, int statsLogOrdinal) {
|
||||
super(id, statsLogOrdinal, STATE_FLAGS);
|
||||
}
|
||||
|
||||
@Override
|
||||
|
||||
@@ -27,32 +27,21 @@ import java.lang.annotation.RetentionPolicy;
|
||||
*/
|
||||
public class StateAnimationConfig {
|
||||
|
||||
// We separate the state animations into "atomic" and "non-atomic" components. The atomic
|
||||
// components may be run atomically - that is, all at once, instead of user-controlled. However,
|
||||
// atomic components are not restricted to this purpose; they can be user-controlled alongside
|
||||
// non atomic components as well. Note that each gesture model has exactly one atomic component,
|
||||
// PLAY_ATOMIC_OVERVIEW_SCALE *or* PLAY_ATOMIC_OVERVIEW_PEEK.
|
||||
@IntDef(flag = true, value = {
|
||||
PLAY_NON_ATOMIC,
|
||||
PLAY_ATOMIC_OVERVIEW_SCALE,
|
||||
PLAY_ATOMIC_OVERVIEW_PEEK,
|
||||
SKIP_ALL_ANIMATIONS,
|
||||
SKIP_OVERVIEW,
|
||||
SKIP_DEPTH_CONTROLLER,
|
||||
})
|
||||
@Retention(RetentionPolicy.SOURCE)
|
||||
public @interface AnimationFlags {}
|
||||
public static final int PLAY_NON_ATOMIC = 1 << 0;
|
||||
public static final int PLAY_ATOMIC_OVERVIEW_SCALE = 1 << 1;
|
||||
public static final int PLAY_ATOMIC_OVERVIEW_PEEK = 1 << 2;
|
||||
public static final int SKIP_OVERVIEW = 1 << 3;
|
||||
public static final int SKIP_DEPTH_CONTROLLER = 1 << 4;
|
||||
public static final int SKIP_ALL_ANIMATIONS = 1 << 0;
|
||||
public static final int SKIP_OVERVIEW = 1 << 1;
|
||||
public static final int SKIP_DEPTH_CONTROLLER = 1 << 2;
|
||||
|
||||
public long duration;
|
||||
public boolean userControlled;
|
||||
public @AnimationFlags int animFlags = ANIM_ALL_COMPONENTS;
|
||||
public @AnimationFlags int animFlags = 0;
|
||||
|
||||
public static final int ANIM_ALL_COMPONENTS = PLAY_NON_ATOMIC | PLAY_ATOMIC_OVERVIEW_SCALE
|
||||
| PLAY_ATOMIC_OVERVIEW_PEEK;
|
||||
|
||||
// Various types of animation state transition
|
||||
@IntDef(value = {
|
||||
@@ -126,38 +115,10 @@ public class StateAnimationConfig {
|
||||
mInterpolators[animId] = interpolator;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return Whether Overview is scaling as part of this animation. If this is the only
|
||||
* component (i.e. NON_ATOMIC_COMPONENT isn't included), then this scaling is happening
|
||||
* atomically, rather than being part of a normal state animation. StateHandlers can use
|
||||
* this to designate part of their animation that should scale with Overview.
|
||||
*/
|
||||
public boolean playAtomicOverviewScaleComponent() {
|
||||
return hasAnimationFlag(StateAnimationConfig.PLAY_ATOMIC_OVERVIEW_SCALE);
|
||||
}
|
||||
|
||||
/**
|
||||
* @return Whether this animation will play atomically at the same time as a different,
|
||||
* user-controlled state transition. StateHandlers, which contribute to both animations, can
|
||||
* use this to avoid animating the same properties in both animations, since they'd conflict
|
||||
* with one another.
|
||||
*/
|
||||
public boolean onlyPlayAtomicComponent() {
|
||||
return getAnimComponents() == StateAnimationConfig.PLAY_ATOMIC_OVERVIEW_SCALE
|
||||
|| getAnimComponents() == StateAnimationConfig.PLAY_ATOMIC_OVERVIEW_PEEK;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns true if the config and any of the provided component flags
|
||||
*/
|
||||
public boolean hasAnimationFlag(@AnimationFlags int a) {
|
||||
return (animFlags & a) != 0;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return Only the flags that determine which animation components to play.
|
||||
*/
|
||||
public @AnimationFlags int getAnimComponents() {
|
||||
return animFlags & StateAnimationConfig.ANIM_ALL_COMPONENTS;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -32,7 +32,8 @@ public final class TestProtocol {
|
||||
public static final int ALL_APPS_STATE_ORDINAL = 5;
|
||||
public static final int BACKGROUND_APP_STATE_ORDINAL = 6;
|
||||
public static final int HINT_STATE_ORDINAL = 7;
|
||||
public static final int OVERVIEW_SPLIT_SELECT_ORDINAL = 8;
|
||||
public static final int HINT_STATE_TWO_BUTTON_ORDINAL = 8;
|
||||
public static final int OVERVIEW_SPLIT_SELECT_ORDINAL = 9;
|
||||
public static final String TAPL_EVENTS_TAG = "TaplEvents";
|
||||
public static final String SEQUENCE_MAIN = "Main";
|
||||
public static final String SEQUENCE_TIS = "TIS";
|
||||
@@ -56,6 +57,8 @@ public final class TestProtocol {
|
||||
return "Background";
|
||||
case HINT_STATE_ORDINAL:
|
||||
return "Hint";
|
||||
case HINT_STATE_TWO_BUTTON_ORDINAL:
|
||||
return "Hint2Button";
|
||||
case OVERVIEW_SPLIT_SELECT_ORDINAL:
|
||||
return "OverviewSplitSelect";
|
||||
default:
|
||||
|
||||
@@ -27,30 +27,20 @@ import static com.android.launcher3.logging.StatsLogManager.LAUNCHER_STATE_HOME;
|
||||
import static com.android.launcher3.logging.StatsLogManager.LAUNCHER_STATE_OVERVIEW;
|
||||
import static com.android.launcher3.logging.StatsLogManager.LauncherEvent.LAUNCHER_UNKNOWN_SWIPEDOWN;
|
||||
import static com.android.launcher3.logging.StatsLogManager.LauncherEvent.LAUNCHER_UNKNOWN_SWIPEUP;
|
||||
import static com.android.launcher3.states.StateAnimationConfig.ANIM_ALL_COMPONENTS;
|
||||
import static com.android.launcher3.states.StateAnimationConfig.PLAY_ATOMIC_OVERVIEW_SCALE;
|
||||
import static com.android.launcher3.states.StateAnimationConfig.PLAY_NON_ATOMIC;
|
||||
import static com.android.launcher3.util.DisplayController.getSingleFrameMs;
|
||||
|
||||
import android.animation.Animator;
|
||||
import android.animation.Animator.AnimatorListener;
|
||||
import android.animation.AnimatorListenerAdapter;
|
||||
import android.animation.AnimatorSet;
|
||||
import android.animation.ValueAnimator;
|
||||
import android.os.SystemClock;
|
||||
import android.view.HapticFeedbackConstants;
|
||||
import android.view.MotionEvent;
|
||||
|
||||
import com.android.launcher3.Launcher;
|
||||
import com.android.launcher3.LauncherAnimUtils;
|
||||
import com.android.launcher3.LauncherState;
|
||||
import com.android.launcher3.Utilities;
|
||||
import com.android.launcher3.anim.AnimationSuccessListener;
|
||||
import com.android.launcher3.anim.AnimatorPlaybackController;
|
||||
import com.android.launcher3.logger.LauncherAtom;
|
||||
import com.android.launcher3.logging.StatsLogManager;
|
||||
import com.android.launcher3.states.StateAnimationConfig;
|
||||
import com.android.launcher3.states.StateAnimationConfig.AnimationFlags;
|
||||
import com.android.launcher3.util.FlingBlockCheck;
|
||||
import com.android.launcher3.util.TouchController;
|
||||
|
||||
@@ -60,13 +50,6 @@ import com.android.launcher3.util.TouchController;
|
||||
public abstract class AbstractStateChangeTouchController
|
||||
implements TouchController, SingleAxisSwipeDetector.Listener {
|
||||
|
||||
/**
|
||||
* Play an atomic recents animation when the progress from NORMAL to OVERVIEW reaches this.
|
||||
* TODO: Remove the atomic animation altogether and just go to OVERVIEW directly (b/175137718).
|
||||
*/
|
||||
public static final float ATOMIC_OVERVIEW_ANIM_THRESHOLD = 1f;
|
||||
protected final long ATOMIC_DURATION = getAtomicDuration();
|
||||
|
||||
protected final Launcher mLauncher;
|
||||
protected final SingleAxisSwipeDetector mDetector;
|
||||
protected final SingleAxisSwipeDetector.Direction mSwipeDirection;
|
||||
@@ -89,23 +72,7 @@ public abstract class AbstractStateChangeTouchController
|
||||
private float mProgressMultiplier;
|
||||
private float mDisplacementShift;
|
||||
private boolean mCanBlockFling;
|
||||
private FlingBlockCheck mFlingBlockCheck = new FlingBlockCheck();
|
||||
|
||||
protected AnimatorSet mAtomicAnim;
|
||||
// True if we want to resume playing atomic components when mAtomicAnim completes.
|
||||
private boolean mScheduleResumeAtomicComponent;
|
||||
private AutoPlayAtomicAnimationInfo mAtomicAnimAutoPlayInfo;
|
||||
|
||||
private boolean mPassedOverviewAtomicThreshold;
|
||||
// mAtomicAnim plays the atomic components of the state animations when we pass the threshold.
|
||||
// However, if we reinit to transition to a new state (e.g. OVERVIEW -> ALL_APPS) before the
|
||||
// atomic animation finishes, we only control the non-atomic components so that we don't
|
||||
// interfere with the atomic animation. When the atomic animation ends, we start controlling
|
||||
// the atomic components as well, using this controller.
|
||||
private AnimatorPlaybackController mAtomicComponentsController;
|
||||
private LauncherState mAtomicComponentsTargetState = NORMAL;
|
||||
|
||||
private float mAtomicComponentsStartProgress;
|
||||
private final FlingBlockCheck mFlingBlockCheck = new FlingBlockCheck();
|
||||
|
||||
public AbstractStateChangeTouchController(Launcher l, SingleAxisSwipeDetector.Direction dir) {
|
||||
mLauncher = l;
|
||||
@@ -113,10 +80,6 @@ public abstract class AbstractStateChangeTouchController
|
||||
mSwipeDirection = dir;
|
||||
}
|
||||
|
||||
protected long getAtomicDuration() {
|
||||
return 200;
|
||||
}
|
||||
|
||||
protected abstract boolean canInterceptTouch(MotionEvent ev);
|
||||
|
||||
@Override
|
||||
@@ -182,7 +145,7 @@ public abstract class AbstractStateChangeTouchController
|
||||
protected abstract LauncherState getTargetState(LauncherState fromState,
|
||||
boolean isDragTowardPositive);
|
||||
|
||||
protected abstract float initCurrentAnimation(@AnimationFlags int animComponents);
|
||||
protected abstract float initCurrentAnimation();
|
||||
|
||||
private boolean reinitCurrentAnimation(boolean reachedToState, boolean isDragTowardPositive) {
|
||||
LauncherState newFromState = mFromState == null ? mLauncher.getStateManager().getState()
|
||||
@@ -199,28 +162,10 @@ public abstract class AbstractStateChangeTouchController
|
||||
mToState = newToState;
|
||||
|
||||
mStartProgress = 0;
|
||||
mPassedOverviewAtomicThreshold = false;
|
||||
if (mCurrentAnimation != null) {
|
||||
mCurrentAnimation.getTarget().removeListener(mClearStateOnCancelListener);
|
||||
}
|
||||
int animComponents = goingBetweenNormalAndOverview(mFromState, mToState)
|
||||
? PLAY_NON_ATOMIC : ANIM_ALL_COMPONENTS;
|
||||
mScheduleResumeAtomicComponent = false;
|
||||
if (mAtomicAnim != null) {
|
||||
animComponents = PLAY_NON_ATOMIC;
|
||||
// Control the non-atomic components until the atomic animation finishes, then control
|
||||
// the atomic components as well.
|
||||
mScheduleResumeAtomicComponent = true;
|
||||
}
|
||||
if (goingBetweenNormalAndOverview(mFromState, mToState)
|
||||
|| mAtomicComponentsTargetState != mToState) {
|
||||
cancelAtomicComponentsController();
|
||||
}
|
||||
|
||||
if (mAtomicComponentsController != null) {
|
||||
animComponents &= ~PLAY_ATOMIC_OVERVIEW_SCALE;
|
||||
}
|
||||
mProgressMultiplier = initCurrentAnimation(animComponents);
|
||||
mProgressMultiplier = initCurrentAnimation();
|
||||
mCurrentAnimation.dispatchOnStart();
|
||||
return true;
|
||||
}
|
||||
@@ -231,13 +176,6 @@ public abstract class AbstractStateChangeTouchController
|
||||
protected void onReachedFinalState(LauncherState newToState) {
|
||||
}
|
||||
|
||||
protected boolean goingBetweenNormalAndOverview(LauncherState fromState,
|
||||
LauncherState toState) {
|
||||
return (fromState == NORMAL || fromState == OVERVIEW)
|
||||
&& (toState == NORMAL || toState == OVERVIEW)
|
||||
&& mGoingBetweenStates;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onDragStart(boolean start, float startDisplacement) {
|
||||
mStartState = mLauncher.getStateManager().getState();
|
||||
@@ -252,11 +190,6 @@ public abstract class AbstractStateChangeTouchController
|
||||
} else {
|
||||
mCurrentAnimation.pause();
|
||||
mStartProgress = mCurrentAnimation.getProgressFraction();
|
||||
|
||||
mAtomicAnimAutoPlayInfo = null;
|
||||
if (mAtomicComponentsController != null) {
|
||||
mAtomicComponentsController.pause();
|
||||
}
|
||||
}
|
||||
mCanBlockFling = mFromState == NORMAL;
|
||||
mFlingBlockCheck.unblockFling();
|
||||
@@ -310,69 +243,6 @@ public abstract class AbstractStateChangeTouchController
|
||||
return;
|
||||
}
|
||||
mCurrentAnimation.setPlayFraction(fraction);
|
||||
if (mAtomicComponentsController != null) {
|
||||
// Make sure we don't divide by 0, and have at least a small runway.
|
||||
float start = Math.min(mAtomicComponentsStartProgress, 0.9f);
|
||||
mAtomicComponentsController.setPlayFraction((fraction - start) / (1 - start));
|
||||
}
|
||||
maybeUpdateAtomicAnim(mFromState, mToState, fraction);
|
||||
}
|
||||
|
||||
/**
|
||||
* When going between normal and overview states, see if we passed the overview threshold and
|
||||
* play the appropriate atomic animation if so.
|
||||
*/
|
||||
private void maybeUpdateAtomicAnim(LauncherState fromState, LauncherState toState,
|
||||
float progress) {
|
||||
if (!goingBetweenNormalAndOverview(fromState, toState)) {
|
||||
return;
|
||||
}
|
||||
boolean passedThreshold = progress >= ATOMIC_OVERVIEW_ANIM_THRESHOLD;
|
||||
if (passedThreshold != mPassedOverviewAtomicThreshold) {
|
||||
LauncherState atomicFromState = passedThreshold ? fromState: toState;
|
||||
LauncherState atomicToState = passedThreshold ? toState : fromState;
|
||||
mPassedOverviewAtomicThreshold = passedThreshold;
|
||||
if (mAtomicAnim != null) {
|
||||
mAtomicAnim.cancel();
|
||||
}
|
||||
mAtomicAnim = createAtomicAnimForState(atomicFromState, atomicToState, ATOMIC_DURATION);
|
||||
mAtomicAnim.addListener(new AnimationSuccessListener() {
|
||||
@Override
|
||||
public void onAnimationEnd(Animator animation) {
|
||||
super.onAnimationEnd(animation);
|
||||
mAtomicAnim = null;
|
||||
mScheduleResumeAtomicComponent = false;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onAnimationSuccess(Animator animator) {
|
||||
if (!mScheduleResumeAtomicComponent) {
|
||||
return;
|
||||
}
|
||||
cancelAtomicComponentsController();
|
||||
|
||||
if (mCurrentAnimation != null) {
|
||||
mAtomicComponentsStartProgress = mCurrentAnimation.getProgressFraction();
|
||||
long duration = (long) (getShiftRange() * 2);
|
||||
mAtomicComponentsController = AnimatorPlaybackController.wrap(
|
||||
createAtomicAnimForState(mFromState, mToState, duration), duration);
|
||||
mAtomicComponentsController.dispatchOnStart();
|
||||
mAtomicComponentsTargetState = mToState;
|
||||
maybeAutoPlayAtomicComponentsAnim();
|
||||
}
|
||||
}
|
||||
});
|
||||
mAtomicAnim.start();
|
||||
mLauncher.getDragLayer().performHapticFeedback(HapticFeedbackConstants.VIRTUAL_KEY);
|
||||
}
|
||||
}
|
||||
|
||||
private AnimatorSet createAtomicAnimForState(LauncherState fromState, LauncherState targetState,
|
||||
long duration) {
|
||||
StateAnimationConfig config = getConfigForStates(fromState, targetState);
|
||||
config.animFlags = PLAY_ATOMIC_OVERVIEW_SCALE;
|
||||
config.duration = duration;
|
||||
return mLauncher.getStateManager().createAtomicAnimation(fromState, targetState, config);
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -451,59 +321,12 @@ public abstract class AbstractStateChangeTouchController
|
||||
mCurrentAnimation.setEndAction(() -> onSwipeInteractionCompleted(targetState));
|
||||
ValueAnimator anim = mCurrentAnimation.getAnimationPlayer();
|
||||
anim.setFloatValues(startProgress, endProgress);
|
||||
maybeUpdateAtomicAnim(mFromState, targetState, targetState == mToState ? 1f : 0f);
|
||||
updateSwipeCompleteAnimation(anim, Math.max(duration, getRemainingAtomicDuration()),
|
||||
targetState, velocity, fling);
|
||||
updateSwipeCompleteAnimation(anim, duration, targetState, velocity, fling);
|
||||
mCurrentAnimation.dispatchOnStart();
|
||||
if (fling && targetState == LauncherState.ALL_APPS && !UNSTABLE_SPRINGS.get()) {
|
||||
mLauncher.getAppsView().addSpringFromFlingUpdateListener(anim, velocity);
|
||||
}
|
||||
anim.start();
|
||||
mAtomicAnimAutoPlayInfo = new AutoPlayAtomicAnimationInfo(endProgress, anim.getDuration());
|
||||
maybeAutoPlayAtomicComponentsAnim();
|
||||
}
|
||||
|
||||
/**
|
||||
* Animates the atomic components from the current progress to the final progress.
|
||||
*
|
||||
* Note that this only applies when we are controlling the atomic components separately from
|
||||
* the non-atomic components, which only happens if we reinit before the atomic animation
|
||||
* finishes.
|
||||
*/
|
||||
private void maybeAutoPlayAtomicComponentsAnim() {
|
||||
if (mAtomicComponentsController == null || mAtomicAnimAutoPlayInfo == null) {
|
||||
return;
|
||||
}
|
||||
|
||||
final AnimatorPlaybackController controller = mAtomicComponentsController;
|
||||
ValueAnimator atomicAnim = controller.getAnimationPlayer();
|
||||
atomicAnim.setFloatValues(controller.getProgressFraction(),
|
||||
mAtomicAnimAutoPlayInfo.toProgress);
|
||||
long duration = mAtomicAnimAutoPlayInfo.endTime - SystemClock.elapsedRealtime();
|
||||
mAtomicAnimAutoPlayInfo = null;
|
||||
if (duration <= 0) {
|
||||
atomicAnim.start();
|
||||
atomicAnim.end();
|
||||
mAtomicComponentsController = null;
|
||||
} else {
|
||||
atomicAnim.setDuration(duration);
|
||||
atomicAnim.addListener(new AnimatorListenerAdapter() {
|
||||
@Override
|
||||
public void onAnimationEnd(Animator animation) {
|
||||
if (mAtomicComponentsController == controller) {
|
||||
mAtomicComponentsController = null;
|
||||
}
|
||||
}
|
||||
});
|
||||
atomicAnim.start();
|
||||
}
|
||||
}
|
||||
|
||||
private long getRemainingAtomicDuration() {
|
||||
if (mAtomicAnim == null) {
|
||||
return 0;
|
||||
}
|
||||
return mAtomicAnim.getTotalDuration() - mAtomicAnim.getCurrentPlayTime();
|
||||
}
|
||||
|
||||
protected void updateSwipeCompleteAnimation(ValueAnimator animator, long expectedDuration,
|
||||
@@ -513,10 +336,6 @@ public abstract class AbstractStateChangeTouchController
|
||||
}
|
||||
|
||||
protected void onSwipeInteractionCompleted(LauncherState targetState) {
|
||||
if (mAtomicComponentsController != null) {
|
||||
mAtomicComponentsController.getAnimationPlayer().end();
|
||||
mAtomicComponentsController = null;
|
||||
}
|
||||
onReachedFinalState(mToState);
|
||||
clearState();
|
||||
boolean shouldGoToTargetState = mGoingBetweenStates || (mToState != targetState);
|
||||
@@ -556,37 +375,12 @@ public abstract class AbstractStateChangeTouchController
|
||||
|
||||
protected void clearState() {
|
||||
cancelAnimationControllers();
|
||||
if (mAtomicAnim != null) {
|
||||
mAtomicAnim.cancel();
|
||||
mAtomicAnim = null;
|
||||
}
|
||||
mGoingBetweenStates = true;
|
||||
mScheduleResumeAtomicComponent = false;
|
||||
mDetector.finishedScrolling();
|
||||
mDetector.setDetectableScrollConditions(0, false);
|
||||
}
|
||||
|
||||
private void cancelAnimationControllers() {
|
||||
mCurrentAnimation = null;
|
||||
cancelAtomicComponentsController();
|
||||
}
|
||||
|
||||
private void cancelAtomicComponentsController() {
|
||||
if (mAtomicComponentsController != null) {
|
||||
mAtomicComponentsController.getAnimationPlayer().cancel();
|
||||
mAtomicComponentsController = null;
|
||||
}
|
||||
mAtomicAnimAutoPlayInfo = null;
|
||||
}
|
||||
|
||||
private static class AutoPlayAtomicAnimationInfo {
|
||||
|
||||
public final float toProgress;
|
||||
public final long endTime;
|
||||
|
||||
AutoPlayAtomicAnimationInfo(float toProgress, long duration) {
|
||||
this.toProgress = toProgress;
|
||||
this.endTime = duration + SystemClock.elapsedRealtime();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -23,24 +23,18 @@ import android.view.MotionEvent;
|
||||
import com.android.launcher3.AbstractFloatingView;
|
||||
import com.android.launcher3.Launcher;
|
||||
import com.android.launcher3.LauncherState;
|
||||
import com.android.launcher3.states.StateAnimationConfig.AnimationFlags;
|
||||
|
||||
/**
|
||||
* TouchController to switch between NORMAL and ALL_APPS state.
|
||||
*/
|
||||
public class AllAppsSwipeController extends AbstractStateChangeTouchController {
|
||||
|
||||
private MotionEvent mTouchDownEvent;
|
||||
|
||||
public AllAppsSwipeController(Launcher l) {
|
||||
super(l, SingleAxisSwipeDetector.VERTICAL);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected boolean canInterceptTouch(MotionEvent ev) {
|
||||
if (ev.getAction() == MotionEvent.ACTION_DOWN) {
|
||||
mTouchDownEvent = ev;
|
||||
}
|
||||
if (mCurrentAnimation != null) {
|
||||
// If we are already animating from a previous state, we can intercept.
|
||||
return true;
|
||||
@@ -69,11 +63,11 @@ public class AllAppsSwipeController extends AbstractStateChangeTouchController {
|
||||
}
|
||||
|
||||
@Override
|
||||
protected float initCurrentAnimation(@AnimationFlags int animComponents) {
|
||||
protected float initCurrentAnimation() {
|
||||
float range = getShiftRange();
|
||||
long maxAccuracy = (long) (2 * range);
|
||||
mCurrentAnimation = mLauncher.getStateManager()
|
||||
.createAnimationToNewWorkspace(mToState, maxAccuracy, animComponents);
|
||||
.createAnimationToNewWorkspace(mToState, maxAccuracy);
|
||||
float startVerticalShift = mFromState.getVerticalProgress(mLauncher) * range;
|
||||
float endVerticalShift = mToState.getVerticalProgress(mLauncher) * range;
|
||||
float totalShift = endVerticalShift - startVerticalShift;
|
||||
|
||||
Reference in New Issue
Block a user