summaryrefslogtreecommitdiffstats
path: root/quickstep
diff options
context:
space:
mode:
authorTony <twickham@google.com>2017-12-22 17:33:02 -0800
committerTony <twickham@google.com>2018-01-11 17:20:35 -0800
commit6d6fe041c75e83e795b7dec3ce2a87139eee4368 (patch)
tree1b6bd0c9d01b98e5fd361ac30781e92392b51b1f /quickstep
parent1a52ef57c72291a87d4ca6bb1e752fd746646991 (diff)
downloadandroid_packages_apps_Trebuchet-6d6fe041c75e83e795b7dec3ce2a87139eee4368.tar.gz
android_packages_apps_Trebuchet-6d6fe041c75e83e795b7dec3ce2a87139eee4368.tar.bz2
android_packages_apps_Trebuchet-6d6fe041c75e83e795b7dec3ce2a87139eee4368.zip
Implement quick scrub and quick switch callbacks
Bug: 70180755 Change-Id: I011dd5b0435cea7ba493e83b973ce5be7d18c1f0
Diffstat (limited to 'quickstep')
-rw-r--r--quickstep/libs/sysui_shared.jarbin93195 -> 94484 bytes
-rw-r--r--quickstep/src/com/android/launcher3/uioverrides/RecentsViewStateController.java6
-rw-r--r--quickstep/src/com/android/launcher3/uioverrides/WorkspaceCard.java3
-rw-r--r--quickstep/src/com/android/quickstep/NavBarSwipeInteractionHandler.java61
-rw-r--r--quickstep/src/com/android/quickstep/QuickScrubController.java111
-rw-r--r--quickstep/src/com/android/quickstep/RecentsView.java15
-rw-r--r--quickstep/src/com/android/quickstep/TouchInteractionService.java44
7 files changed, 225 insertions, 15 deletions
diff --git a/quickstep/libs/sysui_shared.jar b/quickstep/libs/sysui_shared.jar
index 906969826..b3025ff98 100644
--- a/quickstep/libs/sysui_shared.jar
+++ b/quickstep/libs/sysui_shared.jar
Binary files differ
diff --git a/quickstep/src/com/android/launcher3/uioverrides/RecentsViewStateController.java b/quickstep/src/com/android/launcher3/uioverrides/RecentsViewStateController.java
index d657e4e19..146582238 100644
--- a/quickstep/src/com/android/launcher3/uioverrides/RecentsViewStateController.java
+++ b/quickstep/src/com/android/launcher3/uioverrides/RecentsViewStateController.java
@@ -15,6 +15,9 @@
*/
package com.android.launcher3.uioverrides;
+import static com.android.launcher3.LauncherState.NORMAL;
+import static com.android.launcher3.LauncherState.OVERVIEW;
+
import android.animation.Animator;
import android.animation.AnimatorListenerAdapter;
import android.animation.ObjectAnimator;
@@ -31,9 +34,6 @@ import com.android.launcher3.anim.Interpolators;
import com.android.quickstep.AnimatedFloat;
import com.android.quickstep.RecentsView;
-import static com.android.launcher3.LauncherState.NORMAL;
-import static com.android.launcher3.LauncherState.OVERVIEW;
-
public class RecentsViewStateController implements StateHandler {
private final Launcher mLauncher;
diff --git a/quickstep/src/com/android/launcher3/uioverrides/WorkspaceCard.java b/quickstep/src/com/android/launcher3/uioverrides/WorkspaceCard.java
index ed60b84e1..4816e2a24 100644
--- a/quickstep/src/com/android/launcher3/uioverrides/WorkspaceCard.java
+++ b/quickstep/src/com/android/launcher3/uioverrides/WorkspaceCard.java
@@ -77,6 +77,7 @@ public class WorkspaceCard extends FrameLayout implements PageCallbacks, OnClick
mWorkspaceClickTarget.setOnClickListener(this);
mWidgetsButton.setOnClickListener(this);
+ setOnClickListener(this);
}
@Override
@@ -168,7 +169,7 @@ public class WorkspaceCard extends FrameLayout implements PageCallbacks, OnClick
@Override
public void onClick(View view) {
- if (view == mWorkspaceClickTarget) {
+ if (view == mWorkspaceClickTarget || view == this) {
mLauncher.getStateManager().goToState(NORMAL);
} else if (view == mWidgetsButton) {
WidgetsFullSheet.show(mLauncher, true);
diff --git a/quickstep/src/com/android/quickstep/NavBarSwipeInteractionHandler.java b/quickstep/src/com/android/quickstep/NavBarSwipeInteractionHandler.java
index 2e251d1f6..ce528e38a 100644
--- a/quickstep/src/com/android/quickstep/NavBarSwipeInteractionHandler.java
+++ b/quickstep/src/com/android/quickstep/NavBarSwipeInteractionHandler.java
@@ -67,6 +67,7 @@ public class NavBarSwipeInteractionHandler extends InternalStateHandler {
private static final long RECENTS_VIEW_VISIBILITY_DURATION = 150;
private static final long MAX_SWIPE_DURATION = 200;
private static final long MIN_SWIPE_DURATION = 80;
+ private static final int QUICK_SWITCH_SNAP_DURATION = 120;
// Ideal velocity for a smooth transition
private static final float PIXEL_PER_MS = 2f;
@@ -98,6 +99,7 @@ public class NavBarSwipeInteractionHandler extends InternalStateHandler {
private SnapshotDragView mDragView;
private RecentsView mRecentsView;
private RecentsViewStateController mStateController;
+ private QuickScrubController mQuickScrubController;
private Hotseat mHotseat;
private AllAppsScrim mAllAppsScrim;
private RecentsTaskLoadPlan mLoadPlan;
@@ -105,12 +107,16 @@ public class NavBarSwipeInteractionHandler extends InternalStateHandler {
private boolean mLauncherReady;
private boolean mTouchEndHandled;
private float mCurrentDisplacement;
+ private @TouchInteractionService.InteractionType int mInteractionType;
+ private boolean mStartedQuickScrubFromHome;
private Bitmap mTaskSnapshot;
- NavBarSwipeInteractionHandler(RunningTaskInfo runningTaskInfo, Context context) {
+ NavBarSwipeInteractionHandler(RunningTaskInfo runningTaskInfo, Context context,
+ @TouchInteractionService.InteractionType int interactionType) {
mRunningTaskId = runningTaskInfo.id;
mContext = context;
+ mInteractionType = interactionType;
WindowManagerWrapper.getInstance().getStableInsets(mStableInsets);
DeviceProfile dp = LauncherAppState.getIDP(mContext).getDeviceProfile(mContext);
@@ -191,11 +197,24 @@ public class NavBarSwipeInteractionHandler extends InternalStateHandler {
mLauncher.getDragLayer().addView(mDragView);
mDragView.setPivotX(0);
mDragView.setPivotY(0);
- mRecentsView = mLauncher.getOverviewPanel();
+ mRecentsView = launcher.getOverviewPanel();
mStateController = mRecentsView.getStateController();
mHotseat = mLauncher.getHotseat();
mAllAppsScrim = mLauncher.findViewById(R.id.all_apps_scrim);
+ boolean interactionIsQuick
+ = mInteractionType == TouchInteractionService.INTERACTION_QUICK_SCRUB
+ || mInteractionType == TouchInteractionService.INTERACTION_QUICK_SWITCH;
+ mStartedQuickScrubFromHome = alreadyOnHome && interactionIsQuick;
+ if (interactionIsQuick) {
+ mQuickScrubController = mRecentsView.getQuickScrubController();
+ mQuickScrubController.onQuickScrubStart(mStartedQuickScrubFromHome);
+ animateToProgress(1f, MAX_SWIPE_DURATION);
+ if (mStartedQuickScrubFromHome) {
+ mDragView.setVisibility(View.INVISIBLE);
+ }
+ }
+
// Optimization
if (!mLauncher.getDeviceProfile().isVerticalBarLayout()) {
// All-apps search box is visible in vertical bar layout.
@@ -224,7 +243,7 @@ public class NavBarSwipeInteractionHandler extends InternalStateHandler {
@UiThread
private void updateFinalShift() {
- if (!mLauncherReady) {
+ if (!mLauncherReady || mStartedQuickScrubFromHome) {
return;
}
@@ -261,7 +280,7 @@ public class NavBarSwipeInteractionHandler extends InternalStateHandler {
private void setTaskPlanToUi() {
mRecentsView.update(mLoadPlan);
- mRecentsView.initToPage(mRecentsView.getFirstTaskIndex());
+ mRecentsView.initToPage(mStartedQuickScrubFromHome ? 0 : mRecentsView.getFirstTaskIndex());
ObjectAnimator anim = mStateController.animateVisibility(true /* isVisible */)
.setDuration(RECENTS_VIEW_VISIBILITY_DURATION);
anim.addListener(new AnimationSuccessListener() {
@@ -301,7 +320,12 @@ public class NavBarSwipeInteractionHandler extends InternalStateHandler {
}
}
- ObjectAnimator anim = mCurrentShift.animateToValue(endShift).setDuration(duration);
+ animateToProgress(endShift, duration);
+ }
+
+ /** Animates to the given progress, where 0 is the current app and 1 is overview. */
+ private void animateToProgress(float progress, long duration) {
+ ObjectAnimator anim = mCurrentShift.animateToValue(progress).setDuration(duration);
anim.setInterpolator(Interpolators.SCROLL);
anim.addListener(new AnimationSuccessListener() {
@Override
@@ -345,5 +369,32 @@ public class NavBarSwipeInteractionHandler extends InternalStateHandler {
if (currentRecentsPage instanceof TaskView) {
((TaskView) currentRecentsPage).animateIconToScale(1f);
}
+ if (mInteractionType == TouchInteractionService.INTERACTION_QUICK_SWITCH) {
+ for (int i = mRecentsView.getFirstTaskIndex(); i < mRecentsView.getPageCount(); i++) {
+ TaskView taskView = (TaskView) mRecentsView.getPageAt(i);
+ if (taskView.getTask().key.id != mRunningTaskId) {
+ mRecentsView.snapToPage(i, QUICK_SWITCH_SNAP_DURATION);
+ taskView.postDelayed(() -> {taskView.launchTask(true);},
+ QUICK_SWITCH_SNAP_DURATION);
+ break;
+ }
+ }
+ } else if (mInteractionType == TouchInteractionService.INTERACTION_QUICK_SCRUB) {
+ if (mQuickScrubController != null) {
+ mQuickScrubController.snapToPageForCurrentQuickScrubSection();
+ }
+ }
+ }
+
+ public void onQuickScrubEnd() {
+ if (mQuickScrubController != null) {
+ mQuickScrubController.onQuickScrubEnd();
+ }
+ }
+
+ public void onQuickScrubProgress(float progress) {
+ if (mQuickScrubController != null) {
+ mQuickScrubController.onQuickScrubProgress(progress);
+ }
}
}
diff --git a/quickstep/src/com/android/quickstep/QuickScrubController.java b/quickstep/src/com/android/quickstep/QuickScrubController.java
new file mode 100644
index 000000000..f4c205510
--- /dev/null
+++ b/quickstep/src/com/android/quickstep/QuickScrubController.java
@@ -0,0 +1,111 @@
+/*
+ * 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 android.view.HapticFeedbackConstants;
+
+import com.android.launcher3.Alarm;
+import com.android.launcher3.Launcher;
+import com.android.launcher3.OnAlarmListener;
+
+/**
+ * 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.
+ */
+public class QuickScrubController implements OnAlarmListener {
+
+ private static final int NUM_QUICK_SCRUB_SECTIONS = 5;
+ private static final long AUTO_ADVANCE_DELAY = 500;
+ private static final int QUICKSCRUB_END_SNAP_DURATION_PER_PAGE = 60;
+
+ private Launcher mLauncher;
+ private Alarm mAutoAdvanceAlarm;
+ private RecentsView mRecentsView;
+
+ private int mQuickScrubSection;
+ private int mStartPage;
+
+ public QuickScrubController(Launcher launcher) {
+ mLauncher = launcher;
+ mAutoAdvanceAlarm = new Alarm();
+ mAutoAdvanceAlarm.setOnAlarmListener(this);
+ }
+
+ public void onQuickScrubStart(boolean startingFromHome) {
+ mRecentsView = mLauncher.getOverviewPanel();
+ mStartPage = startingFromHome ? 0 : mRecentsView.getFirstTaskIndex();
+ mQuickScrubSection = 0;
+ }
+
+ public void onQuickScrubEnd() {
+ mAutoAdvanceAlarm.cancelAlarm();
+ if (mRecentsView != null) {
+ int page = mRecentsView.getNextPage();
+ // Settle on the page then launch it.
+ int snapDuration = Math.abs(page - mRecentsView.getPageNearestToCenterOfScreen())
+ * QUICKSCRUB_END_SNAP_DURATION_PER_PAGE;
+ mRecentsView.snapToPage(page, snapDuration);
+ mRecentsView.postDelayed(() -> {
+ if (page < mRecentsView.getFirstTaskIndex()) {
+ mRecentsView.getPageAt(page).performClick();
+ } else {
+ ((TaskView) mRecentsView.getPageAt(page)).launchTask(true);
+ }
+ }, snapDuration);
+ }
+ }
+
+ public void onQuickScrubProgress(float progress) {
+ int quickScrubSection = Math.round(progress * NUM_QUICK_SCRUB_SECTIONS);
+ if (quickScrubSection != mQuickScrubSection) {
+ int pageToGoTo = mRecentsView.getNextPage() + quickScrubSection - mQuickScrubSection;
+ goToPageWithHaptic(pageToGoTo);
+ if (quickScrubSection == NUM_QUICK_SCRUB_SECTIONS || quickScrubSection == 0) {
+ mAutoAdvanceAlarm.setAlarm(AUTO_ADVANCE_DELAY);
+ } else {
+ mAutoAdvanceAlarm.cancelAlarm();
+ }
+ mQuickScrubSection = quickScrubSection;
+ }
+ }
+
+ public void snapToPageForCurrentQuickScrubSection() {
+ goToPageWithHaptic(mRecentsView.getCurrentPage() + mQuickScrubSection);
+ }
+
+ private void goToPageWithHaptic(int pageToGoTo) {
+ if (pageToGoTo != mRecentsView.getNextPage()) {
+ mRecentsView.snapToPage(pageToGoTo);
+ mRecentsView.performHapticFeedback(HapticFeedbackConstants.KEYBOARD_TAP,
+ HapticFeedbackConstants.FLAG_IGNORE_VIEW_SETTING);
+ }
+ }
+
+ @Override
+ public void onAlarm(Alarm alarm) {
+ int currPage = mRecentsView.getNextPage();
+ if (mQuickScrubSection == NUM_QUICK_SCRUB_SECTIONS
+ && currPage < mRecentsView.getPageCount() - 1) {
+ goToPageWithHaptic(currPage + 1);
+ } else if (mQuickScrubSection == 0 && currPage > mStartPage) {
+ goToPageWithHaptic(currPage - 1);
+ }
+ mAutoAdvanceAlarm.setAlarm(AUTO_ADVANCE_DELAY);
+ }
+}
diff --git a/quickstep/src/com/android/quickstep/RecentsView.java b/quickstep/src/com/android/quickstep/RecentsView.java
index 0ea5b7c23..09003b2d9 100644
--- a/quickstep/src/com/android/quickstep/RecentsView.java
+++ b/quickstep/src/com/android/quickstep/RecentsView.java
@@ -16,6 +16,8 @@
package com.android.quickstep;
+import static com.android.launcher3.LauncherState.OVERVIEW;
+
import android.animation.LayoutTransition;
import android.content.Context;
import android.graphics.Rect;
@@ -42,8 +44,6 @@ import com.android.systemui.shared.system.WindowManagerWrapper;
import java.util.ArrayList;
-import static com.android.launcher3.LauncherState.OVERVIEW;
-
/**
* A list of recent tasks.
*/
@@ -53,6 +53,8 @@ public class RecentsView extends PagedView {
public static final int SCROLL_TYPE_TASK = 1;
public static final int SCROLL_TYPE_WORKSPACE = 2;
+ private final Launcher mLauncher;
+ private QuickScrubController mQuickScrubController;
private final ScrollState mScrollState = new ScrollState();
private boolean mOverviewStateEnabled;
private boolean mTaskStackListenerRegistered;
@@ -89,6 +91,9 @@ public class RecentsView extends PagedView {
setClipChildren(true);
setupLayoutTransition();
+ mLauncher = Launcher.getLauncher(context);
+ mQuickScrubController = new QuickScrubController(mLauncher);
+
mScrollState.isRtl = mIsRtl;
}
@@ -298,10 +303,14 @@ public class RecentsView extends PagedView {
ActivityManagerWrapper.getInstance().removeTask(taskView.getTask().key.id);
removeView(taskView);
if (getChildCount() == mFirstTaskIndex) {
- Launcher.getLauncher(getContext()).getStateManager().goToState(LauncherState.NORMAL);
+ mLauncher.getStateManager().goToState(LauncherState.NORMAL);
}
}
+ public QuickScrubController getQuickScrubController() {
+ return mQuickScrubController;
+ }
+
public interface PageCallbacks {
/**
diff --git a/quickstep/src/com/android/quickstep/TouchInteractionService.java b/quickstep/src/com/android/quickstep/TouchInteractionService.java
index c72fbf49c..56f0e8920 100644
--- a/quickstep/src/com/android/quickstep/TouchInteractionService.java
+++ b/quickstep/src/com/android/quickstep/TouchInteractionService.java
@@ -37,6 +37,7 @@ import android.graphics.Rect;
import android.os.Build;
import android.os.IBinder;
import android.os.RemoteException;
+import android.support.annotation.IntDef;
import android.util.Log;
import android.view.Choreographer;
import android.view.Display;
@@ -56,6 +57,8 @@ import com.android.systemui.shared.system.ActivityManagerWrapper;
import com.android.systemui.shared.system.BackgroundExecutor;
import com.android.systemui.shared.system.WindowManagerWrapper;
+import java.lang.annotation.Retention;
+import java.lang.annotation.RetentionPolicy;
import java.util.function.Consumer;
/**
@@ -68,6 +71,17 @@ public class TouchInteractionService extends Service {
private static final String TAG = "TouchInteractionService";
+ @IntDef(flag = true, value = {
+ INTERACTION_NORMAL,
+ INTERACTION_QUICK_SWITCH,
+ INTERACTION_QUICK_SCRUB
+ })
+ @Retention(RetentionPolicy.SOURCE)
+ public @interface InteractionType {}
+ public static final int INTERACTION_NORMAL = 0;
+ public static final int INTERACTION_QUICK_SWITCH = 1;
+ public static final int INTERACTION_QUICK_SCRUB = 2;
+
private final IBinder mMyBinder = new IOverviewProxy.Stub() {
@Override
@@ -79,6 +93,30 @@ public class TouchInteractionService extends Service {
public void onBind(ISystemUiProxy iSystemUiProxy) throws RemoteException {
mISystemUiProxy = iSystemUiProxy;
}
+
+ @Override
+ public void onQuickSwitch() {
+ startTouchTracking(INTERACTION_QUICK_SWITCH);
+ }
+
+ @Override
+ public void onQuickScrubStart() {
+ startTouchTracking(INTERACTION_QUICK_SCRUB);
+ }
+
+ @Override
+ public void onQuickScrubEnd() {
+ if (mInteractionHandler != null) {
+ mInteractionHandler.onQuickScrubEnd();
+ }
+ }
+
+ @Override
+ public void onQuickScrubProgress(float progress) {
+ if (mInteractionHandler != null) {
+ mInteractionHandler.onQuickScrubProgress(progress);
+ }
+ }
};
private final Consumer<MotionEvent> mOtherActivityTouchConsumer
@@ -216,7 +254,7 @@ public class TouchInteractionService extends Service {
if (mInteractionHandler == null) {
if (Math.abs(displacement) >= mTouchSlop) {
mStartDisplacement = Math.signum(displacement) * mTouchSlop;
- startTouchTracking();
+ startTouchTracking(INTERACTION_NORMAL);
}
} else {
// Move
@@ -244,10 +282,10 @@ public class TouchInteractionService extends Service {
return mDisplayRotation == Surface.ROTATION_270 && mStableInsets.left > 0;
}
- private void startTouchTracking() {
+ private void startTouchTracking(@InteractionType int interactionType) {
// Create the shared handler
final NavBarSwipeInteractionHandler handler =
- new NavBarSwipeInteractionHandler(mRunningTask, this);
+ new NavBarSwipeInteractionHandler(mRunningTask, this, interactionType);
TraceHelper.partitionSection("TouchInt", "Thershold crossed ");