Merge "Update KQS overview launch animation" into main
This commit is contained in:
committed by
Android (Google) Code Review
commit
3dafeb2d09
@@ -22,6 +22,7 @@ import android.content.pm.ActivityInfo;
|
||||
|
||||
import androidx.annotation.NonNull;
|
||||
import androidx.annotation.Nullable;
|
||||
import androidx.annotation.VisibleForTesting;
|
||||
|
||||
import com.android.launcher3.R;
|
||||
import com.android.launcher3.statehandlers.DesktopVisibilityController;
|
||||
@@ -47,7 +48,8 @@ import java.util.stream.Collectors;
|
||||
public final class KeyboardQuickSwitchController implements
|
||||
TaskbarControllers.LoggableTaskbarController {
|
||||
|
||||
static final int MAX_TASKS = 6;
|
||||
@VisibleForTesting
|
||||
public static final int MAX_TASKS = 6;
|
||||
|
||||
@NonNull private final ControllerCallbacks mControllerCallbacks = new ControllerCallbacks();
|
||||
|
||||
|
||||
@@ -22,7 +22,9 @@ import static android.view.Surface.ROTATION_90;
|
||||
import static android.widget.Toast.LENGTH_SHORT;
|
||||
|
||||
import static com.android.app.animation.Interpolators.ACCELERATE_DECELERATE;
|
||||
import static com.android.app.animation.Interpolators.EMPHASIZED;
|
||||
import static com.android.app.animation.Interpolators.DECELERATE;
|
||||
import static com.android.app.animation.Interpolators.LINEAR;
|
||||
import static com.android.app.animation.Interpolators.OVERSHOOT_1_2;
|
||||
import static com.android.launcher3.BaseActivity.EVENT_DESTROYED;
|
||||
import static com.android.launcher3.BaseActivity.EVENT_STARTED;
|
||||
@@ -134,6 +136,7 @@ import com.android.quickstep.util.SurfaceTransaction;
|
||||
import com.android.quickstep.util.SurfaceTransactionApplier;
|
||||
import com.android.quickstep.util.SwipePipToHomeAnimator;
|
||||
import com.android.quickstep.util.TaskViewSimulator;
|
||||
import com.android.quickstep.util.TransformParams;
|
||||
import com.android.quickstep.views.RecentsView;
|
||||
import com.android.quickstep.views.TaskView;
|
||||
import com.android.quickstep.views.TaskView.TaskIdAttributeContainer;
|
||||
@@ -167,6 +170,9 @@ public abstract class AbsSwipeUpHandler<T extends StatefulActivity<S>,
|
||||
|
||||
private static final ArrayList<String> STATE_NAMES = new ArrayList<>();
|
||||
|
||||
// Fraction of the scroll and transform animation in which the current task fades out
|
||||
private static final float KQS_TASK_FADE_ANIMATION_FRACTION = 0.4f;
|
||||
|
||||
protected final BaseActivityInterface<S, T> mActivityInterface;
|
||||
protected final InputConsumerProxy mInputConsumerProxy;
|
||||
protected final ActivityInitListener mActivityInitListener;
|
||||
@@ -900,7 +906,10 @@ public abstract class AbsSwipeUpHandler<T extends StatefulActivity<S>,
|
||||
return;
|
||||
}
|
||||
mLauncherTransitionController.setProgress(
|
||||
Math.max(mCurrentShift.value, getScaleProgressDueToScroll()), mDragLengthFactor);
|
||||
// Immediately finish the grid transition
|
||||
isKeyboardTaskFocusPending()
|
||||
? 1f : Math.max(mCurrentShift.value, getScaleProgressDueToScroll()),
|
||||
mDragLengthFactor);
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -1349,7 +1358,9 @@ public abstract class AbsSwipeUpHandler<T extends StatefulActivity<S>,
|
||||
}
|
||||
Interpolator interpolator;
|
||||
S state = mActivityInterface.stateFromGestureEndTarget(endTarget);
|
||||
if (state.displayOverviewTasksAsGrid(mDp)) {
|
||||
if (isKeyboardTaskFocusPending()) {
|
||||
interpolator = EMPHASIZED;
|
||||
} else if (state.displayOverviewTasksAsGrid(mDp)) {
|
||||
interpolator = ACCELERATE_DECELERATE;
|
||||
} else if (endTarget == RECENTS) {
|
||||
interpolator = OVERSHOOT_1_2;
|
||||
@@ -1653,7 +1664,8 @@ public abstract class AbsSwipeUpHandler<T extends StatefulActivity<S>,
|
||||
animatorSet.play(windowAnim);
|
||||
if (mRecentsView != null) {
|
||||
mRecentsView.onPrepareGestureEndAnimation(
|
||||
animatorSet, mGestureState.getEndTarget(),
|
||||
mGestureState.isHandlingAtomicEvent() ? null : animatorSet,
|
||||
mGestureState.getEndTarget(),
|
||||
getRemoteTaskViewSimulators());
|
||||
}
|
||||
animatorSet.setDuration(duration).setInterpolator(interpolator);
|
||||
@@ -2225,6 +2237,14 @@ public abstract class AbsSwipeUpHandler<T extends StatefulActivity<S>,
|
||||
}
|
||||
}
|
||||
|
||||
private boolean shouldLinkRecentsViewScroll() {
|
||||
return mRecentsViewScrollLinked && !isKeyboardTaskFocusPending();
|
||||
}
|
||||
|
||||
private boolean isKeyboardTaskFocusPending() {
|
||||
return mRecentsView != null && mRecentsView.isKeyboardTaskFocusPending();
|
||||
}
|
||||
|
||||
private void onRecentsViewScroll() {
|
||||
if (moveWindowWithRecentsScroll()) {
|
||||
onCurrentShiftUpdated();
|
||||
@@ -2457,6 +2477,44 @@ public abstract class AbsSwipeUpHandler<T extends StatefulActivity<S>,
|
||||
mActivityInitListener.register();
|
||||
}
|
||||
|
||||
private boolean shouldFadeOutTargetsForKeyboardQuickSwitch(
|
||||
TransformParams transformParams,
|
||||
TaskViewSimulator taskViewSimulator,
|
||||
float progress) {
|
||||
RemoteAnimationTargets targets = transformParams.getTargetSet();
|
||||
boolean fadeAppTargets = isKeyboardTaskFocusPending()
|
||||
&& targets != null
|
||||
&& targets.apps != null
|
||||
&& targets.apps.length > 0;
|
||||
float fadeProgress = Utilities.mapBoundToRange(
|
||||
progress,
|
||||
/* lowerBound= */ 0f,
|
||||
/* upperBound= */ KQS_TASK_FADE_ANIMATION_FRACTION,
|
||||
/* toMin= */ 0f,
|
||||
/* toMax= */ 1f,
|
||||
LINEAR);
|
||||
if (!fadeAppTargets || Float.compare(fadeProgress, 1f) == 0) {
|
||||
return false;
|
||||
}
|
||||
SurfaceTransaction surfaceTransaction =
|
||||
transformParams.createSurfaceParams(taskViewSimulator);
|
||||
SurfaceControl.Transaction transaction = surfaceTransaction.getTransaction();
|
||||
|
||||
for (RemoteAnimationTarget app : targets.apps) {
|
||||
transaction.setAlpha(app.leash, 1f - fadeProgress);
|
||||
transaction.setPosition(app.leash,
|
||||
/* x= */ app.startBounds.left
|
||||
+ (mActivity.getDeviceProfile().overviewPageSpacing
|
||||
* (mRecentsView.isRtl() ? fadeProgress : -fadeProgress)),
|
||||
/* y= */ 0f);
|
||||
transaction.setScale(app.leash, 1f, 1f);
|
||||
taskViewSimulator.taskPrimaryTranslation.value =
|
||||
mRecentsView.getScrollOffsetForKeyboardTaskFocus();
|
||||
taskViewSimulator.apply(transformParams, surfaceTransaction);
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
* Applies the transform on the recents animation
|
||||
*/
|
||||
@@ -2466,7 +2524,7 @@ public abstract class AbsSwipeUpHandler<T extends StatefulActivity<S>,
|
||||
// swipe-to-icon animation is handled by RectFSpringAnim anim
|
||||
boolean notSwipingToHome = mRecentsAnimationTargets != null
|
||||
&& mGestureState.getEndTarget() != HOME;
|
||||
boolean setRecentsScroll = mRecentsViewScrollLinked && mRecentsView != null;
|
||||
boolean setRecentsScroll = shouldLinkRecentsViewScroll() && mRecentsView != null;
|
||||
float progress = Math.max(mCurrentShift.value, getScaleProgressDueToScroll());
|
||||
int scrollOffset = setRecentsScroll ? mRecentsView.getScrollOffset() : 0;
|
||||
if (!mStartMovingTasks && (progress > 0 || scrollOffset != 0)) {
|
||||
@@ -2485,7 +2543,12 @@ public abstract class AbsSwipeUpHandler<T extends StatefulActivity<S>,
|
||||
if (setRecentsScroll) {
|
||||
taskViewSimulator.setScroll(scrollOffset);
|
||||
}
|
||||
taskViewSimulator.apply(remoteHandle.getTransformParams());
|
||||
TransformParams transformParams = remoteHandle.getTransformParams();
|
||||
if (shouldFadeOutTargetsForKeyboardQuickSwitch(
|
||||
transformParams, taskViewSimulator, progress)) {
|
||||
continue;
|
||||
}
|
||||
taskViewSimulator.apply(transformParams);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -2493,7 +2556,7 @@ public abstract class AbsSwipeUpHandler<T extends StatefulActivity<S>,
|
||||
// Scaling of RecentsView during quick switch based on amount of recents scroll
|
||||
private float getScaleProgressDueToScroll() {
|
||||
if (mActivity == null || !mActivity.getDeviceProfile().isTablet || mRecentsView == null
|
||||
|| !mRecentsViewScrollLinked) {
|
||||
|| !shouldLinkRecentsViewScroll()) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
@@ -178,7 +178,7 @@ public abstract class BaseActivityInterface<STATE_TYPE extends BaseState<STATE_T
|
||||
public abstract <T extends RecentsView> T getVisibleRecentsView();
|
||||
|
||||
@UiThread
|
||||
public abstract boolean switchToRecentsIfVisible(Runnable onCompleteCallback);
|
||||
public abstract boolean switchToRecentsIfVisible(Animator.AnimatorListener animatorListener);
|
||||
|
||||
public abstract Rect getOverviewWindowBounds(
|
||||
Rect homeBounds, RemoteAnimationTarget target);
|
||||
@@ -520,7 +520,7 @@ public abstract class BaseActivityInterface<STATE_TYPE extends BaseState<STATE_T
|
||||
// Since we are changing the start position of the UI, reapply the state, at the end
|
||||
controller.setEndAction(() -> mActivity.getStateManager().goToState(
|
||||
controller.getInterpolatedProgress() > 0.5 ? mTargetState : mBackgroundState,
|
||||
false));
|
||||
/* animated= */ false));
|
||||
|
||||
RecentsView recentsView = mActivity.getOverviewPanel();
|
||||
AnimatorControllerWithResistance controllerWithResistance =
|
||||
|
||||
@@ -122,7 +122,7 @@ public final class FallbackActivityInterface extends
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean switchToRecentsIfVisible(Runnable onCompleteCallback) {
|
||||
public boolean switchToRecentsIfVisible(Animator.AnimatorListener animatorListener) {
|
||||
return false;
|
||||
}
|
||||
|
||||
|
||||
@@ -21,7 +21,6 @@ import static com.android.launcher3.LauncherState.BACKGROUND_APP;
|
||||
import static com.android.launcher3.LauncherState.FLOATING_SEARCH_BAR;
|
||||
import static com.android.launcher3.LauncherState.NORMAL;
|
||||
import static com.android.launcher3.LauncherState.OVERVIEW;
|
||||
import static com.android.launcher3.anim.AnimatorListeners.forEndCallback;
|
||||
import static com.android.launcher3.util.Executors.MAIN_EXECUTOR;
|
||||
import static com.android.launcher3.util.MultiPropertyFactory.MULTI_PROPERTY_VALUE;
|
||||
|
||||
@@ -212,7 +211,7 @@ public final class LauncherActivityInterface extends
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean switchToRecentsIfVisible(Runnable onCompleteCallback) {
|
||||
public boolean switchToRecentsIfVisible(Animator.AnimatorListener animatorListener) {
|
||||
Launcher launcher = getVisibleLauncher();
|
||||
if (launcher == null) {
|
||||
return false;
|
||||
@@ -227,7 +226,7 @@ public final class LauncherActivityInterface extends
|
||||
closeOverlay();
|
||||
launcher.getStateManager().goToState(OVERVIEW,
|
||||
launcher.getStateManager().shouldAnimateStateChange(),
|
||||
onCompleteCallback == null ? null : forEndCallback(onCompleteCallback));
|
||||
animatorListener);
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
@@ -15,9 +15,12 @@
|
||||
*/
|
||||
package com.android.quickstep;
|
||||
|
||||
import static com.android.launcher3.PagedView.INVALID_PAGE;
|
||||
import static com.android.launcher3.util.Executors.MAIN_EXECUTOR;
|
||||
import static com.android.quickstep.util.ActiveGestureLog.INTENT_EXTRA_LOG_TRACE_ID;
|
||||
|
||||
import android.animation.Animator;
|
||||
import android.animation.AnimatorListenerAdapter;
|
||||
import android.content.Intent;
|
||||
import android.graphics.PointF;
|
||||
import android.os.SystemClock;
|
||||
@@ -25,7 +28,6 @@ import android.os.Trace;
|
||||
import android.view.View;
|
||||
|
||||
import androidx.annotation.BinderThread;
|
||||
import androidx.annotation.NonNull;
|
||||
import androidx.annotation.Nullable;
|
||||
import androidx.annotation.UiThread;
|
||||
|
||||
@@ -75,7 +77,7 @@ public class OverviewCommandHelper {
|
||||
* do not lose the focus across multiple calls of
|
||||
* {@link OverviewCommandHelper#executeCommand(CommandInfo)} for the same command
|
||||
*/
|
||||
private int mTaskFocusIndexOverride = -1;
|
||||
private int mKeyboardTaskFocusIndex = -1;
|
||||
|
||||
/**
|
||||
* Whether we should incoming toggle commands while a previous toggle command is still ongoing.
|
||||
@@ -195,9 +197,11 @@ public class OverviewCommandHelper {
|
||||
}
|
||||
BaseActivityInterface<?, T> activityInterface =
|
||||
mOverviewComponentObserver.getActivityInterface();
|
||||
RecentsView recents = activityInterface.getVisibleRecentsView();
|
||||
if (recents == null) {
|
||||
RecentsView visibleRecentsView = activityInterface.getVisibleRecentsView();
|
||||
RecentsView createdRecentsView;
|
||||
if (visibleRecentsView == null) {
|
||||
T activity = activityInterface.getCreatedActivity();
|
||||
createdRecentsView = activity == null ? null : activity.getOverviewPanel();
|
||||
DeviceProfile dp = activity == null ? null : activity.getDeviceProfile();
|
||||
TaskbarUIController uiController = activityInterface.getTaskbarController();
|
||||
boolean allowQuickSwitch = FeatureFlags.ENABLE_KEYBOARD_QUICK_SWITCH.get()
|
||||
@@ -209,8 +213,8 @@ public class OverviewCommandHelper {
|
||||
if (!allowQuickSwitch) {
|
||||
return true;
|
||||
}
|
||||
mTaskFocusIndexOverride = uiController.launchFocusedTask();
|
||||
if (mTaskFocusIndexOverride == -1) {
|
||||
mKeyboardTaskFocusIndex = uiController.launchFocusedTask();
|
||||
if (mKeyboardTaskFocusIndex == -1) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
@@ -224,34 +228,47 @@ public class OverviewCommandHelper {
|
||||
return true;
|
||||
}
|
||||
} else {
|
||||
createdRecentsView = visibleRecentsView;
|
||||
switch (cmd.type) {
|
||||
case TYPE_SHOW:
|
||||
// already visible
|
||||
return true;
|
||||
case TYPE_HIDE: {
|
||||
mTaskFocusIndexOverride = -1;
|
||||
int currentPage = recents.getNextPage();
|
||||
TaskView tv = (currentPage >= 0 && currentPage < recents.getTaskViewCount())
|
||||
? (TaskView) recents.getPageAt(currentPage)
|
||||
mKeyboardTaskFocusIndex = INVALID_PAGE;
|
||||
int currentPage = visibleRecentsView.getNextPage();
|
||||
TaskView tv = (currentPage >= 0
|
||||
&& currentPage < visibleRecentsView.getTaskViewCount())
|
||||
? (TaskView) visibleRecentsView.getPageAt(currentPage)
|
||||
: null;
|
||||
return launchTask(recents, tv, cmd);
|
||||
return launchTask(visibleRecentsView, tv, cmd);
|
||||
}
|
||||
case TYPE_TOGGLE:
|
||||
return launchTask(recents, getNextTask(recents), cmd);
|
||||
return launchTask(visibleRecentsView, getNextTask(visibleRecentsView), cmd);
|
||||
case TYPE_HOME:
|
||||
recents.startHome();
|
||||
visibleRecentsView.startHome();
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
final Runnable completeCallback = () -> {
|
||||
RecentsView rv = activityInterface.getVisibleRecentsView();
|
||||
if (rv != null && (cmd.type == TYPE_KEYBOARD_INPUT || cmd.type == TYPE_HIDE)) {
|
||||
updateRecentsViewFocus(rv);
|
||||
if (createdRecentsView != null) {
|
||||
createdRecentsView.setKeyboardTaskFocusIndex(mKeyboardTaskFocusIndex);
|
||||
}
|
||||
// Handle recents view focus when launching from home
|
||||
Animator.AnimatorListener animatorListener = new AnimatorListenerAdapter() {
|
||||
|
||||
@Override
|
||||
public void onAnimationStart(Animator animation) {
|
||||
super.onAnimationStart(animation);
|
||||
updateRecentsViewFocus(cmd);
|
||||
}
|
||||
@Override
|
||||
public void onAnimationEnd(Animator animation) {
|
||||
super.onAnimationEnd(animation);
|
||||
onRecentsViewFocusUpdated(cmd);
|
||||
scheduleNextTask(cmd);
|
||||
}
|
||||
scheduleNextTask(cmd);
|
||||
};
|
||||
if (activityInterface.switchToRecentsIfVisible(completeCallback)) {
|
||||
if (activityInterface.switchToRecentsIfVisible(animatorListener)) {
|
||||
// If successfully switched, wait until animation finishes
|
||||
return false;
|
||||
}
|
||||
@@ -276,6 +293,7 @@ public class OverviewCommandHelper {
|
||||
@Override
|
||||
public void onRecentsAnimationStart(RecentsAnimationController controller,
|
||||
RecentsAnimationTargets targets) {
|
||||
updateRecentsViewFocus(cmd);
|
||||
activityInterface.runOnInitBackgroundStateUI(() ->
|
||||
interactionHandler.onGestureEnded(0, new PointF()));
|
||||
cmd.removeListener(this);
|
||||
@@ -290,14 +308,12 @@ public class OverviewCommandHelper {
|
||||
if (createdActivity == null) {
|
||||
return;
|
||||
}
|
||||
RecentsView createdRecents = createdActivity.getOverviewPanel();
|
||||
if (createdRecents != null) {
|
||||
createdRecents.onRecentsAnimationComplete();
|
||||
if (createdRecentsView != null) {
|
||||
createdRecentsView.onRecentsAnimationComplete();
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
RecentsView<?, ?> visibleRecentsView = activityInterface.getVisibleRecentsView();
|
||||
if (visibleRecentsView != null) {
|
||||
visibleRecentsView.moveRunningTaskToFront();
|
||||
}
|
||||
@@ -317,7 +333,6 @@ public class OverviewCommandHelper {
|
||||
interactionHandler.onGestureStarted(false /*isLikelyToStartNewTask*/);
|
||||
cmd.mActiveCallbacks.addListener(recentAnimListener);
|
||||
}
|
||||
|
||||
Trace.beginAsyncSection(TRANSITION_NAME, 0);
|
||||
return false;
|
||||
}
|
||||
@@ -325,47 +340,58 @@ public class OverviewCommandHelper {
|
||||
private void onTransitionComplete(CommandInfo cmd, AbsSwipeUpHandler handler) {
|
||||
cmd.removeListener(handler);
|
||||
Trace.endAsyncSection(TRANSITION_NAME, 0);
|
||||
|
||||
RecentsView rv =
|
||||
mOverviewComponentObserver.getActivityInterface().getVisibleRecentsView();
|
||||
if (rv != null && (cmd.type == TYPE_KEYBOARD_INPUT || cmd.type == TYPE_HIDE)) {
|
||||
updateRecentsViewFocus(rv);
|
||||
}
|
||||
onRecentsViewFocusUpdated(cmd);
|
||||
scheduleNextTask(cmd);
|
||||
}
|
||||
|
||||
private void updateRecentsViewFocus(@NonNull RecentsView rv) {
|
||||
private void updateRecentsViewFocus(CommandInfo cmd) {
|
||||
RecentsView recentsView =
|
||||
mOverviewComponentObserver.getActivityInterface().getVisibleRecentsView();
|
||||
if (recentsView == null || (cmd.type != TYPE_KEYBOARD_INPUT && cmd.type != TYPE_HIDE)) {
|
||||
return;
|
||||
}
|
||||
// When the overview is launched via alt tab (cmd type is TYPE_KEYBOARD_INPUT),
|
||||
// the touch mode somehow is not change to false by the Android framework.
|
||||
// The subsequent tab to go through tasks in overview can only be dispatched to
|
||||
// focuses views, while focus can only be requested in
|
||||
// {@link View#requestFocusNoSearch(int, Rect)} when touch mode is false. To note,
|
||||
// here we launch overview with live tile.
|
||||
rv.getViewRootImpl().touchModeChanged(false);
|
||||
recentsView.getViewRootImpl().touchModeChanged(false);
|
||||
// Ensure that recents view has focus so that it receives the followup key inputs
|
||||
TaskView taskView = rv.getTaskViewAt(mTaskFocusIndexOverride);
|
||||
if (taskView != null) {
|
||||
requestFocus(taskView);
|
||||
if (requestFocus(recentsView.getTaskViewAt(mKeyboardTaskFocusIndex))) {
|
||||
return;
|
||||
}
|
||||
taskView = rv.getNextTaskView();
|
||||
if (taskView != null) {
|
||||
requestFocus(taskView);
|
||||
if (requestFocus(recentsView.getNextTaskView())) {
|
||||
return;
|
||||
}
|
||||
taskView = rv.getTaskViewAt(0);
|
||||
if (taskView != null) {
|
||||
requestFocus(taskView);
|
||||
if (requestFocus(recentsView.getTaskViewAt(0))) {
|
||||
return;
|
||||
}
|
||||
requestFocus(rv);
|
||||
requestFocus(recentsView);
|
||||
}
|
||||
|
||||
private void requestFocus(@NonNull View view) {
|
||||
view.post(() -> {
|
||||
view.requestFocus();
|
||||
view.requestAccessibilityFocus();
|
||||
private void onRecentsViewFocusUpdated(CommandInfo cmd) {
|
||||
RecentsView recentsView =
|
||||
mOverviewComponentObserver.getActivityInterface().getVisibleRecentsView();
|
||||
if (recentsView == null
|
||||
|| cmd.type != TYPE_HIDE
|
||||
|| mKeyboardTaskFocusIndex == INVALID_PAGE) {
|
||||
return;
|
||||
}
|
||||
recentsView.setKeyboardTaskFocusIndex(INVALID_PAGE);
|
||||
recentsView.setCurrentPage(mKeyboardTaskFocusIndex);
|
||||
mKeyboardTaskFocusIndex = INVALID_PAGE;
|
||||
}
|
||||
|
||||
private boolean requestFocus(@Nullable View taskView) {
|
||||
if (taskView == null) {
|
||||
return false;
|
||||
}
|
||||
taskView.post(() -> {
|
||||
taskView.requestFocus();
|
||||
taskView.requestAccessibilityFocus();
|
||||
});
|
||||
return true;
|
||||
}
|
||||
|
||||
public void dump(PrintWriter pw) {
|
||||
@@ -374,7 +400,7 @@ public class OverviewCommandHelper {
|
||||
if (!mPendingCommands.isEmpty()) {
|
||||
pw.println(" pendingCommandType=" + mPendingCommands.get(0).type);
|
||||
}
|
||||
pw.println(" mTaskFocusIndexOverride=" + mTaskFocusIndexOverride);
|
||||
pw.println(" mKeyboardTaskFocusIndex=" + mKeyboardTaskFocusIndex);
|
||||
pw.println(" mWaitForToggleCommandComplete=" + mWaitForToggleCommandComplete);
|
||||
}
|
||||
|
||||
|
||||
@@ -40,6 +40,7 @@ import android.util.Log;
|
||||
import android.view.RemoteAnimationTarget;
|
||||
|
||||
import androidx.annotation.NonNull;
|
||||
import androidx.annotation.Nullable;
|
||||
|
||||
import com.android.launcher3.DeviceProfile;
|
||||
import com.android.launcher3.Utilities;
|
||||
@@ -344,6 +345,14 @@ public class TaskViewSimulator implements TransformParams.BuilderProxy {
|
||||
* Applies the target to the previously set parameters
|
||||
*/
|
||||
public void apply(TransformParams params) {
|
||||
apply(params, null);
|
||||
}
|
||||
|
||||
/**
|
||||
* Applies the target to the previously set parameters, optionally with an overridden
|
||||
* surface transaction
|
||||
*/
|
||||
public void apply(TransformParams params, @Nullable SurfaceTransaction surfaceTransaction) {
|
||||
if (mDp == null || mThumbnailPosition.isEmpty()) {
|
||||
return;
|
||||
}
|
||||
@@ -404,7 +413,8 @@ public class TaskViewSimulator implements TransformParams.BuilderProxy {
|
||||
mTempRectF.roundOut(mTmpCropRect);
|
||||
|
||||
params.setProgress(1f - fullScreenProgress);
|
||||
params.applySurfaceParams(params.createSurfaceParams(this));
|
||||
params.applySurfaceParams(surfaceTransaction == null
|
||||
? params.createSurfaceParams(this) : surfaceTransaction);
|
||||
|
||||
if (!DEBUG) {
|
||||
return;
|
||||
|
||||
@@ -542,6 +542,9 @@ public abstract class RecentsView<ACTIVITY_TYPE extends StatefulActivity<STATE_T
|
||||
private int mOverScrollShift = 0;
|
||||
private long mScrollLastHapticTimestamp;
|
||||
|
||||
private int mKeyboardTaskFocusSnapAnimationDuration;
|
||||
private int mKeyboardTaskFocusIndex = INVALID_PAGE;
|
||||
|
||||
/**
|
||||
* TODO: Call reloadIdNeeded in onTaskStackChanged.
|
||||
*/
|
||||
@@ -1704,6 +1707,7 @@ public abstract class RecentsView<ACTIVITY_TYPE extends StatefulActivity<STATE_T
|
||||
// Removing views sets the currentPage to 0, so we save this and restore it after
|
||||
// the new set of views are added
|
||||
int previousCurrentPage = mCurrentPage;
|
||||
int previousFocusedPage = indexOfChild(getFocusedChild());
|
||||
removeAllViews();
|
||||
|
||||
// If we are entering Overview as a result of initiating a split from somewhere else
|
||||
@@ -1833,6 +1837,8 @@ public abstract class RecentsView<ACTIVITY_TYPE extends StatefulActivity<STATE_T
|
||||
targetPage = indexOfChild(currentTaskView);
|
||||
}
|
||||
}
|
||||
} else if (previousFocusedPage != INVALID_PAGE) {
|
||||
targetPage = previousFocusedPage;
|
||||
} else {
|
||||
// Set the current page to the running task, but not if settling on new task.
|
||||
if (hasAnyValidTaskIds(runningTaskId)) {
|
||||
@@ -2914,7 +2920,7 @@ public abstract class RecentsView<ACTIVITY_TYPE extends StatefulActivity<STATE_T
|
||||
int focusedTaskShift = 0;
|
||||
int focusedTaskWidthAndSpacing = 0;
|
||||
int snappedTaskRowWidth = 0;
|
||||
int snappedPage = getNextPage();
|
||||
int snappedPage = isKeyboardTaskFocusPending() ? mKeyboardTaskFocusIndex : getNextPage();
|
||||
TaskView snappedTaskView = getTaskViewAt(snappedPage);
|
||||
TaskView homeTaskView = getHomeTaskView();
|
||||
TaskView nextFocusedTaskView = null;
|
||||
@@ -5576,6 +5582,19 @@ public abstract class RecentsView<ACTIVITY_TYPE extends StatefulActivity<STATE_T
|
||||
return getScrollOffset(getRunningTaskIndex());
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns how many pixels the running task is offset on the currently laid out dominant axis
|
||||
* specifically during a Keyboard task focus.
|
||||
*/
|
||||
public int getScrollOffsetForKeyboardTaskFocus() {
|
||||
if (!isKeyboardTaskFocusPending()) {
|
||||
return getScrollOffset(getRunningTaskIndex());
|
||||
}
|
||||
return getPagedOrientationHandler().getPrimaryScroll(this)
|
||||
- getScrollForPage(mKeyboardTaskFocusIndex)
|
||||
+ getScrollOffset(getRunningTaskIndex());
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets whether or not we should clamp the scroll offset.
|
||||
* This is used to avoid x-axis movement when swiping up transient taskbar.
|
||||
@@ -5609,14 +5628,14 @@ public abstract class RecentsView<ACTIVITY_TYPE extends StatefulActivity<STATE_T
|
||||
if (pageIndex == -1) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
int overScrollShift = getOverScrollShift();
|
||||
if (mAdjacentPageHorizontalOffset > 0) {
|
||||
// Don't dampen the scroll (due to overscroll) if the adjacent tasks are offscreen, so
|
||||
// that the page can move freely given there's no visual indication why it shouldn't.
|
||||
overScrollShift = (int) Utilities.mapRange(mAdjacentPageHorizontalOffset,
|
||||
overScrollShift, getUndampedOverScrollShift());
|
||||
}
|
||||
// Don't dampen the scroll (due to overscroll) if the adjacent tasks are offscreen, so that
|
||||
// the page can move freely given there's no visual indication why it shouldn't.
|
||||
int overScrollShift = mAdjacentPageHorizontalOffset > 0
|
||||
? (int) Utilities.mapRange(
|
||||
mAdjacentPageHorizontalOffset,
|
||||
getOverScrollShift(),
|
||||
getUndampedOverScrollShift())
|
||||
: getOverScrollShift();
|
||||
return getScrollForPage(pageIndex) - getPagedOrientationHandler().getPrimaryScroll(this)
|
||||
+ overScrollShift + getOffsetFromScrollPosition(pageIndex);
|
||||
}
|
||||
@@ -6025,11 +6044,50 @@ public abstract class RecentsView<ACTIVITY_TYPE extends StatefulActivity<STATE_T
|
||||
dispatchScrollChanged();
|
||||
}
|
||||
|
||||
/**
|
||||
* Prepares this RecentsView to scroll properly for an upcoming child view focus request from
|
||||
* keyboard quick switching
|
||||
*/
|
||||
public void setKeyboardTaskFocusIndex(int taskIndex) {
|
||||
mKeyboardTaskFocusIndex = taskIndex;
|
||||
}
|
||||
|
||||
/** Returns whether this RecentsView will be scrolling to a child view for a focus request */
|
||||
public boolean isKeyboardTaskFocusPending() {
|
||||
return mKeyboardTaskFocusIndex != INVALID_PAGE;
|
||||
}
|
||||
|
||||
private boolean isKeyboardTaskFocusPendingForChild(View child) {
|
||||
return isKeyboardTaskFocusPending() && mKeyboardTaskFocusIndex == indexOfChild(child);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected boolean shouldHandleRequestChildFocus() {
|
||||
// If we are already scrolling to a task view, then the focus request has already been
|
||||
// handled
|
||||
return mScroller.isFinished();
|
||||
protected int getSnapAnimationDuration() {
|
||||
return isKeyboardTaskFocusPending()
|
||||
? mKeyboardTaskFocusSnapAnimationDuration : super.getSnapAnimationDuration();
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void onVelocityValuesUpdated() {
|
||||
super.onVelocityValuesUpdated();
|
||||
mKeyboardTaskFocusSnapAnimationDuration =
|
||||
getResources().getInteger(R.integer.config_keyboardTaskFocusSnapAnimationDuration);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected boolean shouldHandleRequestChildFocus(View child) {
|
||||
// If we are already scrolling to a task view and we aren't focusing to this child from
|
||||
// keyboard quick switch, then the focus request has already been handled
|
||||
return mScroller.isFinished() || isKeyboardTaskFocusPendingForChild(child);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void requestChildFocus(View child, View focused) {
|
||||
if (isKeyboardTaskFocusPendingForChild(child)) {
|
||||
updateGridProperties();
|
||||
updateScrollSynchronously();
|
||||
}
|
||||
super.requestChildFocus(child, focused);
|
||||
}
|
||||
|
||||
private void dispatchScrollChanged() {
|
||||
|
||||
Reference in New Issue
Block a user