Deleting Quickscrub related logic
Bug: 124255113 Change-Id: Ic5f2338f1e3ae0a0cfb08f822dee0e01ae54a7b0
This commit is contained in:
parent
435041de60
commit
3f271d4b7f
|
@ -28,18 +28,6 @@ public final class GoLauncherAppTransitionManagerImpl extends QuickstepAppTransi
|
|||
return mLauncher.getStateManager().getState().overviewUi;
|
||||
}
|
||||
|
||||
@Override
|
||||
protected boolean isQuickSwitchInProgress() {
|
||||
// Go does not support quick scrub.
|
||||
return false;
|
||||
}
|
||||
|
||||
@Override
|
||||
protected ActivityOptions getQuickSwitchActivityOptions() {
|
||||
// Go does not support quick scrub.
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void composeRecentsLaunchAnimator(AnimatorSet anim, View v,
|
||||
RemoteAnimationTargetCompat[] targets, boolean launcherClosing) {
|
||||
|
|
|
@ -1,26 +0,0 @@
|
|||
/*
|
||||
* Copyright (C) 2019 The Android Open Source Project
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
package com.android.launcher3.uioverrides;
|
||||
|
||||
/**
|
||||
* Extension of overview state used for QuickScrub. Same as {@link OverviewState} for Go as we do
|
||||
* not support quickscrub.
|
||||
*/
|
||||
public final class FastOverviewState extends OverviewState {
|
||||
public FastOverviewState(int id) {
|
||||
super(id);
|
||||
}
|
||||
}
|
|
@ -18,7 +18,6 @@ package com.android.quickstep;
|
|||
|
||||
import static com.android.launcher3.LauncherState.OVERVIEW;
|
||||
|
||||
import android.app.ActivityManager;
|
||||
import android.content.Context;
|
||||
import android.graphics.Rect;
|
||||
|
||||
|
@ -31,7 +30,6 @@ import com.android.launcher3.anim.AnimatorPlaybackController;
|
|||
import com.android.launcher3.dragndrop.DragLayer;
|
||||
import com.android.launcher3.userevent.nano.LauncherLogProto;
|
||||
import com.android.launcher3.util.MultiValueAlpha.AlphaProperty;
|
||||
import com.android.quickstep.util.TransformedRect;
|
||||
import com.android.quickstep.views.IconRecentsView;
|
||||
import com.android.systemui.shared.system.RemoteAnimationTargetCompat;
|
||||
|
||||
|
@ -51,18 +49,6 @@ public final class LauncherActivityControllerHelper implements ActivityControlHe
|
|||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onQuickInteractionStart(Launcher activity, ActivityManager.RunningTaskInfo taskInfo,
|
||||
boolean activityVisible, TouchInteractionLog touchInteractionLog) {
|
||||
// Go does not have quick interactions.
|
||||
}
|
||||
|
||||
@Override
|
||||
public float getTranslationYForQuickScrub(TransformedRect targetRect, DeviceProfile dp,
|
||||
Context context) {
|
||||
// Go does not have quick scrub.
|
||||
return 0;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void executeOnWindowAvailable(Launcher activity, Runnable action) {
|
||||
|
@ -77,7 +63,7 @@ public final class LauncherActivityControllerHelper implements ActivityControlHe
|
|||
|
||||
@Override
|
||||
public int getSwipeUpDestinationAndLength(DeviceProfile dp, Context context,
|
||||
int interactionType, TransformedRect outRect) {
|
||||
Rect outRect) {
|
||||
// TODO Implement outRect depending on where the task should animate to.
|
||||
// Go does not support swipe up gesture.
|
||||
return 0;
|
||||
|
@ -101,8 +87,7 @@ public final class LauncherActivityControllerHelper implements ActivityControlHe
|
|||
//TODO: Implement this based off where the recents view needs to be for app => recents anim.
|
||||
return new AnimationFactory() {
|
||||
@Override
|
||||
public void createActivityController(long transitionLength,
|
||||
@TouchConsumer.InteractionType int interactionType) {}
|
||||
public void createActivityController(long transitionLength) {}
|
||||
|
||||
@Override
|
||||
public void onTransitionCancelled() {}
|
||||
|
@ -163,12 +148,6 @@ public final class LauncherActivityControllerHelper implements ActivityControlHe
|
|||
return true;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean deferStartingActivity(int downHitTarget) {
|
||||
// Go only supports back to overview so we always defer starting activity.
|
||||
return true;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean supportsLongSwipe(Launcher activity) {
|
||||
// Go does not support long swipe from the app.
|
||||
|
|
|
@ -60,34 +60,17 @@ public final class LauncherAppTransitionManagerImpl extends QuickstepAppTransiti
|
|||
&& findTaskViewToLaunch(mLauncher, v, targets) != null;
|
||||
}
|
||||
|
||||
@Override
|
||||
protected boolean isQuickSwitchInProgress() {
|
||||
return mRecentsView.getQuickScrubController().isQuickSwitch();
|
||||
}
|
||||
|
||||
@Override
|
||||
protected ActivityOptions getQuickSwitchActivityOptions() {
|
||||
return ActivityOptions.makeCustomAnimation(mLauncher, R.anim.no_anim,
|
||||
R.anim.no_anim);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void composeRecentsLaunchAnimator(@NonNull AnimatorSet anim, @NonNull View v,
|
||||
@NonNull RemoteAnimationTargetCompat[] targets, boolean launcherClosing) {
|
||||
RecentsView recentsView = mLauncher.getOverviewPanel();
|
||||
boolean skipLauncherChanges = !launcherClosing;
|
||||
boolean isLaunchingFromQuickscrub =
|
||||
recentsView.getQuickScrubController().isWaitingForTaskLaunch();
|
||||
|
||||
TaskView taskView = findTaskViewToLaunch(mLauncher, v, targets);
|
||||
|
||||
int duration = isLaunchingFromQuickscrub
|
||||
? RECENTS_QUICKSCRUB_LAUNCH_DURATION
|
||||
: RECENTS_LAUNCH_DURATION;
|
||||
|
||||
ClipAnimationHelper helper = new ClipAnimationHelper(mLauncher);
|
||||
anim.play(getRecentsWindowAnimator(taskView, skipLauncherChanges, targets, helper)
|
||||
.setDuration(duration));
|
||||
.setDuration(RECENTS_LAUNCH_DURATION));
|
||||
|
||||
Animator childStateAnimation = null;
|
||||
// Found a visible recents task that matches the opening app, lets launch the app from there
|
||||
|
@ -96,7 +79,7 @@ public final class LauncherAppTransitionManagerImpl extends QuickstepAppTransiti
|
|||
if (launcherClosing) {
|
||||
launcherAnim = recentsView.createAdjacentPageAnimForTaskLaunch(taskView, helper);
|
||||
launcherAnim.setInterpolator(Interpolators.TOUCH_RESPONSE_INTERPOLATOR);
|
||||
launcherAnim.setDuration(duration);
|
||||
launcherAnim.setDuration(RECENTS_LAUNCH_DURATION);
|
||||
|
||||
// Make sure recents gets fixed up by resetting task alphas and scales, etc.
|
||||
windowAnimEndListener = new AnimatorListenerAdapter() {
|
||||
|
@ -108,10 +91,11 @@ public final class LauncherAppTransitionManagerImpl extends QuickstepAppTransiti
|
|||
};
|
||||
} else {
|
||||
AnimatorPlaybackController controller =
|
||||
mLauncher.getStateManager().createAnimationToNewWorkspace(NORMAL, duration);
|
||||
mLauncher.getStateManager().createAnimationToNewWorkspace(NORMAL,
|
||||
RECENTS_LAUNCH_DURATION);
|
||||
controller.dispatchOnStart();
|
||||
childStateAnimation = controller.getTarget();
|
||||
launcherAnim = controller.getAnimationPlayer().setDuration(duration);
|
||||
launcherAnim = controller.getAnimationPlayer().setDuration(RECENTS_LAUNCH_DURATION);
|
||||
windowAnimEndListener = new AnimatorListenerAdapter() {
|
||||
@Override
|
||||
public void onAnimationEnd(Animator animation) {
|
||||
|
|
|
@ -15,10 +15,11 @@
|
|||
*/
|
||||
package com.android.launcher3.uioverrides;
|
||||
|
||||
import static com.android.launcher3.LauncherAnimUtils.OVERVIEW_TRANSITION_MS;
|
||||
|
||||
import android.os.RemoteException;
|
||||
import com.android.launcher3.Launcher;
|
||||
import com.android.launcher3.allapps.AllAppsTransitionController;
|
||||
import com.android.quickstep.QuickScrubController;
|
||||
import com.android.quickstep.RecentsModel;
|
||||
import com.android.quickstep.util.LayoutUtils;
|
||||
import com.android.quickstep.views.RecentsView;
|
||||
|
@ -33,7 +34,7 @@ public class BackgroundAppState extends OverviewState {
|
|||
FLAG_DISABLE_RESTORE | FLAG_OVERVIEW_UI | FLAG_DISABLE_ACCESSIBILITY;
|
||||
|
||||
public BackgroundAppState(int id) {
|
||||
super(id, QuickScrubController.QUICK_SCRUB_FROM_HOME_START_DURATION, STATE_FLAGS);
|
||||
super(id, OVERVIEW_TRANSITION_MS, STATE_FLAGS);
|
||||
}
|
||||
|
||||
@Override
|
||||
|
@ -51,7 +52,7 @@ public class BackgroundAppState extends OverviewState {
|
|||
|
||||
@Override
|
||||
public float[] getOverviewScaleAndTranslationYFactor(Launcher launcher) {
|
||||
// Initialize the recents view scale to what it would be when starting swipe up/quickscrub
|
||||
// Initialize the recents view scale to what it would be when starting swipe up
|
||||
RecentsView recentsView = launcher.getOverviewPanel();
|
||||
recentsView.getTaskSize(sTempRect);
|
||||
int appWidth = launcher.getDragLayer().getWidth();
|
||||
|
|
|
@ -1,95 +0,0 @@
|
|||
/*
|
||||
* Copyright (C) 2018 The Android Open Source Project
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
package com.android.launcher3.uioverrides;
|
||||
|
||||
import android.content.Context;
|
||||
import android.content.res.Resources;
|
||||
import android.graphics.Rect;
|
||||
|
||||
import com.android.launcher3.DeviceProfile;
|
||||
import com.android.launcher3.Launcher;
|
||||
import com.android.launcher3.R;
|
||||
import com.android.quickstep.QuickScrubController;
|
||||
import com.android.quickstep.views.RecentsView;
|
||||
|
||||
/**
|
||||
* Extension of overview state used for QuickScrub
|
||||
*/
|
||||
public class FastOverviewState extends OverviewState {
|
||||
|
||||
private static final float MAX_PREVIEW_SCALE_UP = 1.3f;
|
||||
/**
|
||||
* Vertical transition of the task previews relative to the full container.
|
||||
*/
|
||||
public static final float OVERVIEW_TRANSLATION_FACTOR = 0.4f;
|
||||
public static final float OVERVIEW_CENTERED_TRANSLATION_FACTOR = 0.5f;
|
||||
|
||||
private static final int STATE_FLAGS = FLAG_DISABLE_RESTORE | FLAG_DISABLE_INTERACTION
|
||||
| FLAG_OVERVIEW_UI | FLAG_HIDE_BACK_BUTTON | FLAG_DISABLE_ACCESSIBILITY;
|
||||
|
||||
public FastOverviewState(int id) {
|
||||
super(id, QuickScrubController.QUICK_SCRUB_FROM_HOME_START_DURATION, STATE_FLAGS);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onStateTransitionEnd(Launcher launcher) {
|
||||
super.onStateTransitionEnd(launcher);
|
||||
RecentsView recentsView = launcher.getOverviewPanel();
|
||||
recentsView.getQuickScrubController().onFinishedTransitionToQuickScrub();
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getVisibleElements(Launcher launcher) {
|
||||
return NONE;
|
||||
}
|
||||
|
||||
@Override
|
||||
public float[] getOverviewScaleAndTranslationYFactor(Launcher launcher) {
|
||||
RecentsView recentsView = launcher.getOverviewPanel();
|
||||
recentsView.getTaskSize(sTempRect);
|
||||
|
||||
boolean isQuickSwitch = recentsView.getQuickScrubController().isQuickSwitch();
|
||||
float translationYFactor = isQuickSwitch
|
||||
? OVERVIEW_CENTERED_TRANSLATION_FACTOR
|
||||
: OVERVIEW_TRANSLATION_FACTOR;
|
||||
return new float[] {getOverviewScale(launcher.getDeviceProfile(), sTempRect, launcher,
|
||||
isQuickSwitch), translationYFactor};
|
||||
}
|
||||
|
||||
public static float getOverviewScale(DeviceProfile dp, Rect taskRect, Context context,
|
||||
boolean isQuickSwitch) {
|
||||
if (dp.isVerticalBarLayout() && !isQuickSwitch) {
|
||||
return 1f;
|
||||
}
|
||||
|
||||
Resources res = context.getResources();
|
||||
float usedHeight = taskRect.height() + res.getDimension(R.dimen.task_thumbnail_top_margin);
|
||||
float usedWidth = taskRect.width() + 2 * (res.getDimension(R.dimen.recents_page_spacing)
|
||||
+ res.getDimension(R.dimen.quickscrub_adjacent_visible_width));
|
||||
if (isQuickSwitch) {
|
||||
usedWidth = taskRect.width();
|
||||
return Math.max(dp.availableHeightPx / usedHeight, dp.availableWidthPx / usedWidth);
|
||||
}
|
||||
return Math.min(Math.min(dp.availableHeightPx / usedHeight,
|
||||
dp.availableWidthPx / usedWidth), MAX_PREVIEW_SCALE_UP);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onStateDisabled(Launcher launcher) {
|
||||
super.onStateDisabled(launcher);
|
||||
launcher.<RecentsView>getOverviewPanel().getQuickScrubController().cancelActiveQuickscrub();
|
||||
}
|
||||
}
|
|
@ -15,10 +15,6 @@
|
|||
*/
|
||||
package com.android.launcher3.uioverrides;
|
||||
|
||||
import static com.android.launcher3.LauncherState.FAST_OVERVIEW;
|
||||
import static com.android.launcher3.LauncherState.OVERVIEW;
|
||||
import static com.android.quickstep.QuickScrubController.QUICK_SCRUB_START_INTERPOLATOR;
|
||||
import static com.android.quickstep.QuickScrubController.QUICK_SCRUB_TRANSLATION_Y_FACTOR;
|
||||
import static com.android.quickstep.views.LauncherRecentsView.TRANSLATION_Y_FACTOR;
|
||||
import static com.android.quickstep.views.RecentsView.CONTENT_ALPHA;
|
||||
|
||||
|
@ -26,18 +22,16 @@ import android.animation.ValueAnimator;
|
|||
import android.annotation.TargetApi;
|
||||
import android.os.Build;
|
||||
import android.util.FloatProperty;
|
||||
import android.view.animation.Interpolator;
|
||||
|
||||
import androidx.annotation.NonNull;
|
||||
|
||||
import com.android.launcher3.Launcher;
|
||||
import com.android.launcher3.LauncherState;
|
||||
import com.android.launcher3.LauncherStateManager.AnimationConfig;
|
||||
import com.android.launcher3.anim.AnimatorSetBuilder;
|
||||
import com.android.launcher3.anim.Interpolators;
|
||||
import com.android.quickstep.views.LauncherRecentsView;
|
||||
import com.android.quickstep.views.RecentsView;
|
||||
|
||||
import androidx.annotation.NonNull;
|
||||
|
||||
/**
|
||||
* State handler for handling UI changes for {@link LauncherRecentsView}. In addition to managing
|
||||
* the basic view properties, this class also manages changes in the task visuals.
|
||||
|
@ -80,16 +74,6 @@ public final class RecentsViewStateController extends
|
|||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
Interpolator getScaleAndTransYInterpolator(@NonNull LauncherState toState,
|
||||
@NonNull AnimatorSetBuilder builder) {
|
||||
if (mLauncher.getStateManager().getState() == OVERVIEW && toState == FAST_OVERVIEW) {
|
||||
return Interpolators.clampToProgress(QUICK_SCRUB_START_INTERPOLATOR, 0,
|
||||
QUICK_SCRUB_TRANSLATION_Y_FACTOR);
|
||||
}
|
||||
return super.getScaleAndTransYInterpolator(toState, builder);
|
||||
}
|
||||
|
||||
@Override
|
||||
FloatProperty<LauncherRecentsView> getTranslationYFactorProperty() {
|
||||
return TRANSLATION_Y_FACTOR;
|
||||
|
|
|
@ -19,23 +19,16 @@ import static android.view.View.TRANSLATION_Y;
|
|||
|
||||
import static com.android.launcher3.LauncherAnimUtils.SCALE_PROPERTY;
|
||||
import static com.android.launcher3.LauncherState.BACKGROUND_APP;
|
||||
import static com.android.launcher3.LauncherState.FAST_OVERVIEW;
|
||||
import static com.android.launcher3.LauncherState.NORMAL;
|
||||
import static com.android.launcher3.LauncherState.OVERVIEW;
|
||||
import static com.android.launcher3.allapps.AllAppsTransitionController.SPRING_DAMPING_RATIO;
|
||||
import static com.android.launcher3.allapps.AllAppsTransitionController.SPRING_STIFFNESS;
|
||||
import static com.android.launcher3.anim.Interpolators.LINEAR;
|
||||
import static com.android.launcher3.states.RotationHelper.REQUEST_LOCK;
|
||||
import static com.android.quickstep.TouchConsumer.INTERACTION_NORMAL;
|
||||
import static com.android.quickstep.TouchConsumer.INTERACTION_QUICK_SCRUB;
|
||||
import static com.android.systemui.shared.system.NavigationBarCompat.HIT_TARGET_BACK;
|
||||
import static com.android.systemui.shared.system.NavigationBarCompat.HIT_TARGET_ROTATION;
|
||||
|
||||
import android.animation.Animator;
|
||||
import android.animation.AnimatorListenerAdapter;
|
||||
import android.animation.AnimatorSet;
|
||||
import android.animation.ObjectAnimator;
|
||||
import android.app.ActivityManager.RunningTaskInfo;
|
||||
import android.content.Context;
|
||||
import android.graphics.Rect;
|
||||
import android.graphics.RectF;
|
||||
|
@ -44,16 +37,11 @@ import android.view.MotionEvent;
|
|||
import android.view.View;
|
||||
import android.view.animation.Interpolator;
|
||||
|
||||
import androidx.annotation.NonNull;
|
||||
import androidx.annotation.Nullable;
|
||||
import androidx.annotation.UiThread;
|
||||
|
||||
import com.android.launcher3.DeviceProfile;
|
||||
import com.android.launcher3.Launcher;
|
||||
import com.android.launcher3.LauncherAppState;
|
||||
import com.android.launcher3.LauncherInitListener;
|
||||
import com.android.launcher3.LauncherState;
|
||||
import com.android.launcher3.R;
|
||||
import com.android.launcher3.TestProtocol;
|
||||
import com.android.launcher3.allapps.DiscoveryBounce;
|
||||
import com.android.launcher3.anim.AnimatorPlaybackController;
|
||||
|
@ -61,13 +49,10 @@ import com.android.launcher3.anim.SpringObjectAnimator;
|
|||
import com.android.launcher3.compat.AccessibilityManagerCompat;
|
||||
import com.android.launcher3.config.FeatureFlags;
|
||||
import com.android.launcher3.dragndrop.DragLayer;
|
||||
import com.android.launcher3.uioverrides.FastOverviewState;
|
||||
import com.android.launcher3.userevent.nano.LauncherLogProto;
|
||||
import com.android.launcher3.util.MultiValueAlpha.AlphaProperty;
|
||||
import com.android.quickstep.TouchConsumer.InteractionType;
|
||||
import com.android.quickstep.util.ClipAnimationHelper;
|
||||
import com.android.quickstep.util.LayoutUtils;
|
||||
import com.android.quickstep.util.TransformedRect;
|
||||
import com.android.quickstep.views.LauncherLayoutListener;
|
||||
import com.android.quickstep.views.RecentsView;
|
||||
import com.android.quickstep.views.TaskView;
|
||||
|
@ -76,6 +61,10 @@ import com.android.systemui.shared.system.RemoteAnimationTargetCompat;
|
|||
import java.util.function.BiPredicate;
|
||||
import java.util.function.Consumer;
|
||||
|
||||
import androidx.annotation.NonNull;
|
||||
import androidx.annotation.Nullable;
|
||||
import androidx.annotation.UiThread;
|
||||
|
||||
/**
|
||||
* {@link ActivityControlHelper} for the in-launcher recents.
|
||||
*/
|
||||
|
@ -86,60 +75,14 @@ public final class LauncherActivityControllerHelper implements ActivityControlHe
|
|||
return LauncherLayoutListener.resetAndGet(activity);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onQuickInteractionStart(Launcher activity, RunningTaskInfo taskInfo,
|
||||
boolean activityVisible, TouchInteractionLog touchInteractionLog) {
|
||||
LauncherState fromState = activity.getStateManager().getState();
|
||||
QuickScrubController controller = activity.<RecentsView>getOverviewPanel()
|
||||
.getQuickScrubController();
|
||||
boolean isQuickSwitch = controller.isQuickSwitch();
|
||||
boolean animate = activityVisible;
|
||||
if (isQuickSwitch && fromState == FAST_OVERVIEW && !animate) {
|
||||
// We can already be in FAST_OVERVIEW if createActivityController() was called
|
||||
// before us. This could happen, for instance, when launcher is slow to load when
|
||||
// starting quick switch, causing us to call onQuickScrubStart() on the background
|
||||
// thread. In this case, we also hadn't set isQuickSwitch = true before setting
|
||||
// FAST_OVERVIEW, so we need to reapply FAST_OVERVIEW to take that into account.
|
||||
activity.getStateManager().reapplyState();
|
||||
} else {
|
||||
activity.getStateManager().goToState(FAST_OVERVIEW, animate);
|
||||
}
|
||||
|
||||
controller.onQuickScrubStart(activityVisible && !fromState.overviewUi, this,
|
||||
touchInteractionLog);
|
||||
|
||||
if (!activityVisible) {
|
||||
// For the duration of the gesture, lock the screen orientation to ensure that we
|
||||
// do not rotate mid-quickscrub
|
||||
activity.getRotationHelper().setStateHandlerRequest(REQUEST_LOCK);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public float getTranslationYForQuickScrub(TransformedRect targetRect, DeviceProfile dp,
|
||||
Context context) {
|
||||
// The padding calculations are exactly same as that of RecentsView.setInsets
|
||||
int topMargin = context.getResources()
|
||||
.getDimensionPixelSize(R.dimen.task_thumbnail_top_margin);
|
||||
int paddingTop = targetRect.rect.top - topMargin - dp.getInsets().top;
|
||||
int paddingBottom = dp.heightPx - dp.getInsets().bottom - targetRect.rect.bottom;
|
||||
|
||||
return FastOverviewState.OVERVIEW_TRANSLATION_FACTOR * (paddingBottom - paddingTop);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void executeOnWindowAvailable(Launcher activity, Runnable action) {
|
||||
activity.getWorkspace().runOnOverlayHidden(action);
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getSwipeUpDestinationAndLength(DeviceProfile dp, Context context,
|
||||
@InteractionType int interactionType, TransformedRect outRect) {
|
||||
LayoutUtils.calculateLauncherTaskSize(context, dp, outRect.rect);
|
||||
if (interactionType == INTERACTION_QUICK_SCRUB) {
|
||||
outRect.scale = FastOverviewState.getOverviewScale(dp, outRect.rect, context,
|
||||
FeatureFlags.QUICK_SWITCH.get());
|
||||
}
|
||||
public int getSwipeUpDestinationAndLength(DeviceProfile dp, Context context, Rect outRect) {
|
||||
LayoutUtils.calculateLauncherTaskSize(context, dp, outRect);
|
||||
if (dp.isVerticalBarLayout()) {
|
||||
Rect targetInsets = dp.getInsets();
|
||||
int hotseatInset = dp.isSeascape() ? targetInsets.left : targetInsets.right;
|
||||
|
@ -221,10 +164,9 @@ public final class LauncherActivityControllerHelper implements ActivityControlHe
|
|||
private ShelfAnimState mShelfState;
|
||||
|
||||
@Override
|
||||
public void createActivityController(long transitionLength,
|
||||
@InteractionType int interactionType) {
|
||||
public void createActivityController(long transitionLength) {
|
||||
createActivityControllerInternal(activity, activityVisible, fromState,
|
||||
transitionLength, interactionType, callback);
|
||||
transitionLength, callback);
|
||||
}
|
||||
|
||||
@Override
|
||||
|
@ -270,10 +212,8 @@ public final class LauncherActivityControllerHelper implements ActivityControlHe
|
|||
|
||||
private void createActivityControllerInternal(Launcher activity, boolean wasVisible,
|
||||
LauncherState fromState, long transitionLength,
|
||||
@InteractionType int interactionType,
|
||||
Consumer<AnimatorPlaybackController> callback) {
|
||||
LauncherState endState = interactionType == INTERACTION_QUICK_SCRUB
|
||||
? FAST_OVERVIEW : OVERVIEW;
|
||||
LauncherState endState = OVERVIEW;
|
||||
if (wasVisible && fromState != BACKGROUND_APP) {
|
||||
// If a translucent app was launched fom launcher, animate launcher states.
|
||||
DeviceProfile dp = activity.getDeviceProfile();
|
||||
|
@ -295,10 +235,7 @@ public final class LauncherActivityControllerHelper implements ActivityControlHe
|
|||
endState.getVerticalProgress(activity));
|
||||
anim.play(shiftAnim);
|
||||
}
|
||||
|
||||
if (interactionType == INTERACTION_NORMAL) {
|
||||
playScaleDownAnim(anim, activity, endState);
|
||||
}
|
||||
playScaleDownAnim(anim, activity, endState);
|
||||
|
||||
anim.setDuration(transitionLength * 2);
|
||||
activity.getStateManager().setCurrentAnimation(anim);
|
||||
|
@ -407,11 +344,6 @@ public final class LauncherActivityControllerHelper implements ActivityControlHe
|
|||
return true;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean deferStartingActivity(int downHitTarget) {
|
||||
return downHitTarget == HIT_TARGET_BACK || downHitTarget == HIT_TARGET_ROTATION;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean deferStartingActivity(Region activeNavBarRegion, MotionEvent ev) {
|
||||
return activeNavBarRegion.contains((int) ev.getX(), (int) ev.getY());
|
||||
|
|
|
@ -112,7 +112,6 @@ public abstract class QuickstepAppTransitionManagerImpl extends LauncherAppTrans
|
|||
private static final int APP_LAUNCH_ALPHA_DURATION = 50;
|
||||
|
||||
public static final int RECENTS_LAUNCH_DURATION = 336;
|
||||
public static final int RECENTS_QUICKSCRUB_LAUNCH_DURATION = 300;
|
||||
private static final int LAUNCHER_RESUME_START_DELAY = 100;
|
||||
private static final int CLOSING_TRANSITION_DURATION_MS = 250;
|
||||
|
||||
|
@ -181,10 +180,6 @@ public abstract class QuickstepAppTransitionManagerImpl extends LauncherAppTrans
|
|||
public ActivityOptions getActivityLaunchOptions(Launcher launcher, View v) {
|
||||
if (hasControlRemoteAppTransitionPermission()) {
|
||||
boolean fromRecents = isLaunchingFromRecents(v, null /* targets */);
|
||||
if (fromRecents && isQuickSwitchInProgress()) {
|
||||
return getQuickSwitchActivityOptions();
|
||||
}
|
||||
|
||||
RemoteAnimationRunnerCompat runner = new LauncherAnimationRunner(mHandler,
|
||||
true /* startAtFrontOfQueue */) {
|
||||
|
||||
|
@ -237,20 +232,6 @@ public abstract class QuickstepAppTransitionManagerImpl extends LauncherAppTrans
|
|||
protected abstract boolean isLaunchingFromRecents(@NonNull View v,
|
||||
@Nullable RemoteAnimationTargetCompat[] targets);
|
||||
|
||||
/**
|
||||
* Whether a quick scrub is in progress.
|
||||
*
|
||||
* @return true if in progress
|
||||
*/
|
||||
protected abstract boolean isQuickSwitchInProgress();
|
||||
|
||||
/**
|
||||
* Get activity options for a quick switch launch that include the launch animation.
|
||||
*
|
||||
* @return the activity options for a quick switch recents launch
|
||||
*/
|
||||
protected abstract ActivityOptions getQuickSwitchActivityOptions();
|
||||
|
||||
/**
|
||||
* Composes the animations for a launch from the recents list.
|
||||
*
|
||||
|
|
|
@ -125,8 +125,8 @@ public class UiFactory extends RecentsUiFactory {
|
|||
|
||||
public static void onEnterAnimationComplete(Context context) {
|
||||
// After the transition to home, enable the high-res thumbnail loader if it wasn't enabled
|
||||
// as a part of quickstep/scrub, so that high-res thumbnails can load the next time we
|
||||
// enter overview
|
||||
// as a part of quickstep, so that high-res thumbnails can load the next time we enter
|
||||
// overview
|
||||
RecentsModel.INSTANCE.get(context).getThumbnailCache()
|
||||
.getHighResLoadingState().setVisible(true);
|
||||
}
|
||||
|
|
|
@ -17,7 +17,6 @@ package com.android.quickstep;
|
|||
|
||||
import android.animation.Animator;
|
||||
import android.annotation.TargetApi;
|
||||
import android.app.ActivityManager.RunningTaskInfo;
|
||||
import android.content.Context;
|
||||
import android.content.Intent;
|
||||
import android.graphics.Rect;
|
||||
|
@ -29,24 +28,21 @@ import android.view.MotionEvent;
|
|||
import android.view.View;
|
||||
import android.view.animation.Interpolator;
|
||||
|
||||
import androidx.annotation.NonNull;
|
||||
import androidx.annotation.Nullable;
|
||||
import androidx.annotation.UiThread;
|
||||
|
||||
import com.android.launcher3.BaseDraggingActivity;
|
||||
import com.android.launcher3.DeviceProfile;
|
||||
import com.android.launcher3.anim.AnimatorPlaybackController;
|
||||
import com.android.launcher3.util.MultiValueAlpha.AlphaProperty;
|
||||
import com.android.quickstep.TouchConsumer.InteractionType;
|
||||
import com.android.quickstep.util.RemoteAnimationProvider;
|
||||
import com.android.quickstep.util.RemoteAnimationTargetSet;
|
||||
import com.android.quickstep.util.TransformedRect;
|
||||
import com.android.quickstep.views.RecentsView;
|
||||
import com.android.systemui.shared.system.RemoteAnimationTargetCompat;
|
||||
|
||||
import java.util.function.BiPredicate;
|
||||
import java.util.function.Consumer;
|
||||
|
||||
import androidx.annotation.NonNull;
|
||||
import androidx.annotation.Nullable;
|
||||
import androidx.annotation.UiThread;
|
||||
|
||||
/**
|
||||
* Utility class which abstracts out the logical differences between Launcher and RecentsActivity.
|
||||
*/
|
||||
|
@ -55,21 +51,11 @@ public interface ActivityControlHelper<T extends BaseDraggingActivity> {
|
|||
|
||||
LayoutListener createLayoutListener(T activity);
|
||||
|
||||
/**
|
||||
* Updates the UI to indicate quick interaction.
|
||||
*/
|
||||
void onQuickInteractionStart(T activity, @Nullable RunningTaskInfo taskInfo,
|
||||
boolean activityVisible, TouchInteractionLog touchInteractionLog);
|
||||
|
||||
float getTranslationYForQuickScrub(TransformedRect targetRect, DeviceProfile dp,
|
||||
Context context);
|
||||
|
||||
void executeOnWindowAvailable(T activity, Runnable action);
|
||||
|
||||
void onTransitionCancelled(T activity, boolean activityVisible);
|
||||
|
||||
int getSwipeUpDestinationAndLength(DeviceProfile dp, Context context,
|
||||
@InteractionType int interactionType, TransformedRect outRect);
|
||||
int getSwipeUpDestinationAndLength(DeviceProfile dp, Context context, Rect outRect);
|
||||
|
||||
void onSwipeUpComplete(T activity);
|
||||
|
||||
|
@ -99,12 +85,6 @@ public interface ActivityControlHelper<T extends BaseDraggingActivity> {
|
|||
|
||||
boolean shouldMinimizeSplitScreen();
|
||||
|
||||
/**
|
||||
* @return {@code true} if recents activity should be started immediately on touchDown,
|
||||
* {@code false} if it should deferred until some threshold is crossed.
|
||||
*/
|
||||
boolean deferStartingActivity(int downHitTarget);
|
||||
|
||||
default boolean deferStartingActivity(Region activeNavBarRegion, MotionEvent ev) {
|
||||
return true;
|
||||
}
|
||||
|
@ -161,7 +141,7 @@ public interface ActivityControlHelper<T extends BaseDraggingActivity> {
|
|||
|
||||
default void onRemoteAnimationReceived(RemoteAnimationTargetSet targets) { }
|
||||
|
||||
void createActivityController(long transitionLength, @InteractionType int interactionType);
|
||||
void createActivityController(long transitionLength);
|
||||
|
||||
default void onTransitionCancelled() { }
|
||||
|
||||
|
|
|
@ -17,7 +17,6 @@ package com.android.quickstep;
|
|||
|
||||
import static com.android.launcher3.anim.Interpolators.FAST_OUT_SLOW_IN;
|
||||
import static com.android.launcher3.anim.Interpolators.TOUCH_RESPONSE_INTERPOLATOR;
|
||||
import static com.android.quickstep.TouchConsumer.INTERACTION_NORMAL;
|
||||
import static com.android.systemui.shared.system.RemoteAnimationTargetCompat.MODE_CLOSING;
|
||||
import static com.android.systemui.shared.system.RemoteAnimationTargetCompat.MODE_OPENING;
|
||||
|
||||
|
@ -34,7 +33,6 @@ import com.android.launcher3.anim.AnimationSuccessListener;
|
|||
import com.android.quickstep.util.ClipAnimationHelper;
|
||||
import com.android.quickstep.util.RemoteAnimationProvider;
|
||||
import com.android.quickstep.util.RemoteAnimationTargetSet;
|
||||
import com.android.quickstep.util.TransformedRect;
|
||||
import com.android.quickstep.views.RecentsView;
|
||||
import com.android.systemui.shared.system.RemoteAnimationTargetCompat;
|
||||
import com.android.systemui.shared.system.SyncRtSurfaceTransactionApplierCompat;
|
||||
|
@ -82,7 +80,7 @@ final class AppToOverviewAnimationProvider<T extends BaseDraggingActivity> imple
|
|||
anim.start();
|
||||
});
|
||||
factory.onRemoteAnimationReceived(null);
|
||||
factory.createActivityController(RECENTS_LAUNCH_DURATION, INTERACTION_NORMAL);
|
||||
factory.createActivityController(RECENTS_LAUNCH_DURATION);
|
||||
mActivity = activity;
|
||||
mRecentsView = mActivity.getOverviewPanel();
|
||||
return false;
|
||||
|
@ -136,9 +134,8 @@ final class AppToOverviewAnimationProvider<T extends BaseDraggingActivity> imple
|
|||
loc[0] + rootView.getWidth(), loc[1] + rootView.getHeight());
|
||||
clipHelper.updateSource(homeBounds, runningTaskTarget);
|
||||
|
||||
TransformedRect targetRect = new TransformedRect();
|
||||
mHelper.getSwipeUpDestinationAndLength(mActivity.getDeviceProfile(), mActivity,
|
||||
INTERACTION_NORMAL, targetRect);
|
||||
Rect targetRect = new Rect();
|
||||
mHelper.getSwipeUpDestinationAndLength(mActivity.getDeviceProfile(), mActivity, targetRect);
|
||||
clipHelper.updateTargetRect(targetRect);
|
||||
clipHelper.prepareAnimation(false /* isOpening */);
|
||||
|
||||
|
|
|
@ -15,41 +15,33 @@
|
|||
*/
|
||||
package com.android.quickstep;
|
||||
|
||||
import static com.android.launcher3.LauncherAnimUtils.OVERVIEW_TRANSITION_MS;
|
||||
import static com.android.launcher3.anim.Interpolators.LINEAR;
|
||||
import static com.android.quickstep.TouchConsumer.INTERACTION_NORMAL;
|
||||
import static com.android.quickstep.views.RecentsView.CONTENT_ALPHA;
|
||||
|
||||
import android.animation.Animator;
|
||||
import android.animation.AnimatorSet;
|
||||
import android.animation.ObjectAnimator;
|
||||
import android.app.ActivityManager.RunningTaskInfo;
|
||||
import android.content.ComponentName;
|
||||
import android.content.Context;
|
||||
import android.graphics.Rect;
|
||||
import android.graphics.RectF;
|
||||
import android.os.Handler;
|
||||
import android.os.Looper;
|
||||
|
||||
import androidx.annotation.NonNull;
|
||||
import androidx.annotation.Nullable;
|
||||
|
||||
import com.android.launcher3.DeviceProfile;
|
||||
import com.android.launcher3.anim.AnimationSuccessListener;
|
||||
import com.android.launcher3.anim.AnimatorPlaybackController;
|
||||
import com.android.launcher3.userevent.nano.LauncherLogProto;
|
||||
import com.android.launcher3.util.MultiValueAlpha.AlphaProperty;
|
||||
import com.android.quickstep.TouchConsumer.InteractionType;
|
||||
import com.android.quickstep.util.LayoutUtils;
|
||||
import com.android.quickstep.util.RemoteAnimationTargetSet;
|
||||
import com.android.quickstep.util.TransformedRect;
|
||||
import com.android.quickstep.views.RecentsView;
|
||||
import com.android.systemui.shared.system.RemoteAnimationTargetCompat;
|
||||
|
||||
import java.util.Objects;
|
||||
import java.util.function.BiPredicate;
|
||||
import java.util.function.Consumer;
|
||||
|
||||
import androidx.annotation.NonNull;
|
||||
import androidx.annotation.Nullable;
|
||||
|
||||
/**
|
||||
* {@link ActivityControlHelper} for recents when the default launcher is different than the
|
||||
* currently running one and apps should interact with the {@link RecentsActivity} as opposed
|
||||
|
@ -59,34 +51,11 @@ public final class FallbackActivityControllerHelper implements
|
|||
ActivityControlHelper<RecentsActivity> {
|
||||
|
||||
private final ComponentName mHomeComponent;
|
||||
private final Handler mUiHandler = new Handler(Looper.getMainLooper());
|
||||
|
||||
public FallbackActivityControllerHelper(ComponentName homeComponent) {
|
||||
mHomeComponent = homeComponent;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onQuickInteractionStart(RecentsActivity activity, RunningTaskInfo taskInfo,
|
||||
boolean activityVisible, TouchInteractionLog touchInteractionLog) {
|
||||
QuickScrubController controller = activity.<RecentsView>getOverviewPanel()
|
||||
.getQuickScrubController();
|
||||
|
||||
// TODO: match user is as well
|
||||
boolean startingFromHome = !activityVisible &&
|
||||
(taskInfo == null || Objects.equals(taskInfo.topActivity, mHomeComponent));
|
||||
controller.onQuickScrubStart(startingFromHome, this, touchInteractionLog);
|
||||
if (activityVisible) {
|
||||
mUiHandler.postDelayed(controller::onFinishedTransitionToQuickScrub,
|
||||
OVERVIEW_TRANSITION_MS);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public float getTranslationYForQuickScrub(TransformedRect targetRect, DeviceProfile dp,
|
||||
Context context) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void executeOnWindowAvailable(RecentsActivity activity, Runnable action) {
|
||||
action.run();
|
||||
|
@ -98,15 +67,14 @@ public final class FallbackActivityControllerHelper implements
|
|||
}
|
||||
|
||||
@Override
|
||||
public int getSwipeUpDestinationAndLength(DeviceProfile dp, Context context,
|
||||
@InteractionType int interactionType, TransformedRect outRect) {
|
||||
LayoutUtils.calculateFallbackTaskSize(context, dp, outRect.rect);
|
||||
public int getSwipeUpDestinationAndLength(DeviceProfile dp, Context context, Rect outRect) {
|
||||
LayoutUtils.calculateFallbackTaskSize(context, dp, outRect);
|
||||
if (dp.isVerticalBarLayout()) {
|
||||
Rect targetInsets = dp.getInsets();
|
||||
int hotseatInset = dp.isSeascape() ? targetInsets.left : targetInsets.right;
|
||||
return dp.hotseatBarSizePx + hotseatInset;
|
||||
} else {
|
||||
return dp.heightPx - outRect.rect.bottom;
|
||||
return dp.heightPx - outRect.bottom;
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -148,7 +116,7 @@ public final class FallbackActivityControllerHelper implements
|
|||
public AnimationFactory prepareRecentsUI(RecentsActivity activity, boolean activityVisible,
|
||||
boolean animateActivity, Consumer<AnimatorPlaybackController> callback) {
|
||||
if (activityVisible) {
|
||||
return (transitionLength, interactionType) -> { };
|
||||
return (transitionLength) -> { };
|
||||
}
|
||||
|
||||
RecentsView rv = activity.getOverviewPanel();
|
||||
|
@ -165,12 +133,11 @@ public final class FallbackActivityControllerHelper implements
|
|||
rv.setContentAlpha(1);
|
||||
}
|
||||
createActivityController(getSwipeUpDestinationAndLength(
|
||||
activity.getDeviceProfile(), activity, INTERACTION_NORMAL,
|
||||
new TransformedRect()), INTERACTION_NORMAL);
|
||||
activity.getDeviceProfile(), activity, new Rect()));
|
||||
}
|
||||
|
||||
@Override
|
||||
public void createActivityController(long transitionLength, int interactionType) {
|
||||
public void createActivityController(long transitionLength) {
|
||||
if (!isAnimatingToRecents) {
|
||||
return;
|
||||
}
|
||||
|
@ -231,12 +198,6 @@ public final class FallbackActivityControllerHelper implements
|
|||
return false;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean deferStartingActivity(int downHitTarget) {
|
||||
// Always defer starting the activity when using fallback
|
||||
return true;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Rect getOverviewWindowBounds(Rect homeBounds, RemoteAnimationTargetCompat target) {
|
||||
// TODO: Remove this once b/77875376 is fixed
|
||||
|
|
|
@ -1,159 +0,0 @@
|
|||
/*
|
||||
* Copyright (C) 2017 The Android Open Source Project
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
package com.android.quickstep;
|
||||
|
||||
import static android.view.MotionEvent.ACTION_MASK;
|
||||
import static android.view.MotionEvent.ACTION_POINTER_INDEX_SHIFT;
|
||||
|
||||
import android.annotation.TargetApi;
|
||||
import android.os.Build;
|
||||
import android.os.Looper;
|
||||
import android.util.Log;
|
||||
import android.util.Pair;
|
||||
import android.view.Choreographer;
|
||||
import android.view.InputEvent;
|
||||
import android.view.MotionEvent;
|
||||
|
||||
import com.android.systemui.shared.system.InputChannelCompat;
|
||||
import com.android.systemui.shared.system.InputChannelCompat.InputEventDispatcher;
|
||||
import com.android.systemui.shared.system.InputChannelCompat.InputEventReceiver;
|
||||
import com.android.systemui.shared.system.NavigationBarCompat.HitTarget;
|
||||
|
||||
/**
|
||||
* Helper class for batching input events
|
||||
*/
|
||||
@TargetApi(Build.VERSION_CODES.O)
|
||||
public class MotionEventQueue {
|
||||
|
||||
private static final String TAG = "MotionEventQueue";
|
||||
|
||||
private static final int ACTION_VIRTUAL = ACTION_MASK - 1;
|
||||
|
||||
private static final int ACTION_QUICK_SCRUB_START =
|
||||
ACTION_VIRTUAL | (1 << ACTION_POINTER_INDEX_SHIFT);
|
||||
private static final int ACTION_QUICK_SCRUB_PROGRESS =
|
||||
ACTION_VIRTUAL | (2 << ACTION_POINTER_INDEX_SHIFT);
|
||||
private static final int ACTION_QUICK_SCRUB_END =
|
||||
ACTION_VIRTUAL | (3 << ACTION_POINTER_INDEX_SHIFT);
|
||||
private static final int ACTION_NEW_GESTURE =
|
||||
ACTION_VIRTUAL | (4 << ACTION_POINTER_INDEX_SHIFT);
|
||||
private static final int ACTION_SHOW_OVERVIEW_FROM_ALT_TAB =
|
||||
ACTION_VIRTUAL | (5 << ACTION_POINTER_INDEX_SHIFT);
|
||||
|
||||
private final InputEventDispatcher mDispatcher;
|
||||
private final InputEventReceiver mReceiver;
|
||||
private final ConsumerFactory mConsumerFactory;
|
||||
|
||||
private TouchConsumer mConsumer;
|
||||
|
||||
public MotionEventQueue(Looper looper, Choreographer choreographer,
|
||||
ConsumerFactory consumerFactory) {
|
||||
Pair<InputEventDispatcher, InputEventReceiver> pair = InputChannelCompat.createPair(
|
||||
"sysui-callbacks", looper, choreographer, this::onInputEvent);
|
||||
|
||||
mConsumerFactory = consumerFactory;
|
||||
mConsumer = TouchConsumer.NO_OP;
|
||||
mDispatcher = pair.first;
|
||||
mReceiver = pair.second;
|
||||
}
|
||||
|
||||
private void onInputEvent(InputEvent ev) {
|
||||
if (!(ev instanceof MotionEvent)) {
|
||||
throw new IllegalStateException("Unknown event " + ev);
|
||||
}
|
||||
MotionEvent event = (MotionEvent) ev;
|
||||
if (event.getActionMasked() == ACTION_VIRTUAL) {
|
||||
switch (event.getAction()) {
|
||||
case ACTION_QUICK_SCRUB_START:
|
||||
mConsumer.onQuickScrubStart();
|
||||
break;
|
||||
case ACTION_QUICK_SCRUB_PROGRESS:
|
||||
mConsumer.onQuickScrubProgress(event.getX());
|
||||
break;
|
||||
case ACTION_QUICK_SCRUB_END:
|
||||
mConsumer.onQuickScrubEnd();
|
||||
break;
|
||||
case ACTION_NEW_GESTURE: {
|
||||
boolean useSharedState = mConsumer.isActive();
|
||||
mConsumer.onConsumerAboutToBeSwitched();
|
||||
mConsumer = mConsumerFactory.newConsumer(event.getSource(), useSharedState);
|
||||
break;
|
||||
}
|
||||
case ACTION_SHOW_OVERVIEW_FROM_ALT_TAB:
|
||||
mConsumer.onShowOverviewFromAltTab();
|
||||
mConsumer.onQuickScrubStart();
|
||||
break;
|
||||
default:
|
||||
Log.e(TAG, "Invalid virtual event: " + event.getAction());
|
||||
}
|
||||
} else {
|
||||
mConsumer.accept(event);
|
||||
}
|
||||
}
|
||||
|
||||
public void queue(MotionEvent event) {
|
||||
mDispatcher.dispatch(event);
|
||||
}
|
||||
|
||||
private void queueVirtualAction(int action, float param) {
|
||||
queue(MotionEvent.obtain(0, 0, action, param, 0, 0));
|
||||
}
|
||||
|
||||
private void queueVirtualAction(int action, int param) {
|
||||
MotionEvent ev = MotionEvent.obtain(0, 0, action, 0, 0, 0);
|
||||
ev.setSource(param);
|
||||
queue(ev);
|
||||
}
|
||||
|
||||
public void onQuickScrubStart() {
|
||||
queueVirtualAction(ACTION_QUICK_SCRUB_START, 0);
|
||||
}
|
||||
|
||||
public void onOverviewShownFromAltTab() {
|
||||
queueVirtualAction(ACTION_SHOW_OVERVIEW_FROM_ALT_TAB, 0);
|
||||
}
|
||||
|
||||
public void onQuickScrubProgress(float progress) {
|
||||
queueVirtualAction(ACTION_QUICK_SCRUB_PROGRESS, progress);
|
||||
}
|
||||
|
||||
public void onQuickScrubEnd() {
|
||||
queueVirtualAction(ACTION_QUICK_SCRUB_END, 0);
|
||||
}
|
||||
|
||||
public void onNewGesture(@HitTarget int downHitTarget) {
|
||||
queueVirtualAction(ACTION_NEW_GESTURE, downHitTarget);
|
||||
}
|
||||
|
||||
/**
|
||||
* To be called by the consumer when it's no longer active.
|
||||
*/
|
||||
public void onConsumerInactive(TouchConsumer caller) {
|
||||
if (mConsumer == caller) {
|
||||
mConsumer = TouchConsumer.NO_OP;
|
||||
}
|
||||
}
|
||||
|
||||
public void dispose() {
|
||||
mDispatcher.dispose();
|
||||
mReceiver.dispose();
|
||||
}
|
||||
|
||||
public interface ConsumerFactory {
|
||||
|
||||
TouchConsumer newConsumer(@HitTarget int downHitTarget, boolean useSharedState);
|
||||
}
|
||||
}
|
|
@ -15,8 +15,6 @@
|
|||
*/
|
||||
package com.android.quickstep;
|
||||
|
||||
import static com.android.quickstep.WindowTransformSwipeHandler.STATES;
|
||||
|
||||
import android.util.Log;
|
||||
import android.util.SparseArray;
|
||||
|
||||
|
@ -29,11 +27,17 @@ import java.util.function.Consumer;
|
|||
public class MultiStateCallback {
|
||||
|
||||
private static final String TAG = "MultiStateCallback";
|
||||
private static final boolean DEBUG_STATES = false;
|
||||
public static final boolean DEBUG_STATES = false;
|
||||
|
||||
private final SparseArray<Runnable> mCallbacks = new SparseArray<>();
|
||||
private final SparseArray<Consumer<Boolean>> mStateChangeHandlers = new SparseArray<>();
|
||||
|
||||
private final String[] mStateNames;
|
||||
|
||||
public MultiStateCallback(String[] stateNames) {
|
||||
mStateNames = DEBUG_STATES ? stateNames : null;
|
||||
}
|
||||
|
||||
private int mState = 0;
|
||||
|
||||
/**
|
||||
|
@ -113,12 +117,12 @@ public class MultiStateCallback {
|
|||
int state = getState();
|
||||
StringJoiner currentStateStr = new StringJoiner(", ", "[", "]");
|
||||
String stateFlagStr = "Unknown-" + stateFlag;
|
||||
for (int i = 0; i < STATES.length; i++) {
|
||||
for (int i = 0; i < mStateNames.length; i++) {
|
||||
if ((state & (i << i)) != 0) {
|
||||
currentStateStr.add(STATES[i]);
|
||||
currentStateStr.add(mStateNames[i]);
|
||||
}
|
||||
if (stateFlag == (1 << i)) {
|
||||
stateFlagStr = STATES[i] + " (" + stateFlag + ")";
|
||||
stateFlagStr = mStateNames[i] + " (" + stateFlag + ")";
|
||||
}
|
||||
}
|
||||
Log.d(TAG, "[" + System.identityHashCode(this) + "] Adding " + stateFlagStr + " to "
|
||||
|
|
|
@ -24,6 +24,7 @@ import static android.view.MotionEvent.INVALID_POINTER_ID;
|
|||
|
||||
import static com.android.launcher3.util.RaceConditionTracker.ENTER;
|
||||
import static com.android.launcher3.util.RaceConditionTracker.EXIT;
|
||||
import static com.android.quickstep.TouchInteractionService.TOUCH_INTERACTION_LOG;
|
||||
import static com.android.systemui.shared.system.ActivityManagerWrapper.CLOSE_SYSTEM_WINDOWS_REASON_RECENTS;
|
||||
|
||||
import android.annotation.TargetApi;
|
||||
|
@ -35,7 +36,6 @@ import android.graphics.PointF;
|
|||
import android.graphics.Rect;
|
||||
import android.os.Build;
|
||||
import android.os.Bundle;
|
||||
import android.os.SystemClock;
|
||||
import android.view.Display;
|
||||
import android.view.MotionEvent;
|
||||
import android.view.Surface;
|
||||
|
@ -77,7 +77,6 @@ public class OtherActivityTouchConsumer extends ContextWrapper implements TouchC
|
|||
private final ActivityControlHelper mActivityControlHelper;
|
||||
private final OverviewCallbacks mOverviewCallbacks;
|
||||
private final TaskOverlayFactory mTaskOverlayFactory;
|
||||
private final TouchInteractionLog mTouchInteractionLog;
|
||||
private final InputConsumerController mInputConsumer;
|
||||
private final SwipeSharedState mSwipeSharedState;
|
||||
|
||||
|
@ -110,7 +109,6 @@ public class OtherActivityTouchConsumer extends ContextWrapper implements TouchC
|
|||
RecentsModel recentsModel, Intent homeIntent, ActivityControlHelper activityControl,
|
||||
boolean isDeferredDownTarget, OverviewCallbacks overviewCallbacks,
|
||||
TaskOverlayFactory taskOverlayFactory, InputConsumerController inputConsumer,
|
||||
TouchInteractionLog touchInteractionLog,
|
||||
Consumer<OtherActivityTouchConsumer> onCompleteCallback,
|
||||
SwipeSharedState swipeSharedState) {
|
||||
super(base);
|
||||
|
@ -127,8 +125,6 @@ public class OtherActivityTouchConsumer extends ContextWrapper implements TouchC
|
|||
mIsDeferredDownTarget = isDeferredDownTarget;
|
||||
mOverviewCallbacks = overviewCallbacks;
|
||||
mTaskOverlayFactory = taskOverlayFactory;
|
||||
mTouchInteractionLog = touchInteractionLog;
|
||||
mTouchInteractionLog.setTouchConsumer(this);
|
||||
mInputConsumer = inputConsumer;
|
||||
mSwipeSharedState = swipeSharedState;
|
||||
|
||||
|
@ -142,11 +138,6 @@ public class OtherActivityTouchConsumer extends ContextWrapper implements TouchC
|
|||
mPassedTouchSlop = mPassedDragSlop = mSwipeSharedState.getActiveListener() != null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onShowOverviewFromAltTab() {
|
||||
startTouchTrackingForWindowAnimation(SystemClock.uptimeMillis());
|
||||
}
|
||||
|
||||
@Override
|
||||
public void accept(MotionEvent ev) {
|
||||
if (mVelocityTracker == null) {
|
||||
|
@ -158,7 +149,6 @@ public class OtherActivityTouchConsumer extends ContextWrapper implements TouchC
|
|||
mMotionPauseDetector.clear();
|
||||
}
|
||||
|
||||
mTouchInteractionLog.addMotionEvent(ev);
|
||||
switch (ev.getActionMasked()) {
|
||||
case ACTION_DOWN: {
|
||||
RaceConditionTracker.onEvent(DOWN_EVT, ENTER);
|
||||
|
@ -213,7 +203,7 @@ public class OtherActivityTouchConsumer extends ContextWrapper implements TouchC
|
|||
mTouchSlop) {
|
||||
mPassedTouchSlop = true;
|
||||
|
||||
mTouchInteractionLog.startQuickStep();
|
||||
TOUCH_INTERACTION_LOG.startQuickStep();
|
||||
if (mIsDeferredDownTarget) {
|
||||
// Deferred gesture, start the animation and gesture tracking once
|
||||
// we pass the actual touch slop
|
||||
|
@ -284,12 +274,12 @@ public class OtherActivityTouchConsumer extends ContextWrapper implements TouchC
|
|||
}
|
||||
|
||||
private void startTouchTrackingForWindowAnimation(long touchTimeMs) {
|
||||
mTouchInteractionLog.startRecentsAnimation();
|
||||
TOUCH_INTERACTION_LOG.startRecentsAnimation();
|
||||
|
||||
RecentsAnimationListenerSet listenerSet = mSwipeSharedState.getActiveListener();
|
||||
final WindowTransformSwipeHandler handler = new WindowTransformSwipeHandler(
|
||||
mRunningTask, this, touchTimeMs, mActivityControlHelper,
|
||||
listenerSet != null, mInputConsumer, mTouchInteractionLog);
|
||||
listenerSet != null, mInputConsumer);
|
||||
|
||||
// Preload the plan
|
||||
mRecentsModel.getTasks(null);
|
||||
|
@ -393,38 +383,6 @@ public class OtherActivityTouchConsumer extends ContextWrapper implements TouchC
|
|||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onQuickScrubStart() {
|
||||
if (!mPassedDragSlop && mIsDeferredDownTarget && mInteractionHandler == null) {
|
||||
// If we deferred starting the window animation on touch down, then
|
||||
// start tracking now
|
||||
startTouchTrackingForWindowAnimation(SystemClock.uptimeMillis());
|
||||
mPassedDragSlop = true;
|
||||
}
|
||||
|
||||
mTouchInteractionLog.startQuickScrub();
|
||||
if (mInteractionHandler != null) {
|
||||
mInteractionHandler.onQuickScrubStart();
|
||||
}
|
||||
notifyGestureStarted();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onQuickScrubEnd() {
|
||||
mTouchInteractionLog.endQuickScrub("onQuickScrubEnd");
|
||||
if (mInteractionHandler != null) {
|
||||
mInteractionHandler.onQuickScrubEnd();
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onQuickScrubProgress(float progress) {
|
||||
mTouchInteractionLog.setQuickScrubProgress(progress);
|
||||
if (mInteractionHandler != null) {
|
||||
mInteractionHandler.onQuickScrubProgress(progress);
|
||||
}
|
||||
}
|
||||
|
||||
private float getDisplacement(MotionEvent ev) {
|
||||
float eventX = ev.getX();
|
||||
float eventY = ev.getY();
|
||||
|
|
|
@ -31,6 +31,7 @@ import com.android.launcher3.logging.UserEventDispatcher;
|
|||
import com.android.launcher3.userevent.nano.LauncherLogProto;
|
||||
import com.android.quickstep.ActivityControlHelper.ActivityInitListener;
|
||||
import com.android.quickstep.views.RecentsView;
|
||||
import com.android.quickstep.views.TaskView;
|
||||
import com.android.systemui.shared.system.ActivityManagerWrapper;
|
||||
import com.android.systemui.shared.system.LatencyTrackerCompat;
|
||||
import com.android.systemui.shared.system.RemoteAnimationTargetCompat;
|
||||
|
@ -71,6 +72,10 @@ public class OverviewCommandHelper {
|
|||
mMainThreadExecutor.execute(new ShowRecentsCommand());
|
||||
}
|
||||
|
||||
public void onOverviewHidden() {
|
||||
mMainThreadExecutor.execute(new HideRecentsCommand());
|
||||
}
|
||||
|
||||
public void onTip(int actionType, int viewType) {
|
||||
mMainThreadExecutor.execute(() ->
|
||||
UserEventDispatcher.newInstance(mContext).logActionTip(actionType, viewType));
|
||||
|
@ -80,10 +85,29 @@ public class OverviewCommandHelper {
|
|||
|
||||
@Override
|
||||
protected boolean handleCommand(long elapsedTime) {
|
||||
// TODO: Go to the next page if started from alt-tab.
|
||||
return mHelper.getVisibleRecentsView() != null;
|
||||
}
|
||||
}
|
||||
|
||||
private class HideRecentsCommand extends RecentsActivityCommand {
|
||||
|
||||
@Override
|
||||
protected boolean handleCommand(long elapsedTime) {
|
||||
RecentsView recents = (RecentsView) mHelper.getVisibleRecentsView();
|
||||
if (recents == null) {
|
||||
return false;
|
||||
}
|
||||
int currentPage = recents.getNextPage();
|
||||
if (currentPage >= 0 && currentPage < recents.getTaskViewCount()) {
|
||||
((TaskView) recents.getPageAt(currentPage)).launchTask(true);
|
||||
} else {
|
||||
recents.startHome();
|
||||
}
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
private class RecentsActivityCommand<T extends BaseDraggingActivity> implements Runnable {
|
||||
|
||||
protected final ActivityControlHelper<T> mHelper;
|
||||
|
|
|
@ -22,6 +22,7 @@ import static android.view.MotionEvent.ACTION_POINTER_DOWN;
|
|||
import static android.view.MotionEvent.ACTION_POINTER_INDEX_SHIFT;
|
||||
import static android.view.MotionEvent.ACTION_UP;
|
||||
|
||||
import static com.android.quickstep.TouchInteractionService.TOUCH_INTERACTION_LOG;
|
||||
import static com.android.systemui.shared.system.ActivityManagerWrapper.CLOSE_SYSTEM_WINDOWS_REASON_RECENTS;
|
||||
|
||||
import android.graphics.PointF;
|
||||
|
@ -30,7 +31,6 @@ import android.view.ViewConfiguration;
|
|||
|
||||
import com.android.launcher3.BaseDraggingActivity;
|
||||
import com.android.launcher3.views.BaseDragLayer;
|
||||
import com.android.quickstep.views.RecentsView;
|
||||
import com.android.systemui.shared.system.ActivityManagerWrapper;
|
||||
|
||||
/**
|
||||
|
@ -39,42 +39,22 @@ import com.android.systemui.shared.system.ActivityManagerWrapper;
|
|||
public class OverviewTouchConsumer<T extends BaseDraggingActivity>
|
||||
implements TouchConsumer {
|
||||
|
||||
private static final String TAG = "OverviewTouchConsumer";
|
||||
|
||||
private final ActivityControlHelper<T> mActivityHelper;
|
||||
private final T mActivity;
|
||||
private final BaseDragLayer mTarget;
|
||||
private final int[] mLocationOnScreen = new int[2];
|
||||
private final PointF mDownPos = new PointF();
|
||||
private final int mTouchSlop;
|
||||
private final QuickScrubController mQuickScrubController;
|
||||
private final TouchInteractionLog mTouchInteractionLog;
|
||||
|
||||
private final boolean mStartingInActivityBounds;
|
||||
|
||||
private boolean mTrackingStarted = false;
|
||||
private boolean mInvalidated = false;
|
||||
|
||||
private float mLastProgress = 0;
|
||||
private boolean mStartPending = false;
|
||||
private boolean mEndPending = false;
|
||||
private boolean mWaitForWindowAvailable;
|
||||
|
||||
OverviewTouchConsumer(ActivityControlHelper<T> activityHelper, T activity,
|
||||
boolean startingInActivityBounds, TouchInteractionLog touchInteractionLog,
|
||||
boolean waitForWindowAvailable) {
|
||||
mActivityHelper = activityHelper;
|
||||
OverviewTouchConsumer(T activity, boolean startingInActivityBounds) {
|
||||
mActivity = activity;
|
||||
mTarget = activity.getDragLayer();
|
||||
mTouchSlop = ViewConfiguration.get(mActivity).getScaledTouchSlop();
|
||||
mStartingInActivityBounds = startingInActivityBounds;
|
||||
|
||||
mQuickScrubController = mActivity.<RecentsView>getOverviewPanel()
|
||||
.getQuickScrubController();
|
||||
mTouchInteractionLog = touchInteractionLog;
|
||||
mTouchInteractionLog.setTouchConsumer(this);
|
||||
|
||||
mWaitForWindowAvailable = waitForWindowAvailable;
|
||||
}
|
||||
|
||||
@Override
|
||||
|
@ -82,7 +62,6 @@ public class OverviewTouchConsumer<T extends BaseDraggingActivity>
|
|||
if (mInvalidated) {
|
||||
return;
|
||||
}
|
||||
mTouchInteractionLog.addMotionEvent(ev);
|
||||
int action = ev.getActionMasked();
|
||||
if (action == ACTION_DOWN) {
|
||||
if (mStartingInActivityBounds) {
|
||||
|
@ -145,7 +124,7 @@ public class OverviewTouchConsumer<T extends BaseDraggingActivity>
|
|||
OverviewCallbacks.get(mActivity).closeAllWindows();
|
||||
ActivityManagerWrapper.getInstance()
|
||||
.closeSystemWindows(CLOSE_SYSTEM_WINDOWS_REASON_RECENTS);
|
||||
mTouchInteractionLog.startQuickStep();
|
||||
TOUCH_INTERACTION_LOG.startQuickStep();
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -165,83 +144,12 @@ public class OverviewTouchConsumer<T extends BaseDraggingActivity>
|
|||
ev.setEdgeFlags(flags);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onQuickScrubStart() {
|
||||
if (mInvalidated) {
|
||||
return;
|
||||
}
|
||||
mTouchInteractionLog.startQuickScrub();
|
||||
if (!mQuickScrubController.prepareQuickScrub(TAG)) {
|
||||
mInvalidated = true;
|
||||
mTouchInteractionLog.endQuickScrub("onQuickScrubStart");
|
||||
return;
|
||||
}
|
||||
OverviewCallbacks.get(mActivity).closeAllWindows();
|
||||
ActivityManagerWrapper.getInstance()
|
||||
.closeSystemWindows(CLOSE_SYSTEM_WINDOWS_REASON_RECENTS);
|
||||
|
||||
mStartPending = true;
|
||||
Runnable action = () -> {
|
||||
if (!mQuickScrubController.prepareQuickScrub(TAG)) {
|
||||
mInvalidated = true;
|
||||
mTouchInteractionLog.endQuickScrub("onQuickScrubStart");
|
||||
return;
|
||||
}
|
||||
mActivityHelper.onQuickInteractionStart(mActivity, null, true,
|
||||
mTouchInteractionLog);
|
||||
mQuickScrubController.onQuickScrubProgress(mLastProgress);
|
||||
mStartPending = false;
|
||||
|
||||
if (mEndPending) {
|
||||
mQuickScrubController.onQuickScrubEnd();
|
||||
mEndPending = false;
|
||||
}
|
||||
};
|
||||
|
||||
if (mWaitForWindowAvailable) {
|
||||
mActivityHelper.executeOnWindowAvailable(mActivity, action);
|
||||
} else {
|
||||
action.run();
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onQuickScrubEnd() {
|
||||
mTouchInteractionLog.endQuickScrub("onQuickScrubEnd");
|
||||
if (mInvalidated) {
|
||||
return;
|
||||
}
|
||||
if (mStartPending) {
|
||||
mEndPending = true;
|
||||
} else {
|
||||
mQuickScrubController.onQuickScrubEnd();
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onQuickScrubProgress(float progress) {
|
||||
mTouchInteractionLog.setQuickScrubProgress(progress);
|
||||
mLastProgress = progress;
|
||||
if (mInvalidated || mStartPending) {
|
||||
return;
|
||||
}
|
||||
mQuickScrubController.onQuickScrubProgress(progress);
|
||||
}
|
||||
|
||||
public static TouchConsumer newInstance(ActivityControlHelper activityHelper,
|
||||
boolean startingInActivityBounds, TouchInteractionLog touchInteractionLog) {
|
||||
return newInstance(activityHelper, startingInActivityBounds, touchInteractionLog,
|
||||
true /* waitForWindowAvailable */);
|
||||
}
|
||||
|
||||
public static TouchConsumer newInstance(ActivityControlHelper activityHelper,
|
||||
boolean startingInActivityBounds, TouchInteractionLog touchInteractionLog,
|
||||
boolean waitForWindowAvailable) {
|
||||
boolean startingInActivityBounds) {
|
||||
BaseDraggingActivity activity = activityHelper.getCreatedActivity();
|
||||
if (activity == null) {
|
||||
return TouchConsumer.NO_OP;
|
||||
}
|
||||
return new OverviewTouchConsumer(activityHelper, activity, startingInActivityBounds,
|
||||
touchInteractionLog, waitForWindowAvailable);
|
||||
return new OverviewTouchConsumer(activity, startingInActivityBounds);
|
||||
}
|
||||
}
|
|
@ -1,432 +0,0 @@
|
|||
/*
|
||||
* Copyright (C) 2018 The Android Open Source Project
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package com.android.quickstep;
|
||||
|
||||
import static com.android.launcher3.Utilities.SINGLE_FRAME_MS;
|
||||
import static com.android.launcher3.anim.Interpolators.ACCEL;
|
||||
import static com.android.launcher3.anim.Interpolators.DEACCEL_3;
|
||||
import static com.android.launcher3.anim.Interpolators.FAST_OUT_SLOW_IN;
|
||||
import static com.android.launcher3.anim.Interpolators.LINEAR;
|
||||
import static com.android.launcher3.config.FeatureFlags.ENABLE_TASK_STABILIZER;
|
||||
import static com.android.launcher3.config.FeatureFlags.ENABLE_QUICKSTEP_LIVE_TILE;
|
||||
|
||||
import android.animation.Animator;
|
||||
import android.animation.AnimatorListenerAdapter;
|
||||
import android.animation.ObjectAnimator;
|
||||
import android.annotation.TargetApi;
|
||||
import android.os.Build;
|
||||
import android.util.FloatProperty;
|
||||
import android.util.Log;
|
||||
import android.view.HapticFeedbackConstants;
|
||||
import android.view.animation.Interpolator;
|
||||
|
||||
import com.android.launcher3.Alarm;
|
||||
import com.android.launcher3.BaseActivity;
|
||||
import com.android.launcher3.OnAlarmListener;
|
||||
import com.android.launcher3.Utilities;
|
||||
import com.android.launcher3.userevent.nano.LauncherLogProto;
|
||||
import com.android.launcher3.userevent.nano.LauncherLogProto.Action.Touch;
|
||||
import com.android.quickstep.views.RecentsView;
|
||||
import com.android.quickstep.views.TaskView;
|
||||
|
||||
/**
|
||||
* Responds to quick scrub callbacks to page through and launch recent tasks.
|
||||
*
|
||||
* The behavior is to evenly divide the progress into sections, each of which scrolls one page.
|
||||
* The first and last section set an alarm to auto-advance backwards or forwards, respectively.
|
||||
*/
|
||||
@TargetApi(Build.VERSION_CODES.P)
|
||||
public class QuickScrubController implements OnAlarmListener {
|
||||
|
||||
public static final int QUICK_SWITCH_FROM_APP_START_DURATION = 0;
|
||||
public static final int QUICK_SCRUB_FROM_APP_START_DURATION = 240;
|
||||
public static final int QUICK_SCRUB_FROM_HOME_START_DURATION = 200;
|
||||
// We want the translation y to finish faster than the rest of the animation.
|
||||
public static final float QUICK_SCRUB_TRANSLATION_Y_FACTOR = 5f / 6;
|
||||
public static final Interpolator QUICK_SCRUB_START_INTERPOLATOR = FAST_OUT_SLOW_IN;
|
||||
|
||||
/**
|
||||
* Snap to a new page when crossing these thresholds. The first and last auto-advance.
|
||||
*/
|
||||
private static final float[] QUICK_SCRUB_THRESHOLDS = new float[] {
|
||||
0.05f, 0.20f, 0.35f, 0.50f, 0.65f, 0.80f, 0.95f
|
||||
};
|
||||
|
||||
private static final FloatProperty<QuickScrubController> PROGRESS
|
||||
= new FloatProperty<QuickScrubController>("progress") {
|
||||
@Override
|
||||
public void setValue(QuickScrubController quickScrubController, float progress) {
|
||||
quickScrubController.onQuickScrubProgress(progress);
|
||||
}
|
||||
|
||||
@Override
|
||||
public Float get(QuickScrubController quickScrubController) {
|
||||
return quickScrubController.mEndProgress;
|
||||
}
|
||||
};
|
||||
|
||||
private static final String TAG = "QuickScrubController";
|
||||
private static final boolean ENABLE_AUTO_ADVANCE = true;
|
||||
private static final long AUTO_ADVANCE_DELAY = 500;
|
||||
private static final int QUICKSCRUB_SNAP_DURATION_PER_PAGE = 325;
|
||||
private static final int QUICKSCRUB_END_SNAP_DURATION_PER_PAGE = 60;
|
||||
|
||||
private final Alarm mAutoAdvanceAlarm;
|
||||
private final RecentsView mRecentsView;
|
||||
private final BaseActivity mActivity;
|
||||
|
||||
private boolean mInQuickScrub;
|
||||
private boolean mWaitingForTaskLaunch;
|
||||
private int mQuickScrubSection;
|
||||
private boolean mStartedFromHome;
|
||||
private boolean mFinishedTransitionToQuickScrub;
|
||||
private int mLaunchingTaskId;
|
||||
private Runnable mOnFinishedTransitionToQuickScrubRunnable;
|
||||
private ActivityControlHelper mActivityControlHelper;
|
||||
private TouchInteractionLog mTouchInteractionLog;
|
||||
|
||||
private boolean mIsQuickSwitch;
|
||||
private float mStartProgress;
|
||||
private float mEndProgress;
|
||||
private float mPrevProgressDelta;
|
||||
private float mPrevPrevProgressDelta;
|
||||
private boolean mShouldSwitchToNext;
|
||||
|
||||
public QuickScrubController(BaseActivity activity, RecentsView recentsView) {
|
||||
mActivity = activity;
|
||||
mRecentsView = recentsView;
|
||||
if (ENABLE_AUTO_ADVANCE) {
|
||||
mAutoAdvanceAlarm = new Alarm();
|
||||
mAutoAdvanceAlarm.setOnAlarmListener(this);
|
||||
}
|
||||
}
|
||||
|
||||
public void onQuickScrubStart(boolean startingFromHome, ActivityControlHelper controlHelper,
|
||||
TouchInteractionLog touchInteractionLog) {
|
||||
prepareQuickScrub(TAG);
|
||||
mInQuickScrub = true;
|
||||
mStartedFromHome = startingFromHome;
|
||||
mQuickScrubSection = 0;
|
||||
mFinishedTransitionToQuickScrub = false;
|
||||
mActivityControlHelper = controlHelper;
|
||||
mTouchInteractionLog = touchInteractionLog;
|
||||
|
||||
if (ENABLE_QUICKSTEP_LIVE_TILE.get()) {
|
||||
if (mRecentsView.getRunningTaskView() != null) {
|
||||
mRecentsView.getRunningTaskView().setShowScreenshot(false);
|
||||
}
|
||||
}
|
||||
|
||||
if (mIsQuickSwitch) {
|
||||
mShouldSwitchToNext = true;
|
||||
mPrevProgressDelta = 0;
|
||||
TaskView runningTaskView = mRecentsView.getRunningTaskView();
|
||||
TaskView nextTaskView = mRecentsView.getNextTaskView();
|
||||
if (runningTaskView != null) {
|
||||
runningTaskView.setFullscreenProgress(1);
|
||||
}
|
||||
if (nextTaskView != null) {
|
||||
nextTaskView.setFullscreenProgress(1);
|
||||
}
|
||||
}
|
||||
|
||||
snapToNextTaskIfAvailable();
|
||||
mActivity.getUserEventDispatcher().resetActionDurationMillis();
|
||||
}
|
||||
|
||||
public void onQuickScrubEnd() {
|
||||
mInQuickScrub = false;
|
||||
|
||||
Runnable launchTaskRunnable = () -> {
|
||||
int page = mRecentsView.getPageNearestToCenterOfScreen();
|
||||
TaskView taskView = mRecentsView.getTaskViewAt(page);
|
||||
if (taskView != null) {
|
||||
mWaitingForTaskLaunch = true;
|
||||
mTouchInteractionLog.launchTaskStart();
|
||||
mLaunchingTaskId = taskView.getTask().key.id;
|
||||
taskView.launchTask(true, (result) -> {
|
||||
mTouchInteractionLog.launchTaskEnd(result);
|
||||
if (!result) {
|
||||
taskView.notifyTaskLaunchFailed(TAG);
|
||||
breakOutOfQuickScrub();
|
||||
} else {
|
||||
mActivity.getUserEventDispatcher().logTaskLaunchOrDismiss(Touch.DRAGDROP,
|
||||
LauncherLogProto.Action.Direction.NONE, page,
|
||||
TaskUtils.getLaunchComponentKeyForTask(taskView.getTask().key));
|
||||
}
|
||||
mWaitingForTaskLaunch = false;
|
||||
if (mIsQuickSwitch) {
|
||||
mIsQuickSwitch = false;
|
||||
TaskView runningTaskView = mRecentsView.getRunningTaskView();
|
||||
TaskView nextTaskView = mRecentsView.getNextTaskView();
|
||||
if (runningTaskView != null) {
|
||||
runningTaskView.setFullscreenProgress(0);
|
||||
}
|
||||
if (nextTaskView != null) {
|
||||
nextTaskView.setFullscreenProgress(0);
|
||||
}
|
||||
}
|
||||
|
||||
}, taskView.getHandler());
|
||||
} else {
|
||||
breakOutOfQuickScrub();
|
||||
}
|
||||
mActivityControlHelper = null;
|
||||
};
|
||||
|
||||
if (mIsQuickSwitch) {
|
||||
float progressVelocity = mPrevPrevProgressDelta / SINGLE_FRAME_MS;
|
||||
// Move to the next frame immediately, then start the animation from the
|
||||
// following frame since it starts a frame later.
|
||||
float singleFrameProgress = progressVelocity * SINGLE_FRAME_MS;
|
||||
float fromProgress = mEndProgress + singleFrameProgress;
|
||||
onQuickScrubProgress(fromProgress);
|
||||
fromProgress += singleFrameProgress;
|
||||
float toProgress = mShouldSwitchToNext ? 1 : 0;
|
||||
int duration = (int) Math.abs((toProgress - fromProgress) / progressVelocity);
|
||||
duration = Utilities.boundToRange(duration, 80, 300);
|
||||
Animator anim = ObjectAnimator.ofFloat(this, PROGRESS, fromProgress, toProgress);
|
||||
anim.addListener(new AnimatorListenerAdapter() {
|
||||
@Override
|
||||
public void onAnimationEnd(Animator animation) {
|
||||
launchTaskRunnable.run();
|
||||
}
|
||||
});
|
||||
anim.setDuration(duration).start();
|
||||
return;
|
||||
}
|
||||
|
||||
if (ENABLE_AUTO_ADVANCE) {
|
||||
mAutoAdvanceAlarm.cancelAlarm();
|
||||
}
|
||||
int page = mRecentsView.getNextPage();
|
||||
int snapDuration = Math.abs(page - mRecentsView.getPageNearestToCenterOfScreen())
|
||||
* QUICKSCRUB_END_SNAP_DURATION_PER_PAGE;
|
||||
if (mRecentsView.getChildCount() > 0 && mRecentsView.snapToPage(page, snapDuration)) {
|
||||
// Settle on the page then launch it
|
||||
mRecentsView.setNextPageSwitchRunnable(launchTaskRunnable);
|
||||
} else {
|
||||
// No page move needed, just launch it
|
||||
if (mFinishedTransitionToQuickScrub) {
|
||||
launchTaskRunnable.run();
|
||||
} else {
|
||||
mOnFinishedTransitionToQuickScrubRunnable = launchTaskRunnable;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public void cancelActiveQuickscrub() {
|
||||
if (!mInQuickScrub) {
|
||||
return;
|
||||
}
|
||||
Log.d(TAG, "Quickscrub was active, cancelling");
|
||||
mInQuickScrub = false;
|
||||
mActivityControlHelper = null;
|
||||
mOnFinishedTransitionToQuickScrubRunnable = null;
|
||||
mRecentsView.setNextPageSwitchRunnable(null);
|
||||
mLaunchingTaskId = 0;
|
||||
}
|
||||
|
||||
public boolean prepareQuickScrub(String tag) {
|
||||
return prepareQuickScrub(tag, mIsQuickSwitch);
|
||||
}
|
||||
|
||||
/**
|
||||
* Initializes the UI for quick scrub, returns true if success.
|
||||
*/
|
||||
public boolean prepareQuickScrub(String tag, boolean isQuickSwitch) {
|
||||
if (mWaitingForTaskLaunch || mInQuickScrub) {
|
||||
Log.d(tag, "Waiting for last scrub to finish, will skip this interaction");
|
||||
return false;
|
||||
}
|
||||
mOnFinishedTransitionToQuickScrubRunnable = null;
|
||||
mRecentsView.setNextPageSwitchRunnable(null);
|
||||
mIsQuickSwitch = isQuickSwitch;
|
||||
return true;
|
||||
}
|
||||
|
||||
public boolean isQuickSwitch() {
|
||||
return mIsQuickSwitch;
|
||||
}
|
||||
|
||||
public boolean isWaitingForTaskLaunch() {
|
||||
return mWaitingForTaskLaunch;
|
||||
}
|
||||
|
||||
public boolean hasFinishedTransitionToQuickScrub() {
|
||||
return mFinishedTransitionToQuickScrub;
|
||||
}
|
||||
|
||||
/**
|
||||
* Attempts to go to normal overview or back to home, so UI doesn't prevent user interaction.
|
||||
*/
|
||||
private void breakOutOfQuickScrub() {
|
||||
if (mRecentsView.getChildCount() == 0 || mActivityControlHelper == null
|
||||
|| !mActivityControlHelper.switchToRecentsIfVisible(false)) {
|
||||
mActivity.onBackPressed();
|
||||
}
|
||||
}
|
||||
|
||||
public void onQuickScrubProgress(float progress) {
|
||||
if (mIsQuickSwitch) {
|
||||
TaskView currentPage = mRecentsView.getRunningTaskView();
|
||||
TaskView nextPage = mRecentsView.getNextTaskView();
|
||||
if (currentPage == null || nextPage == null) {
|
||||
return;
|
||||
}
|
||||
if (!mFinishedTransitionToQuickScrub || mStartProgress <= 0) {
|
||||
mStartProgress = mEndProgress = progress;
|
||||
} else {
|
||||
float progressDelta = progress - mEndProgress;
|
||||
mEndProgress = progress;
|
||||
progress = Utilities.boundToRange(progress, mStartProgress, 1);
|
||||
progress = Utilities.mapToRange(progress, mStartProgress, 1, 0, 1, LINEAR);
|
||||
if (mInQuickScrub) {
|
||||
mShouldSwitchToNext = mPrevProgressDelta > 0.007f || progressDelta > 0.007f
|
||||
|| progress >= 0.5f;
|
||||
}
|
||||
mPrevPrevProgressDelta = mPrevProgressDelta;
|
||||
mPrevProgressDelta = progressDelta;
|
||||
int startScroll = mRecentsView.getScrollForPage(
|
||||
mRecentsView.indexOfChild(currentPage));
|
||||
int scrollDiff = mRecentsView.getScrollForPage(mRecentsView.indexOfChild(nextPage))
|
||||
- startScroll;
|
||||
|
||||
int linearScrollDiff = (int) (progress * scrollDiff);
|
||||
currentPage.setZoomScale(1 - DEACCEL_3.getInterpolation(progress)
|
||||
* TaskView.EDGE_SCALE_DOWN_FACTOR);
|
||||
if (!ENABLE_TASK_STABILIZER.get()) {
|
||||
float accelScrollDiff = ACCEL.getInterpolation(progress) * scrollDiff;
|
||||
currentPage.setTranslationX(linearScrollDiff + accelScrollDiff);
|
||||
}
|
||||
nextPage.setTranslationZ(1);
|
||||
nextPage.setTranslationY(currentPage.getTranslationY());
|
||||
mRecentsView.setScrollX(startScroll + linearScrollDiff);
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
int quickScrubSection = 0;
|
||||
for (float threshold : QUICK_SCRUB_THRESHOLDS) {
|
||||
if (progress < threshold) {
|
||||
break;
|
||||
}
|
||||
quickScrubSection++;
|
||||
}
|
||||
if (quickScrubSection != mQuickScrubSection) {
|
||||
boolean cameFromAutoAdvance = mQuickScrubSection == QUICK_SCRUB_THRESHOLDS.length
|
||||
|| mQuickScrubSection == 0;
|
||||
int pageToGoTo = mRecentsView.getNextPage() + quickScrubSection - mQuickScrubSection;
|
||||
if (mFinishedTransitionToQuickScrub && !cameFromAutoAdvance) {
|
||||
goToPageWithHaptic(pageToGoTo);
|
||||
}
|
||||
if (ENABLE_AUTO_ADVANCE) {
|
||||
if (quickScrubSection == QUICK_SCRUB_THRESHOLDS.length || quickScrubSection == 0) {
|
||||
mAutoAdvanceAlarm.setAlarm(AUTO_ADVANCE_DELAY);
|
||||
} else {
|
||||
mAutoAdvanceAlarm.cancelAlarm();
|
||||
}
|
||||
}
|
||||
mQuickScrubSection = quickScrubSection;
|
||||
}
|
||||
}
|
||||
|
||||
public void onFinishedTransitionToQuickScrub() {
|
||||
mFinishedTransitionToQuickScrub = true;
|
||||
Runnable action = mOnFinishedTransitionToQuickScrubRunnable;
|
||||
// Clear the runnable before executing it, to prevent potential recursion.
|
||||
mOnFinishedTransitionToQuickScrubRunnable = null;
|
||||
if (action != null) {
|
||||
action.run();
|
||||
}
|
||||
mRecentsView.setEnableDrawingLiveTile(true);
|
||||
}
|
||||
|
||||
public void onTaskRemoved(int taskId) {
|
||||
if (mLaunchingTaskId == taskId) {
|
||||
// The task has been removed mid-launch, break out of quickscrub and return the user
|
||||
// to where they were before (and notify the launch failed)
|
||||
TaskView taskView = mRecentsView.getTaskView(taskId);
|
||||
if (taskView != null) {
|
||||
taskView.notifyTaskLaunchFailed(TAG);
|
||||
}
|
||||
breakOutOfQuickScrub();
|
||||
}
|
||||
}
|
||||
|
||||
public void snapToNextTaskIfAvailable() {
|
||||
if (mInQuickScrub && mRecentsView.getChildCount() > 0) {
|
||||
int duration = mIsQuickSwitch
|
||||
? QUICK_SWITCH_FROM_APP_START_DURATION
|
||||
: mStartedFromHome
|
||||
? QUICK_SCRUB_FROM_HOME_START_DURATION
|
||||
: QUICK_SCRUB_FROM_APP_START_DURATION;
|
||||
final int pageToGoTo;
|
||||
if (mStartedFromHome) {
|
||||
pageToGoTo = 0;
|
||||
} else if (mIsQuickSwitch) {
|
||||
TaskView tv = mRecentsView.getRunningTaskView();
|
||||
pageToGoTo = tv != null ? mRecentsView.indexOfChild(tv)
|
||||
: mRecentsView.getNextPage();
|
||||
} else {
|
||||
pageToGoTo = mRecentsView.getNextPage() + 1;
|
||||
}
|
||||
goToPageWithHaptic(pageToGoTo, duration, true /* forceHaptic */,
|
||||
QUICK_SCRUB_START_INTERPOLATOR);
|
||||
}
|
||||
}
|
||||
|
||||
private void goToPageWithHaptic(int pageToGoTo) {
|
||||
goToPageWithHaptic(pageToGoTo, -1 /* overrideDuration */, false /* forceHaptic */, null);
|
||||
}
|
||||
|
||||
private void goToPageWithHaptic(int pageToGoTo, int overrideDuration, boolean forceHaptic,
|
||||
Interpolator interpolator) {
|
||||
pageToGoTo = Utilities.boundToRange(pageToGoTo, 0, mRecentsView.getTaskViewCount() - 1);
|
||||
boolean snappingToPage = pageToGoTo != mRecentsView.getNextPage();
|
||||
if (snappingToPage) {
|
||||
int duration = overrideDuration > -1 ? overrideDuration
|
||||
: Math.abs(pageToGoTo - mRecentsView.getNextPage())
|
||||
* QUICKSCRUB_SNAP_DURATION_PER_PAGE;
|
||||
mRecentsView.snapToPage(pageToGoTo, duration, interpolator);
|
||||
}
|
||||
if (snappingToPage || forceHaptic) {
|
||||
mRecentsView.performHapticFeedback(HapticFeedbackConstants.VIRTUAL_KEY,
|
||||
HapticFeedbackConstants.FLAG_IGNORE_VIEW_SETTING);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onAlarm(Alarm alarm) {
|
||||
int currPage = mRecentsView.getNextPage();
|
||||
boolean recentsVisible = mActivityControlHelper != null
|
||||
&& mActivityControlHelper.getVisibleRecentsView() != null;
|
||||
if (!recentsVisible) {
|
||||
Log.w(TAG, "Failed to auto advance; recents not visible");
|
||||
return;
|
||||
}
|
||||
if (mQuickScrubSection == QUICK_SCRUB_THRESHOLDS.length
|
||||
&& currPage < mRecentsView.getTaskViewCount() - 1) {
|
||||
goToPageWithHaptic(currPage + 1);
|
||||
} else if (mQuickScrubSection == 0 && currPage > 0) {
|
||||
goToPageWithHaptic(currPage - 1);
|
||||
}
|
||||
if (ENABLE_AUTO_ADVANCE) {
|
||||
mAutoAdvanceAlarm.setAlarm(AUTO_ADVANCE_DELAY);
|
||||
}
|
||||
}
|
||||
}
|
|
@ -19,10 +19,6 @@ import android.annotation.TargetApi;
|
|||
import android.os.Build;
|
||||
import android.view.MotionEvent;
|
||||
|
||||
import androidx.annotation.IntDef;
|
||||
|
||||
import java.lang.annotation.Retention;
|
||||
import java.lang.annotation.RetentionPolicy;
|
||||
import java.util.function.Consumer;
|
||||
|
||||
@TargetApi(Build.VERSION_CODES.O)
|
||||
|
@ -31,23 +27,6 @@ public interface TouchConsumer extends Consumer<MotionEvent> {
|
|||
|
||||
TouchConsumer NO_OP = (ev) -> {};
|
||||
|
||||
@IntDef(flag = true, value = {
|
||||
INTERACTION_NORMAL,
|
||||
INTERACTION_QUICK_SCRUB
|
||||
})
|
||||
@Retention(RetentionPolicy.SOURCE)
|
||||
@interface InteractionType {}
|
||||
int INTERACTION_NORMAL = 0;
|
||||
int INTERACTION_QUICK_SCRUB = 1;
|
||||
|
||||
default void onQuickScrubStart() { }
|
||||
|
||||
default void onQuickScrubEnd() { }
|
||||
|
||||
default void onQuickScrubProgress(float progress) { }
|
||||
|
||||
default void onShowOverviewFromAltTab() {}
|
||||
|
||||
default boolean isActive() {
|
||||
return false;
|
||||
}
|
||||
|
|
|
@ -23,7 +23,7 @@ import java.util.Calendar;
|
|||
import java.util.LinkedList;
|
||||
|
||||
/**
|
||||
* Keeps track of debugging logs for a particular quickstep/scrub gesture.
|
||||
* Keeps track of debugging logs for a particular quickstep gesture.
|
||||
*/
|
||||
public class TouchInteractionLog {
|
||||
|
||||
|
@ -54,18 +54,6 @@ public class TouchInteractionLog {
|
|||
getCurrentLog().add("qstStart");
|
||||
}
|
||||
|
||||
public void startQuickScrub() {
|
||||
getCurrentLog().add("qsStart");
|
||||
}
|
||||
|
||||
public void setQuickScrubProgress(float progress) {
|
||||
getCurrentLog().add("qsP=" + progress);
|
||||
}
|
||||
|
||||
public void endQuickScrub(String reason) {
|
||||
getCurrentLog().add("qsEnd=" + reason);
|
||||
}
|
||||
|
||||
public void startRecentsAnimation() {
|
||||
getCurrentLog().add("raStart");
|
||||
}
|
||||
|
@ -82,14 +70,6 @@ public class TouchInteractionLog {
|
|||
getCurrentLog().add("raFinish=" + toHome);
|
||||
}
|
||||
|
||||
public void launchTaskStart() {
|
||||
getCurrentLog().add("launchStart");
|
||||
}
|
||||
|
||||
public void launchTaskEnd(boolean result) {
|
||||
getCurrentLog().add("launchEnd=" + result);
|
||||
}
|
||||
|
||||
public void dump(PrintWriter pw) {
|
||||
pw.println("TouchInteractionLog {");
|
||||
for (ArrayList<String> gesture : mGestureLogs) {
|
||||
|
|
|
@ -15,12 +15,9 @@
|
|||
*/
|
||||
package com.android.quickstep;
|
||||
|
||||
import static android.view.MotionEvent.ACTION_CANCEL;
|
||||
import static android.view.MotionEvent.ACTION_DOWN;
|
||||
import static android.view.MotionEvent.ACTION_UP;
|
||||
|
||||
import static com.android.launcher3.config.FeatureFlags.ENABLE_QUICKSTEP_LIVE_TILE;
|
||||
import static com.android.systemui.shared.system.NavigationBarCompat.HIT_TARGET_NONE;
|
||||
import static com.android.systemui.shared.system.QuickStepContract.KEY_EXTRA_INPUT_CHANNEL;
|
||||
import static com.android.systemui.shared.system.QuickStepContract.KEY_EXTRA_SYSUI_PROXY;
|
||||
|
||||
|
@ -34,20 +31,19 @@ import android.os.Bundle;
|
|||
import android.os.IBinder;
|
||||
import android.os.Looper;
|
||||
import android.util.Log;
|
||||
import android.util.SparseArray;
|
||||
import android.util.Pair;
|
||||
import android.view.Choreographer;
|
||||
import android.view.InputEvent;
|
||||
import android.view.MotionEvent;
|
||||
|
||||
import com.android.launcher3.MainThreadExecutor;
|
||||
import com.android.launcher3.util.TraceHelper;
|
||||
import com.android.systemui.shared.recents.IOverviewProxy;
|
||||
import com.android.systemui.shared.recents.ISystemUiProxy;
|
||||
import com.android.systemui.shared.system.ActivityManagerWrapper;
|
||||
import com.android.systemui.shared.system.InputChannelCompat;
|
||||
import com.android.systemui.shared.system.InputChannelCompat.InputEventDispatcher;
|
||||
import com.android.systemui.shared.system.InputChannelCompat.InputEventReceiver;
|
||||
import com.android.systemui.shared.system.InputConsumerController;
|
||||
import com.android.systemui.shared.system.NavigationBarCompat.HitTarget;
|
||||
|
||||
import java.io.FileDescriptor;
|
||||
import java.io.PrintWriter;
|
||||
|
@ -59,15 +55,7 @@ import java.io.PrintWriter;
|
|||
public class TouchInteractionService extends Service {
|
||||
|
||||
public static final MainThreadExecutor MAIN_THREAD_EXECUTOR = new MainThreadExecutor();
|
||||
|
||||
private static final SparseArray<String> sMotionEventNames;
|
||||
|
||||
static {
|
||||
sMotionEventNames = new SparseArray<>(3);
|
||||
sMotionEventNames.put(ACTION_DOWN, "ACTION_DOWN");
|
||||
sMotionEventNames.put(ACTION_UP, "ACTION_UP");
|
||||
sMotionEventNames.put(ACTION_CANCEL, "ACTION_CANCEL");
|
||||
}
|
||||
public static final TouchInteractionLog TOUCH_INTERACTION_LOG = new TouchInteractionLog();
|
||||
|
||||
public static final int EDGE_NAV_BAR = 1 << 8;
|
||||
|
||||
|
@ -85,73 +73,12 @@ public class TouchInteractionService extends Service {
|
|||
mRecentsModel.setSystemUiProxy(mISystemUiProxy);
|
||||
mOverviewInteractionState.setSystemUiProxy(mISystemUiProxy);
|
||||
|
||||
if (mInputEventReceiver != null) {
|
||||
mInputEventReceiver.dispose();
|
||||
}
|
||||
disposeEventHandlers();
|
||||
mInputEventReceiver = InputChannelCompat.fromBundle(bundle, KEY_EXTRA_INPUT_CHANNEL,
|
||||
Looper.getMainLooper(), mMainChoreographer,
|
||||
TouchInteractionService.this::onInputEvent);
|
||||
}
|
||||
|
||||
public void onPreMotionEvent(@HitTarget int downHitTarget) {
|
||||
// If ev are using the new dispatching system, skip the old logic
|
||||
if (mInputEventReceiver != null) {
|
||||
return;
|
||||
}
|
||||
mTouchInteractionLog.prepareForNewGesture();
|
||||
|
||||
TraceHelper.beginSection("SysUiBinder");
|
||||
mEventQueue.onNewGesture(downHitTarget);
|
||||
TraceHelper.partitionSection("SysUiBinder", "Down target " + downHitTarget);
|
||||
}
|
||||
|
||||
public void onMotionEvent(MotionEvent ev) {
|
||||
// If ev are using the new dispatching system, skip the old logic
|
||||
if (mInputEventReceiver != null) {
|
||||
ev.recycle();
|
||||
return;
|
||||
}
|
||||
mEventQueue.queue(ev);
|
||||
|
||||
int action = ev.getActionMasked();
|
||||
String name = sMotionEventNames.get(action);
|
||||
if (name != null){
|
||||
TraceHelper.partitionSection("SysUiBinder", name);
|
||||
}
|
||||
}
|
||||
|
||||
public void onBind(ISystemUiProxy iSystemUiProxy) {
|
||||
mISystemUiProxy = iSystemUiProxy;
|
||||
mRecentsModel.setSystemUiProxy(mISystemUiProxy);
|
||||
mOverviewInteractionState.setSystemUiProxy(mISystemUiProxy);
|
||||
}
|
||||
|
||||
public void onQuickScrubStart() {
|
||||
// If ev are using the new dispatching system, skip the old logic
|
||||
if (mInputEventReceiver != null) {
|
||||
return;
|
||||
}
|
||||
mEventQueue.onQuickScrubStart();
|
||||
TraceHelper.partitionSection("SysUiBinder", "onQuickScrubStart");
|
||||
}
|
||||
|
||||
public void onQuickScrubProgress(float progress) {
|
||||
// If ev are using the new dispatching system, skip the old logic
|
||||
if (mInputEventReceiver != null) {
|
||||
return;
|
||||
}
|
||||
mEventQueue.onQuickScrubProgress(progress);
|
||||
}
|
||||
|
||||
public void onQuickScrubEnd() {
|
||||
// If ev are using the new dispatching system, skip the old logic
|
||||
if (mInputEventReceiver != null) {
|
||||
return;
|
||||
}
|
||||
mEventQueue.onQuickScrubEnd();
|
||||
TraceHelper.endSection("SysUiBinder", "onQuickScrubEnd");
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onOverviewToggle() {
|
||||
mOverviewCommandHelper.onOverviewToggle();
|
||||
|
@ -159,37 +86,55 @@ public class TouchInteractionService extends Service {
|
|||
|
||||
@Override
|
||||
public void onOverviewShown(boolean triggeredFromAltTab) {
|
||||
// If ev are using the new dispatching system, skip the old logic
|
||||
if (mInputEventReceiver != null) {
|
||||
mOverviewCommandHelper.onOverviewShown();
|
||||
return;
|
||||
}
|
||||
if (triggeredFromAltTab) {
|
||||
mEventQueue.onNewGesture(HIT_TARGET_NONE);
|
||||
mEventQueue.onOverviewShownFromAltTab();
|
||||
} else {
|
||||
mOverviewCommandHelper.onOverviewShown();
|
||||
}
|
||||
mOverviewCommandHelper.onOverviewShown();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onOverviewHidden(boolean triggeredFromAltTab, boolean triggeredFromHomeKey) {
|
||||
// If ev are using the new dispatching system, skip the old logic
|
||||
if (mInputEventReceiver != null) {
|
||||
return;
|
||||
}
|
||||
if (triggeredFromAltTab && !triggeredFromHomeKey) {
|
||||
// onOverviewShownFromAltTab initiates quick scrub. Ending it here.
|
||||
mEventQueue.onQuickScrubEnd();
|
||||
// onOverviewShownFromAltTab hides the overview and ends at the target app
|
||||
mOverviewCommandHelper.onOverviewHidden();
|
||||
}
|
||||
}
|
||||
|
||||
public void onQuickStep(MotionEvent motionEvent) { }
|
||||
|
||||
@Override
|
||||
public void onTip(int actionType, int viewType) {
|
||||
mOverviewCommandHelper.onTip(actionType, viewType);
|
||||
}
|
||||
|
||||
/** Deprecated methods **/
|
||||
public void onQuickStep(MotionEvent motionEvent) { }
|
||||
|
||||
public void onQuickScrubEnd() { }
|
||||
|
||||
public void onQuickScrubProgress(float progress) { }
|
||||
|
||||
public void onQuickScrubStart() { }
|
||||
|
||||
public void onPreMotionEvent(int downHitTarget) { }
|
||||
|
||||
public void onMotionEvent(MotionEvent ev) {
|
||||
if (mDeprecatedDispatcher == null) {
|
||||
ev.recycle();
|
||||
} else {
|
||||
mDeprecatedDispatcher.dispatch(ev);
|
||||
}
|
||||
}
|
||||
|
||||
public void onBind(ISystemUiProxy iSystemUiProxy) {
|
||||
mISystemUiProxy = iSystemUiProxy;
|
||||
mRecentsModel.setSystemUiProxy(mISystemUiProxy);
|
||||
mOverviewInteractionState.setSystemUiProxy(mISystemUiProxy);
|
||||
|
||||
// On Bind is received before onInitialize which will dispose these handlers
|
||||
disposeEventHandlers();
|
||||
Pair<InputEventDispatcher, InputEventReceiver> pair = InputChannelCompat.createPair(
|
||||
"sysui-callbacks", Looper.getMainLooper(), mMainChoreographer,
|
||||
TouchInteractionService.this::onInputEvent);
|
||||
mDeprecatedDispatcher = pair.first;
|
||||
mInputEventReceiver = pair.second;
|
||||
|
||||
}
|
||||
};
|
||||
|
||||
private static boolean sConnected = false;
|
||||
|
@ -200,22 +145,23 @@ public class TouchInteractionService extends Service {
|
|||
|
||||
private ActivityManagerWrapper mAM;
|
||||
private RecentsModel mRecentsModel;
|
||||
private MotionEventQueue mEventQueue;
|
||||
private ISystemUiProxy mISystemUiProxy;
|
||||
private OverviewCommandHelper mOverviewCommandHelper;
|
||||
private OverviewComponentObserver mOverviewComponentObserver;
|
||||
private OverviewInteractionState mOverviewInteractionState;
|
||||
private OverviewCallbacks mOverviewCallbacks;
|
||||
private TaskOverlayFactory mTaskOverlayFactory;
|
||||
private TouchInteractionLog mTouchInteractionLog;
|
||||
private InputConsumerController mInputConsumer;
|
||||
private SwipeSharedState mSwipeSharedState;
|
||||
|
||||
private TouchConsumer mConsumer = TouchConsumer.NO_OP;
|
||||
private Choreographer mMainChoreographer;
|
||||
|
||||
private InputEventReceiver mInputEventReceiver;
|
||||
private Region mActiveNavBarRegion = new Region();
|
||||
|
||||
private InputEventDispatcher mDeprecatedDispatcher;
|
||||
|
||||
@Override
|
||||
public void onCreate() {
|
||||
super.onCreate();
|
||||
|
@ -225,12 +171,9 @@ public class TouchInteractionService extends Service {
|
|||
mMainChoreographer = Choreographer.getInstance();
|
||||
|
||||
mOverviewCommandHelper = new OverviewCommandHelper(this, mOverviewComponentObserver);
|
||||
mEventQueue = new MotionEventQueue(Looper.myLooper(), Choreographer.getInstance(),
|
||||
this::newConsumer);
|
||||
mOverviewInteractionState = OverviewInteractionState.INSTANCE.get(this);
|
||||
mOverviewCallbacks = OverviewCallbacks.get(this);
|
||||
mTaskOverlayFactory = TaskOverlayFactory.INSTANCE.get(this);
|
||||
mTouchInteractionLog = new TouchInteractionLog();
|
||||
mSwipeSharedState = new SwipeSharedState();
|
||||
mInputConsumer = InputConsumerController.getRecentsAnimationInputConsumer();
|
||||
mInputConsumer.registerInputConsumer();
|
||||
|
@ -245,14 +188,22 @@ public class TouchInteractionService extends Service {
|
|||
public void onDestroy() {
|
||||
mInputConsumer.unregisterInputConsumer();
|
||||
mOverviewComponentObserver.onDestroy();
|
||||
mEventQueue.dispose();
|
||||
if (mInputEventReceiver != null) {
|
||||
mInputEventReceiver.dispose();
|
||||
}
|
||||
disposeEventHandlers();
|
||||
sConnected = false;
|
||||
super.onDestroy();
|
||||
}
|
||||
|
||||
private void disposeEventHandlers() {
|
||||
if (mInputEventReceiver != null) {
|
||||
mInputEventReceiver.dispose();
|
||||
mInputEventReceiver = null;
|
||||
}
|
||||
if (mDeprecatedDispatcher != null) {
|
||||
mDeprecatedDispatcher.dispose();
|
||||
mDeprecatedDispatcher = null;
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public IBinder onBind(Intent intent) {
|
||||
Log.d(TAG, "Touch service connected");
|
||||
|
@ -266,45 +217,17 @@ public class TouchInteractionService extends Service {
|
|||
}
|
||||
MotionEvent event = (MotionEvent) ev;
|
||||
if (event.getAction() == ACTION_DOWN) {
|
||||
mTouchInteractionLog.prepareForNewGesture();
|
||||
TOUCH_INTERACTION_LOG.prepareForNewGesture();
|
||||
boolean useSharedState = mConsumer.isActive();
|
||||
mConsumer.onConsumerAboutToBeSwitched();
|
||||
mConsumer = newConsumer(useSharedState, event);
|
||||
TOUCH_INTERACTION_LOG.setTouchConsumer(mConsumer);
|
||||
}
|
||||
TOUCH_INTERACTION_LOG.addMotionEvent(event);
|
||||
|
||||
mConsumer.accept(event);
|
||||
}
|
||||
|
||||
private TouchConsumer newConsumer(@HitTarget int downHitTarget, boolean useSharedState) {
|
||||
RunningTaskInfo runningTaskInfo = mAM.getRunningTask(0);
|
||||
if (!useSharedState) {
|
||||
mSwipeSharedState.clearAllState();
|
||||
}
|
||||
|
||||
if (runningTaskInfo == null && !mSwipeSharedState.goingToLauncher) {
|
||||
return TouchConsumer.NO_OP;
|
||||
} else if (mSwipeSharedState.goingToLauncher ||
|
||||
mOverviewComponentObserver.getActivityControlHelper().isResumed()) {
|
||||
return OverviewTouchConsumer.newInstance(
|
||||
mOverviewComponentObserver.getActivityControlHelper(), false,
|
||||
mTouchInteractionLog);
|
||||
} else if (ENABLE_QUICKSTEP_LIVE_TILE.get() &&
|
||||
mOverviewComponentObserver.getActivityControlHelper().isInLiveTileMode()) {
|
||||
return OverviewTouchConsumer.newInstance(
|
||||
mOverviewComponentObserver.getActivityControlHelper(), false,
|
||||
mTouchInteractionLog, false /* waitForWindowAvailable */);
|
||||
} else {
|
||||
ActivityControlHelper activityControl =
|
||||
mOverviewComponentObserver.getActivityControlHelper();
|
||||
return new OtherActivityTouchConsumer(this, runningTaskInfo, mRecentsModel,
|
||||
mOverviewComponentObserver.getOverviewIntent(),
|
||||
mOverviewComponentObserver.getActivityControlHelper(),
|
||||
activityControl.deferStartingActivity(downHitTarget), mOverviewCallbacks,
|
||||
mTaskOverlayFactory, mInputConsumer, mTouchInteractionLog,
|
||||
mEventQueue::onConsumerInactive, mSwipeSharedState);
|
||||
}
|
||||
}
|
||||
|
||||
private TouchConsumer newConsumer(boolean useSharedState, MotionEvent event) {
|
||||
RunningTaskInfo runningTaskInfo = mAM.getRunningTask(0);
|
||||
if (!useSharedState) {
|
||||
|
@ -316,13 +239,11 @@ public class TouchInteractionService extends Service {
|
|||
} else if (mSwipeSharedState.goingToLauncher ||
|
||||
mOverviewComponentObserver.getActivityControlHelper().isResumed()) {
|
||||
return OverviewTouchConsumer.newInstance(
|
||||
mOverviewComponentObserver.getActivityControlHelper(), false,
|
||||
mTouchInteractionLog);
|
||||
mOverviewComponentObserver.getActivityControlHelper(), false);
|
||||
} else if (ENABLE_QUICKSTEP_LIVE_TILE.get() &&
|
||||
mOverviewComponentObserver.getActivityControlHelper().isInLiveTileMode()) {
|
||||
return OverviewTouchConsumer.newInstance(
|
||||
mOverviewComponentObserver.getActivityControlHelper(), false,
|
||||
mTouchInteractionLog, false /* waitForWindowAvailable */);
|
||||
mOverviewComponentObserver.getActivityControlHelper(), false);
|
||||
} else {
|
||||
ActivityControlHelper activityControl =
|
||||
mOverviewComponentObserver.getActivityControlHelper();
|
||||
|
@ -331,7 +252,7 @@ public class TouchInteractionService extends Service {
|
|||
mOverviewComponentObserver.getOverviewIntent(),
|
||||
mOverviewComponentObserver.getActivityControlHelper(),
|
||||
shouldDefer, mOverviewCallbacks,
|
||||
mTaskOverlayFactory, mInputConsumer, mTouchInteractionLog,
|
||||
mTaskOverlayFactory, mInputConsumer,
|
||||
this::onConsumerInactive, mSwipeSharedState);
|
||||
}
|
||||
}
|
||||
|
@ -347,6 +268,6 @@ public class TouchInteractionService extends Service {
|
|||
|
||||
@Override
|
||||
protected void dump(FileDescriptor fd, PrintWriter pw, String[] args) {
|
||||
mTouchInteractionLog.dump(pw);
|
||||
TOUCH_INTERACTION_LOG.dump(pw);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -25,16 +25,14 @@ import static com.android.launcher3.anim.Interpolators.LINEAR;
|
|||
import static com.android.launcher3.anim.Interpolators.OVERSHOOT_1_2;
|
||||
import static com.android.launcher3.config.FeatureFlags.ENABLE_QUICKSTEP_LIVE_TILE;
|
||||
import static com.android.launcher3.config.FeatureFlags.QUICKSTEP_SPRINGS;
|
||||
import static com.android.launcher3.config.FeatureFlags.SWIPE_HOME;
|
||||
import static com.android.launcher3.util.RaceConditionTracker.ENTER;
|
||||
import static com.android.launcher3.util.RaceConditionTracker.EXIT;
|
||||
import static com.android.launcher3.config.FeatureFlags.SWIPE_HOME;
|
||||
import static com.android.quickstep.ActivityControlHelper.AnimationFactory.ShelfAnimState.HIDE;
|
||||
import static com.android.quickstep.ActivityControlHelper.AnimationFactory.ShelfAnimState.PEEK;
|
||||
import static com.android.quickstep.QuickScrubController.QUICK_SCRUB_FROM_APP_START_DURATION;
|
||||
import static com.android.quickstep.QuickScrubController.QUICK_SWITCH_FROM_APP_START_DURATION;
|
||||
import static com.android.quickstep.TouchConsumer.INTERACTION_NORMAL;
|
||||
import static com.android.quickstep.TouchConsumer.INTERACTION_QUICK_SCRUB;
|
||||
import static com.android.quickstep.MultiStateCallback.DEBUG_STATES;
|
||||
import static com.android.quickstep.TouchInteractionService.MAIN_THREAD_EXECUTOR;
|
||||
import static com.android.quickstep.TouchInteractionService.TOUCH_INTERACTION_LOG;
|
||||
import static com.android.quickstep.WindowTransformSwipeHandler.GestureEndTarget.HOME;
|
||||
import static com.android.quickstep.WindowTransformSwipeHandler.GestureEndTarget.LAST_TASK;
|
||||
import static com.android.quickstep.WindowTransformSwipeHandler.GestureEndTarget.NEW_TASK;
|
||||
|
@ -50,7 +48,6 @@ import android.animation.ValueAnimator;
|
|||
import android.annotation.TargetApi;
|
||||
import android.app.ActivityManager.RunningTaskInfo;
|
||||
import android.content.Context;
|
||||
import android.content.res.Resources;
|
||||
import android.graphics.Canvas;
|
||||
import android.graphics.Point;
|
||||
import android.graphics.Rect;
|
||||
|
@ -60,7 +57,6 @@ import android.os.Bundle;
|
|||
import android.os.Handler;
|
||||
import android.os.Looper;
|
||||
import android.os.SystemClock;
|
||||
import android.os.UserHandle;
|
||||
import android.view.HapticFeedbackConstants;
|
||||
import android.view.MotionEvent;
|
||||
import android.view.View;
|
||||
|
@ -68,10 +64,6 @@ import android.view.ViewTreeObserver.OnDrawListener;
|
|||
import android.view.WindowManager;
|
||||
import android.view.animation.Interpolator;
|
||||
|
||||
import androidx.annotation.NonNull;
|
||||
import androidx.annotation.Nullable;
|
||||
import androidx.annotation.UiThread;
|
||||
|
||||
import com.android.launcher3.AbstractFloatingView;
|
||||
import com.android.launcher3.BaseDraggingActivity;
|
||||
import com.android.launcher3.DeviceProfile;
|
||||
|
@ -94,17 +86,14 @@ import com.android.quickstep.ActivityControlHelper.ActivityInitListener;
|
|||
import com.android.quickstep.ActivityControlHelper.AnimationFactory;
|
||||
import com.android.quickstep.ActivityControlHelper.AnimationFactory.ShelfAnimState;
|
||||
import com.android.quickstep.ActivityControlHelper.LayoutListener;
|
||||
import com.android.quickstep.TouchConsumer.InteractionType;
|
||||
import com.android.quickstep.util.ClipAnimationHelper;
|
||||
import com.android.quickstep.util.RemoteAnimationTargetSet;
|
||||
import com.android.quickstep.util.SwipeAnimationTargetSet;
|
||||
import com.android.quickstep.util.SwipeAnimationTargetSet.SwipeAnimationListener;
|
||||
import com.android.quickstep.util.TransformedRect;
|
||||
import com.android.quickstep.views.RecentsView;
|
||||
import com.android.quickstep.views.TaskView;
|
||||
import com.android.systemui.shared.recents.model.ThumbnailData;
|
||||
import com.android.systemui.shared.recents.utilities.RectFEvaluator;
|
||||
import com.android.systemui.shared.system.ActivityManagerWrapper;
|
||||
import com.android.systemui.shared.system.InputConsumerController;
|
||||
import com.android.systemui.shared.system.LatencyTrackerCompat;
|
||||
import com.android.systemui.shared.system.RecentsAnimationControllerCompat;
|
||||
|
@ -114,44 +103,67 @@ import com.android.systemui.shared.system.WindowCallbacksCompat;
|
|||
|
||||
import java.util.function.BiFunction;
|
||||
|
||||
import androidx.annotation.NonNull;
|
||||
import androidx.annotation.Nullable;
|
||||
import androidx.annotation.UiThread;
|
||||
|
||||
@TargetApi(Build.VERSION_CODES.O)
|
||||
public class WindowTransformSwipeHandler<T extends BaseDraggingActivity>
|
||||
implements SwipeAnimationListener {
|
||||
private static final String TAG = WindowTransformSwipeHandler.class.getSimpleName();
|
||||
|
||||
private static final String[] STATE_NAMES = DEBUG_STATES ? new String[19] : null;
|
||||
|
||||
private static int getFlagForIndex(int index, String name) {
|
||||
if (DEBUG_STATES) {
|
||||
STATE_NAMES[index] = name;
|
||||
}
|
||||
return 1 << index;
|
||||
}
|
||||
|
||||
// Launcher UI related states
|
||||
private static final int STATE_LAUNCHER_PRESENT = 1 << 0;
|
||||
private static final int STATE_LAUNCHER_STARTED = 1 << 1;
|
||||
private static final int STATE_LAUNCHER_DRAWN = 1 << 2;
|
||||
private static final int STATE_ACTIVITY_MULTIPLIER_COMPLETE = 1 << 3;
|
||||
private static final int STATE_LAUNCHER_PRESENT = getFlagForIndex(0, "STATE_LAUNCHER_PRESENT");
|
||||
private static final int STATE_LAUNCHER_STARTED = getFlagForIndex(1, "STATE_LAUNCHER_STARTED");
|
||||
private static final int STATE_LAUNCHER_DRAWN = getFlagForIndex(2, "STATE_LAUNCHER_DRAWN");
|
||||
private static final int STATE_ACTIVITY_MULTIPLIER_COMPLETE =
|
||||
getFlagForIndex(3, "STATE_ACTIVITY_MULTIPLIER_COMPLETE");
|
||||
|
||||
// Internal initialization states
|
||||
private static final int STATE_APP_CONTROLLER_RECEIVED = 1 << 4;
|
||||
private static final int STATE_APP_CONTROLLER_RECEIVED =
|
||||
getFlagForIndex(4, "STATE_APP_CONTROLLER_RECEIVED");
|
||||
|
||||
// Interaction finish states
|
||||
private static final int STATE_SCALED_CONTROLLER_HOME = 1 << 5;
|
||||
private static final int STATE_SCALED_CONTROLLER_RECENTS = 1 << 6;
|
||||
private static final int STATE_SCALED_CONTROLLER_LAST_TASK = 1 << 7;
|
||||
private static final int STATE_SCALED_CONTROLLER_HOME =
|
||||
getFlagForIndex(5, "STATE_SCALED_CONTROLLER_HOME");
|
||||
private static final int STATE_SCALED_CONTROLLER_RECENTS =
|
||||
getFlagForIndex(6, "STATE_SCALED_CONTROLLER_RECENTS");
|
||||
private static final int STATE_SCALED_CONTROLLER_LAST_TASK =
|
||||
getFlagForIndex(7, "STATE_SCALED_CONTROLLER_LAST_TASK");
|
||||
|
||||
private static final int STATE_HANDLER_INVALIDATED = 1 << 8;
|
||||
private static final int STATE_GESTURE_STARTED_QUICKSTEP = 1 << 9;
|
||||
private static final int STATE_GESTURE_STARTED_QUICKSCRUB = 1 << 10;
|
||||
private static final int STATE_GESTURE_CANCELLED = 1 << 11;
|
||||
private static final int STATE_GESTURE_COMPLETED = 1 << 12;
|
||||
private static final int STATE_HANDLER_INVALIDATED =
|
||||
getFlagForIndex(8, "STATE_HANDLER_INVALIDATED");
|
||||
private static final int STATE_GESTURE_STARTED =
|
||||
getFlagForIndex(9, "STATE_GESTURE_STARTED");
|
||||
private static final int STATE_GESTURE_CANCELLED =
|
||||
getFlagForIndex(10, "STATE_GESTURE_CANCELLED");
|
||||
private static final int STATE_GESTURE_COMPLETED =
|
||||
getFlagForIndex(11, "STATE_GESTURE_COMPLETED");
|
||||
|
||||
// States for quick switch/scrub
|
||||
private static final int STATE_CURRENT_TASK_FINISHED = 1 << 13;
|
||||
private static final int STATE_QUICK_SCRUB_START = 1 << 14;
|
||||
private static final int STATE_QUICK_SCRUB_END = 1 << 15;
|
||||
|
||||
private static final int STATE_CAPTURE_SCREENSHOT = 1 << 16;
|
||||
private static final int STATE_SCREENSHOT_CAPTURED = 1 << 17;
|
||||
private static final int STATE_SCREENSHOT_VIEW_SHOWN = 1 << 18;
|
||||
|
||||
private static final int STATE_RESUME_LAST_TASK = 1 << 19;
|
||||
private static final int STATE_START_NEW_TASK = 1 << 20;
|
||||
private static final int STATE_ASSIST_DATA_RECEIVED = 1 << 21;
|
||||
private static final int STATE_CAPTURE_SCREENSHOT =
|
||||
getFlagForIndex(12, "STATE_CAPTURE_SCREENSHOT");
|
||||
private static final int STATE_SCREENSHOT_CAPTURED =
|
||||
getFlagForIndex(13, "STATE_SCREENSHOT_CAPTURED");
|
||||
private static final int STATE_SCREENSHOT_VIEW_SHOWN =
|
||||
getFlagForIndex(14, "STATE_SCREENSHOT_VIEW_SHOWN");
|
||||
|
||||
private static final int STATE_RESUME_LAST_TASK =
|
||||
getFlagForIndex(15, "STATE_RESUME_LAST_TASK");
|
||||
private static final int STATE_START_NEW_TASK =
|
||||
getFlagForIndex(16, "STATE_START_NEW_TASK");
|
||||
private static final int STATE_CURRENT_TASK_FINISHED =
|
||||
getFlagForIndex(17, "STATE_CURRENT_TASK_FINISHED");
|
||||
private static final int STATE_ASSIST_DATA_RECEIVED =
|
||||
getFlagForIndex(18, "STATE_ASSIST_DATA_RECEIVED");
|
||||
|
||||
private static final int LAUNCHER_UI_STATES =
|
||||
STATE_LAUNCHER_PRESENT | STATE_LAUNCHER_DRAWN | STATE_ACTIVITY_MULTIPLIER_COMPLETE
|
||||
|
@ -165,34 +177,7 @@ public class WindowTransformSwipeHandler<T extends BaseDraggingActivity>
|
|||
STATE_ACTIVITY_MULTIPLIER_COMPLETE | STATE_LAUNCHER_STARTED
|
||||
| STATE_APP_CONTROLLER_RECEIVED | STATE_SCREENSHOT_CAPTURED;
|
||||
|
||||
private static final int QUICK_SCRUB_START_UI_STATE = STATE_LAUNCHER_STARTED
|
||||
| STATE_QUICK_SCRUB_START | STATE_APP_CONTROLLER_RECEIVED;
|
||||
|
||||
// For debugging, keep in sync with above states
|
||||
public static final String[] STATES = new String[] {
|
||||
"STATE_LAUNCHER_PRESENT",
|
||||
"STATE_LAUNCHER_STARTED",
|
||||
"STATE_LAUNCHER_DRAWN",
|
||||
"STATE_ACTIVITY_MULTIPLIER_COMPLETE",
|
||||
"STATE_APP_CONTROLLER_RECEIVED",
|
||||
"STATE_SCALED_CONTROLLER_HOME",
|
||||
"STATE_SCALED_CONTROLLER_RECENTS",
|
||||
"STATE_SCALED_CONTROLLER_LAST_TASK",
|
||||
"STATE_HANDLER_INVALIDATED",
|
||||
"STATE_GESTURE_STARTED_QUICKSTEP",
|
||||
"STATE_GESTURE_STARTED_QUICKSCRUB",
|
||||
"STATE_GESTURE_CANCELLED",
|
||||
"STATE_GESTURE_COMPLETED",
|
||||
"STATE_CURRENT_TASK_FINISHED",
|
||||
"STATE_QUICK_SCRUB_START",
|
||||
"STATE_QUICK_SCRUB_END",
|
||||
"STATE_CAPTURE_SCREENSHOT",
|
||||
"STATE_SCREENSHOT_CAPTURED",
|
||||
"STATE_SCREENSHOT_VIEW_SHOWN",
|
||||
"STATE_RESUME_LAST_TASK",
|
||||
"STATE_START_NEW_TASK",
|
||||
"STATE_ASSIST_DATA_RECEIVED",
|
||||
};
|
||||
|
||||
enum GestureEndTarget {
|
||||
HOME(1, STATE_SCALED_CONTROLLER_HOME, true, false, ContainerType.WORKSPACE),
|
||||
|
@ -256,7 +241,6 @@ public class WindowTransformSwipeHandler<T extends BaseDraggingActivity>
|
|||
private final Context mContext;
|
||||
private final ActivityControlHelper<T> mActivityControlHelper;
|
||||
private final ActivityInitListener mActivityInitListener;
|
||||
private final TouchInteractionLog mTouchInteractionLog;
|
||||
|
||||
private final int mRunningTaskId;
|
||||
private final RunningTaskInfo mRunningTaskInfo;
|
||||
|
@ -269,18 +253,13 @@ public class WindowTransformSwipeHandler<T extends BaseDraggingActivity>
|
|||
private LayoutListener mLayoutListener;
|
||||
private RecentsView mRecentsView;
|
||||
private SyncRtSurfaceTransactionApplierCompat mSyncTransactionApplier;
|
||||
private QuickScrubController mQuickScrubController;
|
||||
private AnimationFactory mAnimationFactory = (t, i) -> { };
|
||||
private AnimationFactory mAnimationFactory = (t) -> { };
|
||||
|
||||
private boolean mWasLauncherAlreadyVisible;
|
||||
|
||||
private boolean mPassedOverviewThreshold;
|
||||
private boolean mGestureStarted;
|
||||
private int mLogAction = Touch.SWIPE;
|
||||
private float mCurrentQuickScrubProgress;
|
||||
private boolean mQuickScrubBlocked;
|
||||
|
||||
private @InteractionType int mInteractionType = INTERACTION_NORMAL;
|
||||
|
||||
private final RecentsAnimationWrapper mRecentsAnimationWrapper;
|
||||
|
||||
|
@ -295,7 +274,7 @@ public class WindowTransformSwipeHandler<T extends BaseDraggingActivity>
|
|||
|
||||
WindowTransformSwipeHandler(RunningTaskInfo runningTaskInfo, Context context,
|
||||
long touchTimeMs, ActivityControlHelper<T> controller, boolean continuingLastGesture,
|
||||
InputConsumerController inputConsumer, TouchInteractionLog touchInteractionLog) {
|
||||
InputConsumerController inputConsumer) {
|
||||
mContext = context;
|
||||
mRunningTaskInfo = runningTaskInfo;
|
||||
mRunningTaskId = runningTaskInfo.id;
|
||||
|
@ -304,7 +283,6 @@ public class WindowTransformSwipeHandler<T extends BaseDraggingActivity>
|
|||
mActivityInitListener = mActivityControlHelper
|
||||
.createActivityInitListener(this::onActivityInit);
|
||||
mContinuingLastGesture = continuingLastGesture;
|
||||
mTouchInteractionLog = touchInteractionLog;
|
||||
mRecentsAnimationWrapper = new RecentsAnimationWrapper(inputConsumer,
|
||||
this::createNewTouchProxyHandler);
|
||||
mClipAnimationHelper = new ClipAnimationHelper(context);
|
||||
|
@ -314,24 +292,20 @@ public class WindowTransformSwipeHandler<T extends BaseDraggingActivity>
|
|||
}
|
||||
|
||||
private void initStateCallbacks() {
|
||||
mStateCallback = new MultiStateCallback();
|
||||
mStateCallback = new MultiStateCallback(STATE_NAMES);
|
||||
|
||||
// Re-setup the recents UI when gesture starts, as the state could have been changed during
|
||||
// that time by a previous window transition.
|
||||
mStateCallback.addCallback(STATE_LAUNCHER_STARTED | STATE_GESTURE_STARTED_QUICKSTEP,
|
||||
mStateCallback.addCallback(STATE_LAUNCHER_STARTED | STATE_GESTURE_STARTED,
|
||||
this::setupRecentsViewUi);
|
||||
|
||||
mStateCallback.addCallback(STATE_LAUNCHER_DRAWN | STATE_GESTURE_STARTED_QUICKSCRUB,
|
||||
this::initializeLauncherAnimationController);
|
||||
mStateCallback.addCallback(STATE_LAUNCHER_DRAWN | STATE_GESTURE_STARTED_QUICKSTEP,
|
||||
mStateCallback.addCallback(STATE_LAUNCHER_DRAWN | STATE_GESTURE_STARTED,
|
||||
this::initializeLauncherAnimationController);
|
||||
|
||||
mStateCallback.addCallback(STATE_LAUNCHER_PRESENT | STATE_LAUNCHER_DRAWN,
|
||||
this::launcherFrameDrawn);
|
||||
|
||||
mStateCallback.addCallback(STATE_LAUNCHER_PRESENT | STATE_GESTURE_STARTED_QUICKSTEP,
|
||||
this::notifyGestureStartedAsync);
|
||||
mStateCallback.addCallback(STATE_LAUNCHER_PRESENT | STATE_GESTURE_STARTED_QUICKSCRUB,
|
||||
mStateCallback.addCallback(STATE_LAUNCHER_PRESENT | STATE_GESTURE_STARTED,
|
||||
this::notifyGestureStartedAsync);
|
||||
|
||||
mStateCallback.addCallback(STATE_LAUNCHER_PRESENT | STATE_LAUNCHER_STARTED
|
||||
|
@ -367,12 +341,12 @@ public class WindowTransformSwipeHandler<T extends BaseDraggingActivity>
|
|||
mStateCallback.addCallback(STATE_LAUNCHER_PRESENT | STATE_APP_CONTROLLER_RECEIVED
|
||||
| STATE_ACTIVITY_MULTIPLIER_COMPLETE | STATE_SCALED_CONTROLLER_RECENTS
|
||||
| STATE_CURRENT_TASK_FINISHED | STATE_GESTURE_COMPLETED
|
||||
| STATE_GESTURE_STARTED_QUICKSTEP,
|
||||
| STATE_GESTURE_STARTED,
|
||||
this::setupLauncherUiAfterSwipeUpAnimation);
|
||||
mStateCallback.addCallback(STATE_LAUNCHER_PRESENT | STATE_APP_CONTROLLER_RECEIVED
|
||||
| STATE_ACTIVITY_MULTIPLIER_COMPLETE | STATE_SCALED_CONTROLLER_RECENTS
|
||||
| STATE_CURRENT_TASK_FINISHED | STATE_GESTURE_COMPLETED
|
||||
| STATE_GESTURE_STARTED_QUICKSTEP | STATE_ASSIST_DATA_RECEIVED,
|
||||
| STATE_GESTURE_STARTED | STATE_ASSIST_DATA_RECEIVED,
|
||||
this::preloadAssistData);
|
||||
|
||||
mStateCallback.addCallback(STATE_HANDLER_INVALIDATED, this::invalidateHandler);
|
||||
|
@ -382,12 +356,6 @@ public class WindowTransformSwipeHandler<T extends BaseDraggingActivity>
|
|||
| STATE_SCALED_CONTROLLER_LAST_TASK,
|
||||
this::notifyTransitionCancelled);
|
||||
|
||||
mStateCallback.addCallback(QUICK_SCRUB_START_UI_STATE, this::onQuickScrubStartUi);
|
||||
mStateCallback.addCallback(STATE_LAUNCHER_STARTED | STATE_QUICK_SCRUB_START
|
||||
| STATE_SCALED_CONTROLLER_RECENTS, this::onFinishedTransitionToQuickScrub);
|
||||
mStateCallback.addCallback(STATE_LAUNCHER_STARTED | STATE_CURRENT_TASK_FINISHED
|
||||
| STATE_QUICK_SCRUB_END, this::switchToFinalAppAfterQuickScrub);
|
||||
|
||||
mStateCallback.addCallback(LONG_SWIPE_ENTER_STATE, this::checkLongSwipeCanEnter);
|
||||
mStateCallback.addCallback(LONG_SWIPE_START_STATE, this::checkLongSwipeCanStart);
|
||||
|
||||
|
@ -409,9 +377,9 @@ public class WindowTransformSwipeHandler<T extends BaseDraggingActivity>
|
|||
private void initTransitionEndpoints(DeviceProfile dp) {
|
||||
mDp = dp;
|
||||
|
||||
TransformedRect tempRect = new TransformedRect();
|
||||
Rect tempRect = new Rect();
|
||||
mTransitionDragLength = mActivityControlHelper.getSwipeUpDestinationAndLength(
|
||||
dp, mContext, mInteractionType, tempRect);
|
||||
dp, mContext, tempRect);
|
||||
mClipAnimationHelper.updateTargetRect(tempRect);
|
||||
}
|
||||
|
||||
|
@ -464,7 +432,6 @@ public class WindowTransformSwipeHandler<T extends BaseDraggingActivity>
|
|||
});
|
||||
mRecentsView.setRecentsAnimationWrapper(mRecentsAnimationWrapper);
|
||||
mRecentsView.setClipAnimationHelper(mClipAnimationHelper);
|
||||
mQuickScrubController = mRecentsView.getQuickScrubController();
|
||||
mLayoutListener = mActivityControlHelper.createLayoutListener(mActivity);
|
||||
|
||||
mStateCallback.setState(STATE_LAUNCHER_PRESENT);
|
||||
|
@ -560,38 +527,12 @@ public class WindowTransformSwipeHandler<T extends BaseDraggingActivity>
|
|||
LatencyTrackerCompat.logToggleRecents((int) (mLauncherFrameDrawnTime - mTouchTimeMs));
|
||||
}
|
||||
|
||||
// This method is only called when STATE_GESTURE_STARTED_QUICKSTEP/
|
||||
// STATE_GESTURE_STARTED_QUICKSCRUB is set, so we can enable the high-res thumbnail loader
|
||||
// here once we are sure that we will end up in an overview state
|
||||
// This method is only called when STATE_GESTURE_STARTED is set, so we can enable the
|
||||
// high-res thumbnail loader here once we are sure that we will end up in an overview state
|
||||
RecentsModel.INSTANCE.get(mContext).getThumbnailCache()
|
||||
.getHighResLoadingState().setVisible(true);
|
||||
}
|
||||
|
||||
private void shiftAnimationDestinationForQuickscrub() {
|
||||
TransformedRect tempRect = new TransformedRect();
|
||||
mActivityControlHelper
|
||||
.getSwipeUpDestinationAndLength(mDp, mContext, mInteractionType, tempRect);
|
||||
mClipAnimationHelper.updateTargetRect(tempRect);
|
||||
|
||||
float offsetY =
|
||||
mActivityControlHelper.getTranslationYForQuickScrub(tempRect, mDp, mContext);
|
||||
float scale, offsetX;
|
||||
Resources res = mContext.getResources();
|
||||
|
||||
if (ActivityManagerWrapper.getInstance().getRecentTasks(2, UserHandle.myUserId()).size()
|
||||
< 2) {
|
||||
// There are not enough tasks, we don't need to shift
|
||||
offsetX = 0;
|
||||
scale = 1;
|
||||
} else {
|
||||
offsetX = res.getDimensionPixelSize(R.dimen.recents_page_spacing)
|
||||
+ tempRect.rect.width();
|
||||
scale = getTaskCurveScaleForOffsetX(offsetX, tempRect.rect.width());
|
||||
}
|
||||
mClipAnimationHelper.offsetTarget(scale, Utilities.isRtl(res) ? -offsetX : offsetX, offsetY,
|
||||
QuickScrubController.QUICK_SCRUB_START_INTERPOLATOR);
|
||||
}
|
||||
|
||||
private float getTaskCurveScaleForOffsetX(float offsetX, float taskWidth) {
|
||||
float distanceToReachEdge = mDp.widthPx / 2 + taskWidth / 2 +
|
||||
mContext.getResources().getDimensionPixelSize(R.dimen.recents_page_spacing);
|
||||
|
@ -647,13 +588,11 @@ public class WindowTransformSwipeHandler<T extends BaseDraggingActivity>
|
|||
|
||||
@UiThread
|
||||
public void setShelfState(ShelfAnimState shelfState, Interpolator interpolator, long duration) {
|
||||
if (mInteractionType == INTERACTION_NORMAL) {
|
||||
mAnimationFactory.setShelfState(shelfState, interpolator, duration);
|
||||
mIsShelfPeeking = shelfState == PEEK;
|
||||
if (mRecentsView != null && shelfState.shouldPreformHaptic) {
|
||||
mRecentsView.performHapticFeedback(HapticFeedbackConstants.VIRTUAL_KEY,
|
||||
HapticFeedbackConstants.FLAG_IGNORE_VIEW_SETTING);
|
||||
}
|
||||
mAnimationFactory.setShelfState(shelfState, interpolator, duration);
|
||||
mIsShelfPeeking = shelfState == PEEK;
|
||||
if (mRecentsView != null && shelfState.shouldPreformHaptic) {
|
||||
mRecentsView.performHapticFeedback(HapticFeedbackConstants.VIRTUAL_KEY,
|
||||
HapticFeedbackConstants.FLAG_IGNORE_VIEW_SETTING);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -662,7 +601,7 @@ public class WindowTransformSwipeHandler<T extends BaseDraggingActivity>
|
|||
*/
|
||||
public void buildAnimationController() {
|
||||
initTransitionEndpoints(mActivity.getDeviceProfile());
|
||||
mAnimationFactory.createActivityController(mTransitionDragLength, mInteractionType);
|
||||
mAnimationFactory.createActivityController(mTransitionDragLength);
|
||||
}
|
||||
|
||||
private void onAnimatorPlaybackControllerCreated(AnimatorPlaybackController anim) {
|
||||
|
@ -678,7 +617,7 @@ public class WindowTransformSwipeHandler<T extends BaseDraggingActivity>
|
|||
RecentsAnimationControllerCompat controller = mRecentsAnimationWrapper.getController();
|
||||
if (controller != null) {
|
||||
float offsetX = 0;
|
||||
if (mRecentsView != null && mInteractionType == INTERACTION_NORMAL) {
|
||||
if (mRecentsView != null) {
|
||||
int startScroll = mRecentsView.getScrollForPage(mRecentsView.indexOfChild(
|
||||
mRecentsView.getRunningTaskView()));
|
||||
offsetX = startScroll - mRecentsView.getScrollX();
|
||||
|
@ -699,9 +638,7 @@ public class WindowTransformSwipeHandler<T extends BaseDraggingActivity>
|
|||
}
|
||||
|
||||
if (ENABLE_QUICKSTEP_LIVE_TILE.get()) {
|
||||
if (mRecentsAnimationWrapper.getController() != null && mLayoutListener != null &&
|
||||
(mInteractionType == INTERACTION_NORMAL
|
||||
|| !mQuickScrubController.hasFinishedTransitionToQuickScrub())) {
|
||||
if (mRecentsAnimationWrapper.getController() != null && mLayoutListener != null) {
|
||||
mLayoutListener.open();
|
||||
mLayoutListener.update(mCurrentShift.value > 1, mLongSwipeMode,
|
||||
mClipAnimationHelper.getCurrentRectWithInsets(),
|
||||
|
@ -712,15 +649,14 @@ public class WindowTransformSwipeHandler<T extends BaseDraggingActivity>
|
|||
final boolean passed = mCurrentShift.value >= MIN_PROGRESS_FOR_OVERVIEW;
|
||||
if (passed != mPassedOverviewThreshold) {
|
||||
mPassedOverviewThreshold = passed;
|
||||
if (mInteractionType == INTERACTION_NORMAL && mRecentsView != null
|
||||
&& !SWIPE_HOME.get()) {
|
||||
if (mRecentsView != null && !SWIPE_HOME.get()) {
|
||||
mRecentsView.performHapticFeedback(HapticFeedbackConstants.VIRTUAL_KEY,
|
||||
HapticFeedbackConstants.FLAG_IGNORE_VIEW_SETTING);
|
||||
}
|
||||
}
|
||||
// Update insets of the non-running tasks, as we might switch to them.
|
||||
int runningTaskIndex = mRecentsView == null ? -1 : mRecentsView.getRunningTaskIndex();
|
||||
if (mInteractionType == INTERACTION_NORMAL && runningTaskIndex >= 0) {
|
||||
if (runningTaskIndex >= 0) {
|
||||
for (int i = 0; i < mRecentsView.getTaskViewCount(); i++) {
|
||||
if (i != runningTaskIndex) {
|
||||
mRecentsView.getTaskViewAt(i).setFullscreenProgress(1 - mCurrentShift.value);
|
||||
|
@ -780,7 +716,7 @@ public class WindowTransformSwipeHandler<T extends BaseDraggingActivity>
|
|||
initTransitionEndpoints(dp);
|
||||
|
||||
mRecentsAnimationWrapper.setController(targetSet.controller, targetSet);
|
||||
mTouchInteractionLog.startRecentsAnimationCallback(targetSet.apps.length);
|
||||
TOUCH_INTERACTION_LOG.startRecentsAnimationCallback(targetSet.apps.length);
|
||||
setStateOnUiThread(STATE_APP_CONTROLLER_RECEIVED);
|
||||
|
||||
mPassedOverviewThreshold = false;
|
||||
|
@ -791,15 +727,14 @@ public class WindowTransformSwipeHandler<T extends BaseDraggingActivity>
|
|||
mRecentsAnimationWrapper.setController(null, null);
|
||||
mActivityInitListener.unregister();
|
||||
setStateOnUiThread(STATE_GESTURE_CANCELLED | STATE_HANDLER_INVALIDATED);
|
||||
mTouchInteractionLog.cancelRecentsAnimation();
|
||||
TOUCH_INTERACTION_LOG.cancelRecentsAnimation();
|
||||
}
|
||||
|
||||
@UiThread
|
||||
public void onGestureStarted() {
|
||||
notifyGestureStartedAsync();
|
||||
mShiftAtGestureStart = mCurrentShift.value;
|
||||
setStateOnUiThread(mInteractionType == INTERACTION_NORMAL
|
||||
? STATE_GESTURE_STARTED_QUICKSTEP : STATE_GESTURE_STARTED_QUICKSCRUB);
|
||||
setStateOnUiThread(STATE_GESTURE_STARTED);
|
||||
mGestureStarted = true;
|
||||
mRecentsAnimationWrapper.hideCurrentInputMethod();
|
||||
mRecentsAnimationWrapper.enableInputConsumer();
|
||||
|
@ -845,8 +780,7 @@ public class WindowTransformSwipeHandler<T extends BaseDraggingActivity>
|
|||
setTargetAlphaProvider(WindowTransformSwipeHandler::getHiddenTargetAlpha);
|
||||
}
|
||||
|
||||
return OverviewTouchConsumer.newInstance(mActivityControlHelper, true,
|
||||
mTouchInteractionLog);
|
||||
return OverviewTouchConsumer.newInstance(mActivityControlHelper, true);
|
||||
}
|
||||
|
||||
@UiThread
|
||||
|
@ -1114,7 +1048,7 @@ public class WindowTransformSwipeHandler<T extends BaseDraggingActivity>
|
|||
@UiThread
|
||||
private void resumeLastTask() {
|
||||
mRecentsAnimationWrapper.finish(false /* toRecents */, null);
|
||||
mTouchInteractionLog.finishRecentsAnimation(false);
|
||||
TOUCH_INTERACTION_LOG.finishRecentsAnimation(false);
|
||||
}
|
||||
|
||||
@UiThread
|
||||
|
@ -1132,16 +1066,12 @@ public class WindowTransformSwipeHandler<T extends BaseDraggingActivity>
|
|||
mMainThreadHandler);
|
||||
});
|
||||
}
|
||||
mTouchInteractionLog.finishRecentsAnimation(false);
|
||||
TOUCH_INTERACTION_LOG.finishRecentsAnimation(false);
|
||||
doLogGesture(NEW_TASK);
|
||||
}
|
||||
|
||||
public void reset() {
|
||||
if (mInteractionType != INTERACTION_QUICK_SCRUB) {
|
||||
// Only invalidate the handler if we are not quick scrubbing, otherwise, it will be
|
||||
// invalidated after the quick scrub ends
|
||||
setStateOnUiThread(STATE_HANDLER_INVALIDATED);
|
||||
}
|
||||
setStateOnUiThread(STATE_HANDLER_INVALIDATED);
|
||||
}
|
||||
|
||||
public void cancel() {
|
||||
|
@ -1171,7 +1101,6 @@ public class WindowTransformSwipeHandler<T extends BaseDraggingActivity>
|
|||
mRecentsView.setEnableFreeScroll(true);
|
||||
mRecentsView.setRunningTaskIconScaledDown(false);
|
||||
mRecentsView.setOnScrollChangeListener(null);
|
||||
mQuickScrubController.cancelActiveQuickscrub();
|
||||
}
|
||||
|
||||
private void notifyTransitionCancelled() {
|
||||
|
@ -1250,7 +1179,7 @@ public class WindowTransformSwipeHandler<T extends BaseDraggingActivity>
|
|||
() -> setStateOnUiThread(STATE_CURRENT_TASK_FINISHED));
|
||||
}
|
||||
}
|
||||
mTouchInteractionLog.finishRecentsAnimation(true);
|
||||
TOUCH_INTERACTION_LOG.finishRecentsAnimation(true);
|
||||
}
|
||||
|
||||
private void finishCurrentTransitionToHome() {
|
||||
|
@ -1258,7 +1187,7 @@ public class WindowTransformSwipeHandler<T extends BaseDraggingActivity>
|
|||
mRecentsAnimationWrapper.finish(true /* toRecents */,
|
||||
() -> setStateOnUiThread(STATE_CURRENT_TASK_FINISHED));
|
||||
}
|
||||
mTouchInteractionLog.finishRecentsAnimation(true);
|
||||
TOUCH_INTERACTION_LOG.finishRecentsAnimation(true);
|
||||
doLogGesture(HOME);
|
||||
}
|
||||
|
||||
|
@ -1279,91 +1208,6 @@ public class WindowTransformSwipeHandler<T extends BaseDraggingActivity>
|
|||
reset();
|
||||
}
|
||||
|
||||
public void onQuickScrubStart() {
|
||||
if (mInteractionType != INTERACTION_NORMAL) {
|
||||
throw new IllegalArgumentException(
|
||||
"Can't change interaction type from " + mInteractionType);
|
||||
}
|
||||
mInteractionType = INTERACTION_QUICK_SCRUB;
|
||||
mRecentsAnimationWrapper.runOnInit(this::shiftAnimationDestinationForQuickscrub);
|
||||
|
||||
setStateOnUiThread(STATE_QUICK_SCRUB_START | STATE_GESTURE_COMPLETED);
|
||||
|
||||
// Start the window animation without waiting for launcher.
|
||||
long duration = FeatureFlags.QUICK_SWITCH.get()
|
||||
? QUICK_SWITCH_FROM_APP_START_DURATION
|
||||
: QUICK_SCRUB_FROM_APP_START_DURATION;
|
||||
animateToProgress(mCurrentShift.value, 1f, duration, LINEAR, RECENTS, 1f);
|
||||
}
|
||||
|
||||
private void onQuickScrubStartUi() {
|
||||
if (!mQuickScrubController.prepareQuickScrub(TAG, FeatureFlags.QUICK_SWITCH.get())) {
|
||||
mQuickScrubBlocked = true;
|
||||
setStateOnUiThread(STATE_RESUME_LAST_TASK | STATE_HANDLER_INVALIDATED);
|
||||
return;
|
||||
}
|
||||
if (mLauncherTransitionController != null) {
|
||||
mLauncherTransitionController.getAnimationPlayer().end();
|
||||
mLauncherTransitionController = null;
|
||||
}
|
||||
|
||||
mActivityControlHelper.onQuickInteractionStart(mActivity, mRunningTaskInfo, false,
|
||||
mTouchInteractionLog);
|
||||
|
||||
// Inform the last progress in case we skipped before.
|
||||
mQuickScrubController.onQuickScrubProgress(mCurrentQuickScrubProgress);
|
||||
}
|
||||
|
||||
private void onFinishedTransitionToQuickScrub() {
|
||||
if (mQuickScrubBlocked) {
|
||||
return;
|
||||
}
|
||||
mLayoutListener.finish();
|
||||
mQuickScrubController.onFinishedTransitionToQuickScrub();
|
||||
|
||||
mRecentsView.animateUpRunningTaskIconScale();
|
||||
if (mQuickScrubController.isQuickSwitch()) {
|
||||
// Adjust the running task so that it is centered and fills the screen.
|
||||
TaskView runningTask = mRecentsView.getRunningTaskView();
|
||||
if (runningTask != null) {
|
||||
float insetHeight = mDp.heightPx - mDp.getInsets().top - mDp.getInsets().bottom;
|
||||
// Usually insetDiff will be 0, unless we allow apps to draw under the insets. In
|
||||
// that case (insetDiff != 0), we need to center in the system-specified available
|
||||
// height rather than launcher's inset height by adding half the insetDiff.
|
||||
float insetDiff = mDp.availableHeightPx - insetHeight;
|
||||
float topMargin = mActivity.getResources().getDimension(
|
||||
R.dimen.task_thumbnail_half_top_margin);
|
||||
runningTask.setTranslationY((insetDiff / 2 - topMargin) / mRecentsView.getScaleX());
|
||||
}
|
||||
}
|
||||
RecentsModel.INSTANCE.get(mContext).onOverviewShown(false, TAG);
|
||||
}
|
||||
|
||||
public void onQuickScrubProgress(float progress) {
|
||||
mCurrentQuickScrubProgress = progress;
|
||||
if (mQuickScrubController == null || mQuickScrubBlocked ||
|
||||
!mStateCallback.hasStates(QUICK_SCRUB_START_UI_STATE)) {
|
||||
return;
|
||||
}
|
||||
mQuickScrubController.onQuickScrubProgress(progress);
|
||||
}
|
||||
|
||||
public void onQuickScrubEnd() {
|
||||
setStateOnUiThread(STATE_QUICK_SCRUB_END);
|
||||
}
|
||||
|
||||
private void switchToFinalAppAfterQuickScrub() {
|
||||
if (mQuickScrubBlocked) {
|
||||
return;
|
||||
}
|
||||
mQuickScrubController.onQuickScrubEnd();
|
||||
|
||||
// Normally this is handled in reset(), but since we are still scrubbing after the
|
||||
// transition into recents, we need to defer the handler invalidation for quick scrub until
|
||||
// after the gesture ends
|
||||
setStateOnUiThread(STATE_HANDLER_INVALIDATED);
|
||||
}
|
||||
|
||||
public void setGestureEndCallback(Runnable gestureEndCallback) {
|
||||
mGestureEndCallback = gestureEndCallback;
|
||||
}
|
||||
|
|
|
@ -35,7 +35,6 @@ public class FallbackRecentsView extends RecentsView<RecentsActivity> {
|
|||
public FallbackRecentsView(Context context, AttributeSet attrs, int defStyleAttr) {
|
||||
super(context, attrs, defStyleAttr);
|
||||
setOverviewStateEnabled(true);
|
||||
getQuickScrubController().onFinishedTransitionToQuickScrub();
|
||||
}
|
||||
|
||||
@Override
|
||||
|
|
|
@ -15,9 +15,7 @@
|
|||
*/
|
||||
package com.android.quickstep.util;
|
||||
|
||||
import static com.android.launcher3.anim.Interpolators.LINEAR;
|
||||
import static com.android.launcher3.config.FeatureFlags.ENABLE_QUICKSTEP_LIVE_TILE;
|
||||
import static com.android.quickstep.QuickScrubController.QUICK_SCRUB_TRANSLATION_Y_FACTOR;
|
||||
import static com.android.systemui.shared.system.RemoteAnimationTargetCompat.MODE_CLOSING;
|
||||
import static com.android.systemui.shared.system.RemoteAnimationTargetCompat.MODE_OPENING;
|
||||
|
||||
|
@ -26,19 +24,15 @@ import android.content.Context;
|
|||
import android.graphics.Canvas;
|
||||
import android.graphics.Matrix;
|
||||
import android.graphics.Matrix.ScaleToFit;
|
||||
import android.graphics.PointF;
|
||||
import android.graphics.Rect;
|
||||
import android.graphics.RectF;
|
||||
import android.os.Build;
|
||||
import android.os.RemoteException;
|
||||
import android.view.animation.Interpolator;
|
||||
import androidx.annotation.Nullable;
|
||||
|
||||
import com.android.launcher3.BaseDraggingActivity;
|
||||
import com.android.launcher3.DeviceProfile;
|
||||
import com.android.launcher3.R;
|
||||
import com.android.launcher3.Utilities;
|
||||
import com.android.launcher3.anim.Interpolators;
|
||||
import com.android.launcher3.views.BaseDragLayer;
|
||||
import com.android.quickstep.RecentsModel;
|
||||
import com.android.quickstep.views.RecentsView;
|
||||
|
@ -53,6 +47,8 @@ import com.android.systemui.shared.system.WindowManagerWrapper;
|
|||
|
||||
import java.util.function.BiFunction;
|
||||
|
||||
import androidx.annotation.Nullable;
|
||||
|
||||
/**
|
||||
* Utility class to handle window clip animation
|
||||
*/
|
||||
|
@ -67,8 +63,6 @@ public class ClipAnimationHelper {
|
|||
private final RectF mSourceRect = new RectF();
|
||||
// The bounds of the task view in launcher window coordinates
|
||||
private final RectF mTargetRect = new RectF();
|
||||
// Set when the final window destination is changed, such as offsetting for quick scrub
|
||||
private final PointF mTargetOffset = new PointF();
|
||||
// The insets to be used for clipping the app window, which can be larger than mSourceInsets
|
||||
// if the aspect ratio of the target is smaller than the aspect ratio of the source rect. In
|
||||
// app window coordinates.
|
||||
|
@ -95,11 +89,6 @@ public class ClipAnimationHelper {
|
|||
|
||||
// Corner radius currently applied to transformed window.
|
||||
private float mCurrentCornerRadius;
|
||||
private float mTargetScale = 1f;
|
||||
private float mOffsetScale = 1f;
|
||||
private Interpolator mInterpolator = LINEAR;
|
||||
// We translate y slightly faster than the rest of the animation for quick scrub.
|
||||
private Interpolator mOffsetYInterpolator = LINEAR;
|
||||
|
||||
// Whether to boost the opening animation target layers, or the closing
|
||||
private int mBoostModeTargetLayers = -1;
|
||||
|
@ -130,13 +119,11 @@ public class ClipAnimationHelper {
|
|||
updateSourceStack(target);
|
||||
}
|
||||
|
||||
public void updateTargetRect(TransformedRect targetRect) {
|
||||
mOffsetScale = targetRect.scale;
|
||||
public void updateTargetRect(Rect targetRect) {
|
||||
mSourceRect.set(mSourceInsets.left, mSourceInsets.top,
|
||||
mSourceStackBounds.width() - mSourceInsets.right,
|
||||
mSourceStackBounds.height() - mSourceInsets.bottom);
|
||||
mTargetRect.set(targetRect.rect);
|
||||
Utilities.scaleRectFAboutCenter(mTargetRect, targetRect.scale);
|
||||
mTargetRect.set(targetRect);
|
||||
mTargetRect.offset(mHomeStackBounds.left - mSourceStackBounds.left,
|
||||
mHomeStackBounds.top - mSourceStackBounds.top);
|
||||
|
||||
|
@ -165,18 +152,11 @@ public class ClipAnimationHelper {
|
|||
if (params.currentRect == null) {
|
||||
RectF currentRect;
|
||||
mTmpRectF.set(mTargetRect);
|
||||
Utilities.scaleRectFAboutCenter(mTmpRectF, mTargetScale * params.offsetScale);
|
||||
float offsetYProgress = mOffsetYInterpolator.getInterpolation(params.progress);
|
||||
float progress = mInterpolator.getInterpolation(params.progress);
|
||||
Utilities.scaleRectFAboutCenter(mTmpRectF, params.offsetScale);
|
||||
float progress = params.progress;
|
||||
currentRect = mRectFEvaluator.evaluate(progress, mSourceRect, mTmpRectF);
|
||||
currentRect.offset(params.offsetX, 0);
|
||||
|
||||
synchronized (mTargetOffset) {
|
||||
// Stay lined up with the center of the target, since it moves for quick scrub.
|
||||
currentRect.offset(mTargetOffset.x * mOffsetScale * progress,
|
||||
mTargetOffset.y * offsetYProgress);
|
||||
}
|
||||
|
||||
final RectF sourceWindowClipInsets = params.forLiveTile
|
||||
? mSourceWindowClipInsetsForLiveTile : mSourceWindowClipInsets;
|
||||
mClipRectF.left = sourceWindowClipInsets.left * progress;
|
||||
|
@ -246,16 +226,6 @@ public class ClipAnimationHelper {
|
|||
mTaskAlphaCallback = callback;
|
||||
}
|
||||
|
||||
public void offsetTarget(float scale, float offsetX, float offsetY, Interpolator interpolator) {
|
||||
synchronized (mTargetOffset) {
|
||||
mTargetOffset.set(offsetX, offsetY);
|
||||
}
|
||||
mTargetScale = scale;
|
||||
mInterpolator = interpolator;
|
||||
mOffsetYInterpolator = Interpolators.clampToProgress(mInterpolator, 0,
|
||||
QUICK_SCRUB_TRANSLATION_Y_FACTOR);
|
||||
}
|
||||
|
||||
public void fromTaskThumbnailView(TaskThumbnailView ttv, RecentsView rv) {
|
||||
fromTaskThumbnailView(ttv, rv, null);
|
||||
}
|
||||
|
@ -280,8 +250,8 @@ public class ClipAnimationHelper {
|
|||
mSourceInsets.set(ttv.getInsets(fallback));
|
||||
}
|
||||
|
||||
TransformedRect targetRect = new TransformedRect();
|
||||
dl.getDescendantRectRelativeToSelf(ttv, targetRect.rect);
|
||||
Rect targetRect = new Rect();
|
||||
dl.getDescendantRectRelativeToSelf(ttv, targetRect);
|
||||
updateTargetRect(targetRect);
|
||||
|
||||
if (target == null) {
|
||||
|
|
|
@ -1,32 +0,0 @@
|
|||
/*
|
||||
* Copyright (C) 2018 The Android Open Source Project
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
package com.android.quickstep.util;
|
||||
|
||||
import android.graphics.Rect;
|
||||
|
||||
/**
|
||||
* A wrapper around {@link Rect} with additional transformation properties
|
||||
*/
|
||||
public class TransformedRect {
|
||||
|
||||
public final Rect rect = new Rect();
|
||||
public float scale = 1;
|
||||
|
||||
public void set(TransformedRect transformedRect) {
|
||||
rect.set(transformedRect.rect);
|
||||
scale = transformedRect.scale;
|
||||
}
|
||||
}
|
|
@ -88,7 +88,6 @@ import com.android.launcher3.util.PendingAnimation;
|
|||
import com.android.launcher3.util.Themes;
|
||||
import com.android.launcher3.util.ViewPool;
|
||||
import com.android.quickstep.OverviewCallbacks;
|
||||
import com.android.quickstep.QuickScrubController;
|
||||
import com.android.quickstep.RecentsAnimationWrapper;
|
||||
import com.android.quickstep.RecentsModel;
|
||||
import com.android.quickstep.TaskThumbnailCache;
|
||||
|
@ -152,7 +151,6 @@ public abstract class RecentsView<T extends BaseActivity> extends PagedView impl
|
|||
private static final float[] sTempFloatArray = new float[3];
|
||||
|
||||
protected final T mActivity;
|
||||
private final QuickScrubController mQuickScrubController;
|
||||
private final float mFastFlingVelocity;
|
||||
private final RecentsModel mModel;
|
||||
private final int mTaskTopMargin;
|
||||
|
@ -215,9 +213,6 @@ public abstract class RecentsView<T extends BaseActivity> extends PagedView impl
|
|||
return;
|
||||
}
|
||||
|
||||
// Notify the quick scrub controller that a particular task has been removed
|
||||
mQuickScrubController.onTaskRemoved(taskId);
|
||||
|
||||
BackgroundExecutor.get().submit(() -> {
|
||||
TaskView taskView = getTaskView(taskId);
|
||||
if (taskView == null) {
|
||||
|
@ -310,7 +305,6 @@ public abstract class RecentsView<T extends BaseActivity> extends PagedView impl
|
|||
mFastFlingVelocity = getResources()
|
||||
.getDimensionPixelSize(R.dimen.recents_fast_fling_velocity);
|
||||
mActivity = (T) BaseActivity.fromContext(context);
|
||||
mQuickScrubController = new QuickScrubController(mActivity, this);
|
||||
mModel = RecentsModel.INSTANCE.get(context);
|
||||
mIdp = InvariantDeviceProfile.INSTANCE.get(context);
|
||||
|
||||
|
@ -550,10 +544,6 @@ public abstract class RecentsView<T extends BaseActivity> extends PagedView impl
|
|||
mIgnoreResetTaskId = -1;
|
||||
}
|
||||
resetTaskVisuals();
|
||||
|
||||
if (oldChildCount != getChildCount()) {
|
||||
mQuickScrubController.snapToNextTaskIfAvailable();
|
||||
}
|
||||
onTaskStackUpdated();
|
||||
}
|
||||
|
||||
|
@ -605,7 +595,6 @@ public abstract class RecentsView<T extends BaseActivity> extends PagedView impl
|
|||
mTaskWidth = mTempRect.width();
|
||||
mTaskHeight = mTempRect.height();
|
||||
|
||||
// Keep this logic in sync with ActivityControlHelper.getTranslationYForQuickScrub.
|
||||
mTempRect.top -= mTaskTopMargin;
|
||||
setPadding(mTempRect.left - mInsets.left, mTempRect.top - mInsets.top,
|
||||
dp.widthPx - mInsets.right - mTempRect.right,
|
||||
|
@ -854,10 +843,6 @@ public abstract class RecentsView<T extends BaseActivity> extends PagedView impl
|
|||
}
|
||||
}
|
||||
|
||||
public QuickScrubController getQuickScrubController() {
|
||||
return mQuickScrubController;
|
||||
}
|
||||
|
||||
public void setRunningTaskIconScaledDown(boolean isScaledDown) {
|
||||
if (mRunningTaskIconScaledDown != isScaledDown) {
|
||||
mRunningTaskIconScaledDown = isScaledDown;
|
||||
|
|
|
@ -412,10 +412,7 @@ public class TaskView extends FrameLayout implements PageCallbacks, Reusable {
|
|||
|
||||
public void resetVisualProperties() {
|
||||
resetViewTransforms();
|
||||
if (!getRecentsView().getQuickScrubController().isQuickSwitch()) {
|
||||
// Reset full screen progress unless we are doing back to back quick switch.
|
||||
setFullscreenProgress(0);
|
||||
}
|
||||
setFullscreenProgress(0);
|
||||
}
|
||||
|
||||
@Override
|
||||
|
|
|
@ -27,7 +27,6 @@ import android.view.animation.Interpolator;
|
|||
import com.android.launcher3.states.SpringLoadedState;
|
||||
import com.android.launcher3.uioverrides.AllAppsState;
|
||||
import com.android.launcher3.uioverrides.BackgroundAppState;
|
||||
import com.android.launcher3.uioverrides.FastOverviewState;
|
||||
import com.android.launcher3.uioverrides.OverviewState;
|
||||
import com.android.launcher3.uioverrides.UiFactory;
|
||||
import com.android.launcher3.userevent.nano.LauncherLogProto.Action;
|
||||
|
@ -87,9 +86,8 @@ public class LauncherState {
|
|||
*/
|
||||
public static final LauncherState SPRING_LOADED = new SpringLoadedState(1);
|
||||
public static final LauncherState OVERVIEW = new OverviewState(2);
|
||||
public static final LauncherState FAST_OVERVIEW = new FastOverviewState(3);
|
||||
public static final LauncherState ALL_APPS = new AllAppsState(4);
|
||||
public static final LauncherState BACKGROUND_APP = new BackgroundAppState(5);
|
||||
public static final LauncherState ALL_APPS = new AllAppsState(3);
|
||||
public static final LauncherState BACKGROUND_APP = new BackgroundAppState(4);
|
||||
|
||||
public final int ordinal;
|
||||
|
||||
|
@ -187,6 +185,7 @@ public class LauncherState {
|
|||
* translationY factor where 0 is top aligned and 0.5 is centered vertically
|
||||
*/
|
||||
public float[] getOverviewScaleAndTranslationYFactor(Launcher launcher) {
|
||||
// TODO: Simplify to use a constant value instead of a factor.
|
||||
return new float[] {1.1f, 0f};
|
||||
}
|
||||
|
||||
|
|
|
@ -1,26 +0,0 @@
|
|||
/*
|
||||
* Copyright (C) 2018 The Android Open Source Project
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
package com.android.launcher3.uioverrides;
|
||||
|
||||
/**
|
||||
* A dummy overview state
|
||||
*/
|
||||
public class FastOverviewState extends OverviewState {
|
||||
|
||||
public FastOverviewState(int id) {
|
||||
super(id);
|
||||
}
|
||||
}
|
Loading…
Reference in New Issue