use of com.android.launcher3.LauncherState.OVERVIEW in project android_packages_apps_Launcher3 by ArrowOS.
the class NoButtonQuickSwitchTouchController method onDragEnd.
@Override
public void onDragEnd(PointF velocity) {
boolean horizontalFling = mSwipeDetector.isFling(velocity.x);
boolean verticalFling = mSwipeDetector.isFling(velocity.y);
boolean noFling = !horizontalFling && !verticalFling;
if (mMotionPauseDetector.isPaused() && noFling) {
cancelAnimations();
StateAnimationConfig config = new StateAnimationConfig();
config.duration = ATOMIC_DURATION_FROM_PAUSED_TO_OVERVIEW;
Animator overviewAnim = mLauncher.getStateManager().createAtomicAnimation(mStartState, OVERVIEW, config);
overviewAnim.addListener(new AnimatorListenerAdapter() {
@Override
public void onAnimationEnd(Animator animation) {
onAnimationToStateCompleted(OVERVIEW);
}
});
overviewAnim.start();
// Create an empty state transition so StateListeners get onStateTransitionStart().
mLauncher.getStateManager().createAnimationToNewWorkspace(OVERVIEW, config.duration, StateAnimationConfig.SKIP_ALL_ANIMATIONS).dispatchOnStart();
return;
}
final LauncherState targetState;
if (horizontalFling && verticalFling) {
if (velocity.x < 0) {
// Flinging left and up or down both go back home.
targetState = NORMAL;
} else {
if (velocity.y > 0) {
// Flinging right and down goes to quick switch.
targetState = QUICK_SWITCH;
} else {
// Flinging up and right could go either home or to quick switch.
// Determine the target based on the higher velocity.
targetState = Math.abs(velocity.x) > Math.abs(velocity.y) ? QUICK_SWITCH : NORMAL;
}
}
} else if (horizontalFling) {
targetState = velocity.x > 0 ? QUICK_SWITCH : NORMAL;
} else if (verticalFling) {
targetState = velocity.y > 0 ? QUICK_SWITCH : NORMAL;
} else {
// If user isn't flinging, just snap to the closest state.
boolean passedHorizontalThreshold = mXOverviewAnim.getInterpolatedProgress() > 0.5f;
boolean passedVerticalThreshold = mYOverviewAnim.value > 1f;
targetState = passedHorizontalThreshold && !passedVerticalThreshold ? QUICK_SWITCH : NORMAL;
}
// Animate the various components to the target state.
float xProgress = mXOverviewAnim.getProgressFraction();
float startXProgress = Utilities.boundToRange(xProgress + velocity.x * getSingleFrameMs(mLauncher) / mXRange, 0f, 1f);
final float endXProgress = targetState == NORMAL ? 0 : 1;
long xDuration = BaseSwipeDetector.calculateDuration(velocity.x, Math.abs(endXProgress - startXProgress));
ValueAnimator xOverviewAnim = mXOverviewAnim.getAnimationPlayer();
xOverviewAnim.setFloatValues(startXProgress, endXProgress);
xOverviewAnim.setDuration(xDuration).setInterpolator(scrollInterpolatorForVelocity(velocity.x));
mXOverviewAnim.dispatchOnStart();
boolean flingUpToNormal = verticalFling && velocity.y < 0 && targetState == NORMAL;
float yProgress = mYOverviewAnim.value;
float startYProgress = Utilities.boundToRange(yProgress - velocity.y * getSingleFrameMs(mLauncher) / mYRange, 0f, mMaxYProgress);
final float endYProgress;
if (flingUpToNormal) {
endYProgress = 1;
} else if (targetState == NORMAL) {
// Keep overview at its current scale/translationY as it slides off the screen.
endYProgress = startYProgress;
} else {
endYProgress = 0;
}
float yDistanceToCover = Math.abs(endYProgress - startYProgress) * mYRange;
long yDuration = (long) (yDistanceToCover / Math.max(1f, Math.abs(velocity.y)));
ValueAnimator yOverviewAnim = mYOverviewAnim.animateToValue(startYProgress, endYProgress);
yOverviewAnim.setDuration(yDuration);
mYOverviewAnim.updateValue(startYProgress);
ValueAnimator nonOverviewAnim = mNonOverviewAnim.getAnimationPlayer();
if (flingUpToNormal && !mIsHomeScreenVisible) {
// We are flinging to home while workspace is invisible, run the same staggered
// animation as from an app.
StateAnimationConfig config = new StateAnimationConfig();
// Update mNonOverviewAnim to do nothing so it doesn't interfere.
config.animFlags = SKIP_ALL_ANIMATIONS;
updateNonOverviewAnim(targetState, config);
nonOverviewAnim = mNonOverviewAnim.getAnimationPlayer();
mNonOverviewAnim.dispatchOnStart();
new WorkspaceRevealAnim(mLauncher, false).start();
} else {
boolean canceled = targetState == NORMAL;
if (canceled) {
// Let the state manager know that the animation didn't go to the target state,
// but don't clean up yet (we already clean up when the animation completes).
mNonOverviewAnim.getTarget().removeListener(mClearStateOnCancelListener);
mNonOverviewAnim.dispatchOnCancel();
}
float startProgress = mNonOverviewAnim.getProgressFraction();
float endProgress = canceled ? 0 : 1;
nonOverviewAnim.setFloatValues(startProgress, endProgress);
mNonOverviewAnim.dispatchOnStart();
}
if (targetState == QUICK_SWITCH) {
// Navigating to quick switch, add scroll feedback since the first time is not
// considered a scroll by the RecentsView.
VibratorWrapper.INSTANCE.get(mLauncher).vibrate(RecentsView.SCROLL_VIBRATION_PRIMITIVE, RecentsView.SCROLL_VIBRATION_PRIMITIVE_SCALE, RecentsView.SCROLL_VIBRATION_FALLBACK);
}
nonOverviewAnim.setDuration(Math.max(xDuration, yDuration));
mNonOverviewAnim.setEndAction(() -> onAnimationToStateCompleted(targetState));
cancelAnimations();
xOverviewAnim.start();
yOverviewAnim.start();
nonOverviewAnim.start();
}
use of com.android.launcher3.LauncherState.OVERVIEW in project android_packages_apps_Launcher3 by ArrowOS.
the class PortraitStatesTouchController method initCurrentAnimation.
@Override
protected float initCurrentAnimation() {
float range = getShiftRange();
long maxAccuracy = (long) (2 * range);
float startVerticalShift = mFromState.getVerticalProgress(mLauncher) * range;
float endVerticalShift = mToState.getVerticalProgress(mLauncher) * range;
float totalShift = endVerticalShift - startVerticalShift;
final StateAnimationConfig config = totalShift == 0 ? new StateAnimationConfig() : getConfigForStates(mFromState, mToState);
config.duration = maxAccuracy;
if (mCurrentAnimation != null) {
mCurrentAnimation.getTarget().removeListener(mClearStateOnCancelListener);
mCurrentAnimation.dispatchOnCancel();
}
mGoingBetweenStates = true;
if (mFromState == OVERVIEW && mToState == NORMAL && mOverviewPortraitStateTouchHelper.shouldSwipeDownReturnToApp()) {
// Reset the state manager, when changing the interaction mode
mLauncher.getStateManager().goToState(OVERVIEW, false);
mGoingBetweenStates = false;
mCurrentAnimation = mOverviewPortraitStateTouchHelper.createSwipeDownToTaskAppAnimation(maxAccuracy, Interpolators.LINEAR).createPlaybackController();
mLauncher.getStateManager().setCurrentUserControlledAnimation(mCurrentAnimation);
RecentsView recentsView = mLauncher.getOverviewPanel();
totalShift = LayoutUtils.getShelfTrackingDistance(mLauncher, mLauncher.getDeviceProfile(), recentsView.getPagedOrientationHandler());
} else {
mCurrentAnimation = mLauncher.getStateManager().createAnimationToNewWorkspace(mToState, config);
}
mCurrentAnimation.getTarget().addListener(mClearStateOnCancelListener);
if (totalShift == 0) {
totalShift = Math.signum(mFromState.ordinal - mToState.ordinal) * OverviewState.getDefaultSwipeHeight(mLauncher);
}
return 1 / totalShift;
}
use of com.android.launcher3.LauncherState.OVERVIEW in project android_packages_apps_Launcher3 by ArrowOS.
the class RecentsView method createTaskLaunchAnimation.
public PendingAnimation createTaskLaunchAnimation(TaskView tv, long duration, Interpolator interpolator) {
if (FeatureFlags.IS_STUDIO_BUILD && mPendingAnimation != null) {
throw new IllegalStateException("Another pending animation is still running");
}
int count = getTaskViewCount();
if (count == 0) {
return new PendingAnimation(duration);
}
// When swiping down from overview to tasks, ensures the snapped page's scroll maintain
// invariant between quick switch and overview, to ensure a smooth animation transition.
updateGridProperties();
updateScrollSynchronously();
int targetSysUiFlags = tv.getThumbnail().getSysUiStatusNavFlags();
final boolean[] passedOverviewThreshold = new boolean[] { false };
ValueAnimator progressAnim = ValueAnimator.ofFloat(0, 1);
progressAnim.addUpdateListener(animator -> {
// tasks' flags
if (animator.getAnimatedFraction() > UPDATE_SYSUI_FLAGS_THRESHOLD) {
mActivity.getSystemUiController().updateUiState(UI_STATE_FULLSCREEN_TASK, targetSysUiFlags);
} else {
mActivity.getSystemUiController().updateUiState(UI_STATE_FULLSCREEN_TASK, 0);
}
// Passing the threshold from taskview to fullscreen app will vibrate
final boolean passed = animator.getAnimatedFraction() >= SUCCESS_TRANSITION_PROGRESS;
if (passed != passedOverviewThreshold[0]) {
passedOverviewThreshold[0] = passed;
performHapticFeedback(HapticFeedbackConstants.VIRTUAL_KEY, HapticFeedbackConstants.FLAG_IGNORE_VIEW_SETTING);
}
});
AnimatorSet anim = createAdjacentPageAnimForTaskLaunch(tv);
DepthController depthController = getDepthController();
if (depthController != null) {
ObjectAnimator depthAnimator = ObjectAnimator.ofFloat(depthController, DEPTH, BACKGROUND_APP.getDepth(mActivity));
anim.play(depthAnimator);
}
anim.play(progressAnim);
anim.setInterpolator(interpolator);
mPendingAnimation = new PendingAnimation(duration);
mPendingAnimation.add(anim);
if (ENABLE_QUICKSTEP_LIVE_TILE.get()) {
runActionOnRemoteHandles(remoteTargetHandle -> remoteTargetHandle.getTaskViewSimulator().addOverviewToAppAnim(mPendingAnimation, interpolator));
mPendingAnimation.addOnFrameCallback(this::redrawLiveTile);
}
mPendingAnimation.addEndListener(isSuccess -> {
if (isSuccess) {
if (tv.getTaskIds()[1] != -1) {
// TODO(b/194414938): make this part of the animations instead.
TaskViewUtils.setSplitAuxiliarySurfacesShown(mRemoteTargetHandles[0].getTransformParams().getTargetSet().nonApps, true, /*shown*/
false);
}
if (ENABLE_QUICKSTEP_LIVE_TILE.get() && tv.isRunningTask()) {
finishRecentsAnimation(false, /* toRecents */
null);
onTaskLaunchAnimationEnd(true);
} else {
tv.launchTask(this::onTaskLaunchAnimationEnd);
}
Task task = tv.getTask();
if (task != null) {
mActivity.getStatsLogManager().logger().withItemInfo(tv.getItemInfo()).log(LAUNCHER_TASK_LAUNCH_SWIPE_DOWN);
}
} else {
onTaskLaunchAnimationEnd(false);
}
mPendingAnimation = null;
});
return mPendingAnimation;
}
use of com.android.launcher3.LauncherState.OVERVIEW in project android_packages_apps_Launcher3 by ArrowOS.
the class TaskView method onTaskListVisibilityChanged.
/**
* See {@link TaskDataChanges}
* @param visible If this task view will be visible to the user in overview or hidden
*/
public void onTaskListVisibilityChanged(boolean visible, @TaskDataChanges int changes) {
if (mTask == null) {
return;
}
cancelPendingLoadTasks();
if (visible) {
// These calls are no-ops if the data is already loaded, try and load the high
// resolution thumbnail if the state permits
RecentsModel model = RecentsModel.INSTANCE.get(getContext());
TaskThumbnailCache thumbnailCache = model.getThumbnailCache();
TaskIconCache iconCache = model.getIconCache();
if (needsUpdate(changes, FLAG_UPDATE_THUMBNAIL)) {
mThumbnailLoadRequest = thumbnailCache.updateThumbnailInBackground(mTask, thumbnail -> {
mSnapshotView.setThumbnail(mTask, thumbnail);
});
}
if (needsUpdate(changes, FLAG_UPDATE_ICON)) {
mIconLoadRequest = iconCache.updateIconInBackground(mTask, (task) -> {
setIcon(mIconView, task.icon);
mDigitalWellBeingToast.initialize(mTask);
});
}
} else {
if (needsUpdate(changes, FLAG_UPDATE_THUMBNAIL)) {
mSnapshotView.setThumbnail(null, null);
// Reset the task thumbnail reference as well (it will be fetched from the cache or
// reloaded next time we need it)
mTask.thumbnail = null;
}
if (needsUpdate(changes, FLAG_UPDATE_ICON)) {
setIcon(mIconView, null);
}
}
}
use of com.android.launcher3.LauncherState.OVERVIEW in project android_packages_apps_Launcher3 by ArrowOS.
the class FallbackRecentsTest method testOverview.
// b/143488140
// @NavigationModeSwitch
@Test
public void testOverview() {
startAppFast(getAppPackageName());
startAppFast(resolveSystemApp(Intent.CATEGORY_APP_CALCULATOR));
startTestActivity(2);
Wait.atMost("Expected three apps in the task list", () -> mLauncher.getRecentTasks().size() >= 3, DEFAULT_ACTIVITY_TIMEOUT, mLauncher);
BaseOverview overview = mLauncher.getBackground().switchToOverview();
executeOnRecents(recents -> {
assertTrue("Don't have at least 3 tasks", getTaskCount(recents) >= 3);
});
// Test flinging forward and backward.
overview.flingForward();
final Integer currentTaskAfterFlingForward = getFromRecents(this::getCurrentOverviewPage);
executeOnRecents(recents -> assertTrue("Current task in Overview is still 0", currentTaskAfterFlingForward > 0));
overview.flingBackward();
executeOnRecents(recents -> assertTrue("Flinging back in Overview did nothing", getCurrentOverviewPage(recents) < currentTaskAfterFlingForward));
// Test opening a task.
overview = pressHomeAndGoToOverview();
OverviewTask task = overview.getCurrentTask();
assertNotNull("overview.getCurrentTask() returned null (1)", task);
assertNotNull("OverviewTask.open returned null", task.open());
assertTrue("Test activity didn't open from Overview", TestHelpers.wait(Until.hasObject(By.pkg(getAppPackageName()).text("TestActivity2")), DEFAULT_UI_TIMEOUT));
// Test dismissing a task.
overview = pressHomeAndGoToOverview();
final Integer numTasks = getFromRecents(this::getTaskCount);
task = overview.getCurrentTask();
assertNotNull("overview.getCurrentTask() returned null (2)", task);
task.dismiss();
executeOnRecents(recents -> assertEquals("Dismissing a task didn't remove 1 task from Overview", numTasks - 1, getTaskCount(recents)));
// Test dismissing all tasks.
pressHomeAndGoToOverview().dismissAllTasks();
assertTrue("Fallback Launcher not visible", TestHelpers.wait(Until.hasObject(By.pkg(mOtherLauncherActivity.packageName)), WAIT_TIME_MS));
}
Aggregations