Adding support for swipe operation when on home screen

Bug: 137197916
Change-Id: Ic85bf9767d4a9a77dafc1c60c02555f3d2a5d8a2
This commit is contained in:
Sunny Goyal
2019-07-12 14:19:18 -07:00
parent 587c3cef51
commit 365f29e577
6 changed files with 104 additions and 27 deletions
@@ -70,7 +70,7 @@ import androidx.annotation.UiThread;
* Base class for swipe up handler with some utility methods
*/
@TargetApi(Build.VERSION_CODES.Q)
public abstract class BaseSwipeUpHandler<T extends BaseDraggingActivity>
public abstract class BaseSwipeUpHandler<T extends BaseDraggingActivity, Q extends RecentsView>
implements SwipeAnimationListener {
private static final String TAG = "BaseSwipeUpHandler";
@@ -109,7 +109,7 @@ public abstract class BaseSwipeUpHandler<T extends BaseDraggingActivity>
protected final RecentsAnimationWrapper mRecentsAnimationWrapper;
protected T mActivity;
protected RecentsView mRecentsView;
protected Q mRecentsView;
protected DeviceProfile mDp;
private final int mPageSpacing;
@@ -86,6 +86,7 @@ import com.android.quickstep.util.RectFSpringAnim;
import com.android.quickstep.util.RemoteAnimationTargetSet;
import com.android.quickstep.util.SwipeAnimationTargetSet;
import com.android.quickstep.views.LiveTileOverlay;
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.system.InputConsumerController;
@@ -98,7 +99,7 @@ import androidx.annotation.UiThread;
@TargetApi(Build.VERSION_CODES.O)
public class WindowTransformSwipeHandler<T extends BaseDraggingActivity>
extends BaseSwipeUpHandler<T>
extends BaseSwipeUpHandler<T, RecentsView>
implements OnApplyWindowInsetsListener {
private static final String TAG = WindowTransformSwipeHandler.class.getSimpleName();
@@ -17,6 +17,7 @@ package com.android.quickstep.fallback;
import static com.android.launcher3.LauncherAnimUtils.SCALE_PROPERTY;
import android.app.ActivityManager.RunningTaskInfo;
import android.content.Context;
import android.graphics.Canvas;
import android.graphics.Rect;
@@ -31,6 +32,10 @@ import com.android.quickstep.RecentsActivity;
import com.android.quickstep.util.LayoutUtils;
import com.android.quickstep.views.RecentsView;
import com.android.quickstep.views.TaskView;
import com.android.systemui.shared.recents.model.Task;
import com.android.systemui.shared.recents.model.Task.TaskKey;
import java.util.ArrayList;
public class FallbackRecentsView extends RecentsView<RecentsActivity> {
@@ -54,6 +59,8 @@ public class FallbackRecentsView extends RecentsView<RecentsActivity> {
private float mZoomScale = 1f;
private float mZoomTranslationY = 0f;
private RunningTaskInfo mRunningTaskInfo;
public FallbackRecentsView(Context context, AttributeSet attrs) {
this(context, attrs, 0);
}
@@ -151,4 +158,41 @@ public class FallbackRecentsView extends RecentsView<RecentsActivity> {
TRANSLATION_Y.set(this, Utilities.mapRange(mZoomInProgress, 0, mZoomTranslationY));
FULLSCREEN_PROGRESS.set(this, mZoomInProgress);
}
public void onGestureAnimationStart(RunningTaskInfo runningTaskInfo) {
mRunningTaskInfo = runningTaskInfo;
onGestureAnimationStart(runningTaskInfo == null ? -1 : runningTaskInfo.taskId);
}
@Override
public void setCurrentTask(int runningTaskId) {
super.setCurrentTask(runningTaskId);
if (mRunningTaskInfo != null && mRunningTaskInfo.taskId != runningTaskId) {
mRunningTaskInfo = null;
}
}
@Override
protected void applyLoadPlan(ArrayList<Task> tasks) {
// When quick-switching on 3p-launcher, we add a "dummy" tile corresponding to Launcher
// as well. This tile is never shown as we have setCurrentTaskHidden, but allows use to
// track the index of the next task appropriately, as it we are switching on any other app.
if (mRunningTaskInfo != null && mRunningTaskInfo.taskId == mRunningTaskId) {
// Check if the task list has running task
boolean found = false;
for (Task t : tasks) {
if (t.key.id == mRunningTaskId) {
found = true;
break;
}
}
if (!found) {
ArrayList<Task> newList = new ArrayList<>(tasks.size() + 1);
newList.addAll(tasks);
newList.add(Task.from(new TaskKey(mRunningTaskInfo), mRunningTaskInfo, false));
tasks = newList;
}
}
super.applyLoadPlan(tasks);
}
}
@@ -47,10 +47,12 @@ import com.android.quickstep.util.ObjectWrapper;
import com.android.quickstep.util.SwipeAnimationTargetSet;
import com.android.quickstep.views.TaskView;
import com.android.systemui.shared.recents.model.ThumbnailData;
import com.android.systemui.shared.system.ActivityManagerWrapper;
import com.android.systemui.shared.system.ActivityOptionsCompat;
import com.android.systemui.shared.system.InputConsumerController;
public class FallbackNoButtonInputConsumer extends BaseSwipeUpHandler<RecentsActivity> {
public class FallbackNoButtonInputConsumer extends
BaseSwipeUpHandler<RecentsActivity, FallbackRecentsView> {
private static final String[] STATE_NAMES = DEBUG_STATES ? new String[5] : null;
@@ -97,6 +99,11 @@ public class FallbackNoButtonInputConsumer extends BaseSwipeUpHandler<RecentsAct
private final boolean mInQuickSwitchMode;
private final boolean mContinuingLastGesture;
private final boolean mRunningOverHome;
private final boolean mSwipeUpOverHome;
private final RunningTaskInfo mRunningTaskInfo;
private Animator mFinishAnimation;
@@ -108,9 +115,18 @@ public class FallbackNoButtonInputConsumer extends BaseSwipeUpHandler<RecentsAct
super(context, overviewComponentObserver, recentsModel, inputConsumer, runningTaskInfo.id);
mLauncherAlpha.value = 1;
mRunningTaskInfo = runningTaskInfo;
mInQuickSwitchMode = isLikelyToStartNewTask || continuingLastGesture;
mContinuingLastGesture = continuingLastGesture;
mClipAnimationHelper.setBaseAlphaCallback((t, a) -> mLauncherAlpha.value);
mRunningOverHome = ActivityManagerWrapper.isHomeTask(runningTaskInfo);
mSwipeUpOverHome = mRunningOverHome && !mInQuickSwitchMode;
if (mSwipeUpOverHome) {
mClipAnimationHelper.setBaseAlphaCallback((t, a) -> 1 - mLauncherAlpha.value);
} else {
mClipAnimationHelper.setBaseAlphaCallback((t, a) -> mLauncherAlpha.value);
}
initStateCallbacks();
}
@@ -149,10 +165,14 @@ public class FallbackNoButtonInputConsumer extends BaseSwipeUpHandler<RecentsAct
mRecentsView.setDisallowScrollToClearAll(true);
mRecentsView.getClearAllButton().setVisibilityAlpha(0);
((FallbackRecentsView) mRecentsView).setZoomProgress(1);
mRecentsView.setZoomProgress(1);
if (!mContinuingLastGesture) {
mRecentsView.onGestureAnimationStart(mRunningTaskId);
if (mRunningOverHome) {
mRecentsView.onGestureAnimationStart(mRunningTaskInfo);
} else {
mRecentsView.onGestureAnimationStart(mRunningTaskId);
}
}
setStateOnUiThread(STATE_RECENTS_PRESENT);
return true;
@@ -196,7 +216,7 @@ public class FallbackNoButtonInputConsumer extends BaseSwipeUpHandler<RecentsAct
@Override
public Intent getLaunchIntent() {
if (mInQuickSwitchMode) {
if (mInQuickSwitchMode || mSwipeUpOverHome) {
return mOverviewComponentObserver.getOverviewIntent();
} else {
return mOverviewComponentObserver.getHomeIntent();
@@ -282,16 +302,27 @@ public class FallbackNoButtonInputConsumer extends BaseSwipeUpHandler<RecentsAct
mRecentsView.getClearAllButton().setVisibilityAlpha(1);
}
private void finishAnimationTargetSetAnimationComplete() {
switch (mEndTarget) {
case HOME:
mRecentsAnimationWrapper.finish(true, null, true);
case HOME: {
if (mSwipeUpOverHome) {
mRecentsAnimationWrapper.finish(false, null, false);
// Send a home intent to clear the task stack
mContext.startActivity(mOverviewComponentObserver.getHomeIntent());
} else {
mRecentsAnimationWrapper.finish(true, null, true);
}
break;
}
case LAST_TASK:
mRecentsAnimationWrapper.finish(false, null, false);
break;
case RECENTS: {
if (mSwipeUpOverHome) {
mRecentsAnimationWrapper.finish(true, null, true);
break;
}
ThumbnailData thumbnail =
mRecentsAnimationWrapper.targetSet.controller.screenshotTask(mRunningTaskId);
mRecentsAnimationWrapper.setCancelWithDeferredScreenshot(true);
@@ -367,6 +398,10 @@ public class FallbackNoButtonInputConsumer extends BaseSwipeUpHandler<RecentsAct
public void onRecentsAnimationStart(SwipeAnimationTargetSet targetSet) {
super.onRecentsAnimationStart(targetSet);
mRecentsAnimationWrapper.enableInputConsumer();
if (mRunningOverHome) {
mClipAnimationHelper.prepareAnimation(mDp, true);
}
applyTransformUnchecked();
setStateOnUiThread(STATE_APP_CONTROLLER_RECEIVED);
@@ -269,7 +269,7 @@ public abstract class RecentsView<T extends BaseActivity> extends PagedView impl
private int mTaskListChangeId = -1;
// Only valid until the launcher state changes to NORMAL
private int mRunningTaskId = -1;
protected int mRunningTaskId = -1;
private boolean mRunningTaskTileHidden;
private Task mTmpRunningTask;
@@ -532,7 +532,7 @@ public abstract class RecentsView<T extends BaseActivity> extends PagedView impl
return true;
}
private void applyLoadPlan(ArrayList<Task> tasks) {
protected void applyLoadPlan(ArrayList<Task> tasks) {
if (mPendingAnimation != null) {
mPendingAnimation.addEndListener((onEndListener) -> applyLoadPlan(tasks));
return;
@@ -855,12 +855,14 @@ public abstract class RecentsView<T extends BaseActivity> extends PagedView impl
* is called. Also scrolls the view to this task.
*/
public void showCurrentTask(int runningTaskId) {
if (getChildCount() == 0) {
if (getTaskView(runningTaskId) == null) {
boolean wasEmpty = getChildCount() == 0;
// Add an empty view for now until the task plan is loaded and applied
final TaskView taskView = mTaskViewPool.getView();
addView(taskView);
addView(mClearAllButton);
addView(taskView, 0);
if (wasEmpty) {
addView(mClearAllButton);
}
// The temporary running task is only used for the duration between the start of the
// gesture and the task list is loaded and applied
mTmpRunningTask = new Task(new Task.TaskKey(runningTaskId, 0, new Intent(),
@@ -28,8 +28,6 @@ import com.android.launcher3.MainThreadExecutor;
import com.android.systemui.shared.recents.model.Task;
import com.android.systemui.shared.system.ActivityManagerWrapper;
import com.android.systemui.shared.system.KeyguardManagerCompat;
import com.android.systemui.shared.system.RecentTaskInfoCompat;
import com.android.systemui.shared.system.TaskDescriptionCompat;
import com.android.systemui.shared.system.TaskStackChangeListener;
import java.util.ArrayList;
import java.util.Collections;
@@ -86,8 +84,9 @@ public class RecentTasksList extends TaskStackChangeListener {
: () -> callback.accept(copyOf(mTasks));
if (mLastLoadedId == mChangeId && (!mLastLoadHadKeysOnly || loadKeysOnly)) {
// The list is up to date, callback with the same list
mMainThreadExecutor.execute(resultCallback);
// The list is up to date, send the callback on the next frame,
// so that requestID can be returned first.
mMainThreadExecutor.getHandler().post(resultCallback);
return requestLoadId;
}
@@ -165,15 +164,11 @@ public class RecentTasksList extends TaskStackChangeListener {
int taskCount = rawTasks.size();
for (int i = 0; i < taskCount; i++) {
ActivityManager.RecentTaskInfo rawTask = rawTasks.get(i);
RecentTaskInfoCompat t = new RecentTaskInfoCompat(rawTask);
Task.TaskKey taskKey = new Task.TaskKey(rawTask);
Task task;
if (!loadKeysOnly) {
ActivityManager.TaskDescription rawTd = t.getTaskDescription();
TaskDescriptionCompat td = new TaskDescriptionCompat(rawTd);
boolean isLocked = tmpLockedUsers.get(t.getUserId());
task = new Task(taskKey, td.getPrimaryColor(), td.getBackgroundColor(),
t.supportsSplitScreenMultiWindow(), isLocked, rawTd, t.getTopActivity());
boolean isLocked = tmpLockedUsers.get(taskKey.userId);
task = Task.from(taskKey, rawTask, isLocked);
} else {
task = new Task(taskKey);
}