diff options
author | Tony <twickham@google.com> | 2017-12-22 17:33:02 -0800 |
---|---|---|
committer | Tony <twickham@google.com> | 2018-01-11 17:20:35 -0800 |
commit | 6d6fe041c75e83e795b7dec3ce2a87139eee4368 (patch) | |
tree | 1b6bd0c9d01b98e5fd361ac30781e92392b51b1f /quickstep | |
parent | 1a52ef57c72291a87d4ca6bb1e752fd746646991 (diff) | |
download | android_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.jar | bin | 93195 -> 94484 bytes | |||
-rw-r--r-- | quickstep/src/com/android/launcher3/uioverrides/RecentsViewStateController.java | 6 | ||||
-rw-r--r-- | quickstep/src/com/android/launcher3/uioverrides/WorkspaceCard.java | 3 | ||||
-rw-r--r-- | quickstep/src/com/android/quickstep/NavBarSwipeInteractionHandler.java | 61 | ||||
-rw-r--r-- | quickstep/src/com/android/quickstep/QuickScrubController.java | 111 | ||||
-rw-r--r-- | quickstep/src/com/android/quickstep/RecentsView.java | 15 | ||||
-rw-r--r-- | quickstep/src/com/android/quickstep/TouchInteractionService.java | 44 |
7 files changed, 225 insertions, 15 deletions
diff --git a/quickstep/libs/sysui_shared.jar b/quickstep/libs/sysui_shared.jar Binary files differindex 906969826..b3025ff98 100644 --- a/quickstep/libs/sysui_shared.jar +++ b/quickstep/libs/sysui_shared.jar 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 "); |