Deleting Quickscrub related logic

Bug: 124255113
Change-Id: Ic5f2338f1e3ae0a0cfb08f822dee0e01ae54a7b0
This commit is contained in:
Sunny Goyal 2019-02-13 14:57:52 -08:00
parent 435041de60
commit 3f271d4b7f
30 changed files with 244 additions and 1659 deletions

View File

@ -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) {

View File

@ -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);
}
}

View File

@ -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.

View File

@ -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) {

View File

@ -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();

View File

@ -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();
}
}

View File

@ -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;

View File

@ -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());

View File

@ -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.
*

View File

@ -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);
}

View File

@ -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() { }

View File

@ -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 */);

View File

@ -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

View File

@ -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);
}
}

View File

@ -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 "

View File

@ -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();

View File

@ -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;

View File

@ -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);
}
}

View File

@ -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);
}
}
}

View File

@ -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;
}

View File

@ -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) {

View File

@ -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);
}
}

View File

@ -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;
}

View File

@ -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

View File

@ -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) {

View File

@ -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;
}
}

View File

@ -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;

View File

@ -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

View File

@ -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};
}

View File

@ -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);
}
}