blob: 6b0ac948a03636990bbaa722765c6ce96dbcb181 [file] [log] [blame]
Matthew Nga8f24262017-12-19 11:54:24 -08001/*
2 * Copyright (C) 2018 The Android Open Source Project
3 *
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
7 *
8 * http://www.apache.org/licenses/LICENSE-2.0
9 *
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License
15 */
16
17package com.android.systemui.statusbar.phone;
18
19import android.animation.Animator;
20import android.animation.AnimatorListenerAdapter;
21import android.animation.AnimatorSet;
Matthew Ng7090a802018-01-19 13:36:22 -080022import android.animation.ArgbEvaluator;
Matthew Nga8f24262017-12-19 11:54:24 -080023import android.animation.ObjectAnimator;
24import android.animation.ValueAnimator;
25import android.animation.ValueAnimator.AnimatorUpdateListener;
26import android.content.Context;
27import android.graphics.Canvas;
Matthew Ng2ea93b72018-03-14 19:43:18 +000028import android.graphics.Matrix;
Matthew Nga8f24262017-12-19 11:54:24 -080029import android.graphics.Paint;
30import android.graphics.Rect;
31import android.os.Handler;
32import android.os.RemoteException;
33import android.util.Log;
34import android.util.Slog;
Matthew Nga8f24262017-12-19 11:54:24 -080035import android.view.MotionEvent;
36import android.view.View;
Matthew Nga8f24262017-12-19 11:54:24 -080037import android.view.WindowManagerGlobal;
38import android.view.animation.DecelerateInterpolator;
39import android.view.animation.Interpolator;
40import android.support.annotation.DimenRes;
41import com.android.systemui.Dependency;
42import com.android.systemui.OverviewProxyService;
43import com.android.systemui.R;
44import com.android.systemui.plugins.statusbar.phone.NavGesture.GestureHelper;
45import com.android.systemui.shared.recents.IOverviewProxy;
46import com.android.systemui.shared.recents.utilities.Utilities;
Matthew Ngf29ad752018-04-26 11:24:05 -070047import com.android.systemui.shared.system.NavigationBarCompat;
Matthew Nga8f24262017-12-19 11:54:24 -080048
49import static android.view.WindowManagerPolicyConstants.NAV_BAR_LEFT;
50import static android.view.WindowManagerPolicyConstants.NAV_BAR_BOTTOM;
Matthew Ngbd824572018-01-17 16:25:56 -080051import static com.android.systemui.OverviewProxyService.DEBUG_OVERVIEW_PROXY;
52import static com.android.systemui.OverviewProxyService.TAG_OPS;
Winson Chungc4e06202018-02-13 10:37:35 -080053import static com.android.systemui.shared.system.NavigationBarCompat.HIT_TARGET_HOME;
Matthew Nga8f24262017-12-19 11:54:24 -080054
55/**
Matthew Ngfba39692018-03-13 18:08:34 -070056 * Class to detect gestures on the navigation bar and implement quick scrub.
Matthew Nga8f24262017-12-19 11:54:24 -080057 */
Matthew Ngfba39692018-03-13 18:08:34 -070058public class QuickStepController implements GestureHelper {
Matthew Nga8f24262017-12-19 11:54:24 -080059
Matthew Ng2ea93b72018-03-14 19:43:18 +000060 private static final String TAG = "QuickStepController";
Matthew Nga8f24262017-12-19 11:54:24 -080061 private static final int ANIM_DURATION_MS = 200;
Matthew Nga8f24262017-12-19 11:54:24 -080062
63 private NavigationBarView mNavigationBarView;
Matthew Nga8f24262017-12-19 11:54:24 -080064
Matthew Nga8f24262017-12-19 11:54:24 -080065 private boolean mQuickScrubActive;
Matthew Ng2ea93b72018-03-14 19:43:18 +000066 private boolean mAllowGestureDetection;
67 private boolean mQuickStepStarted;
Matthew Nga8f24262017-12-19 11:54:24 -080068 private float mDownOffset;
69 private float mTranslation;
70 private int mTouchDownX;
71 private int mTouchDownY;
Matthew Ng9a223632018-03-30 16:47:22 -070072 private boolean mDragScrubActive;
Matthew Nga8f24262017-12-19 11:54:24 -080073 private boolean mDragPositive;
74 private boolean mIsVertical;
75 private boolean mIsRTL;
Matthew Ng7090a802018-01-19 13:36:22 -080076 private float mTrackAlpha;
77 private int mLightTrackColor;
78 private int mDarkTrackColor;
79 private float mDarkIntensity;
Winson Chungd10ca302018-02-14 10:13:41 -080080 private View mHomeButtonView;
Matthew Nga8f24262017-12-19 11:54:24 -080081
82 private final Handler mHandler = new Handler();
83 private final Interpolator mQuickScrubEndInterpolator = new DecelerateInterpolator();
84 private final Rect mTrackRect = new Rect();
Matthew Nga8f24262017-12-19 11:54:24 -080085 private final Paint mTrackPaint = new Paint();
Matthew Nga8f24262017-12-19 11:54:24 -080086 private final OverviewProxyService mOverviewEventSender;
Matthew Nga8f24262017-12-19 11:54:24 -080087 private final int mTrackThickness;
88 private final int mTrackPadding;
89 private final ValueAnimator mTrackAnimator;
90 private final ValueAnimator mButtonAnimator;
91 private final AnimatorSet mQuickScrubEndAnimator;
92 private final Context mContext;
Matthew Ng2ea93b72018-03-14 19:43:18 +000093 private final Matrix mTransformGlobalMatrix = new Matrix();
94 private final Matrix mTransformLocalMatrix = new Matrix();
Matthew Ng7090a802018-01-19 13:36:22 -080095 private final ArgbEvaluator mTrackColorEvaluator = new ArgbEvaluator();
Matthew Nga8f24262017-12-19 11:54:24 -080096
97 private final AnimatorUpdateListener mTrackAnimatorListener = valueAnimator -> {
Matthew Ng7090a802018-01-19 13:36:22 -080098 mTrackAlpha = (float) valueAnimator.getAnimatedValue();
Matthew Nga8f24262017-12-19 11:54:24 -080099 mNavigationBarView.invalidate();
100 };
101
102 private final AnimatorUpdateListener mButtonTranslationListener = animator -> {
103 int pos = (int) animator.getAnimatedValue();
104 if (!mQuickScrubActive) {
105 pos = mDragPositive ? Math.min((int) mTranslation, pos) : Math.max((int) mTranslation, pos);
106 }
Matthew Nga8f24262017-12-19 11:54:24 -0800107 if (mIsVertical) {
Winson Chungd10ca302018-02-14 10:13:41 -0800108 mHomeButtonView.setTranslationY(pos);
Matthew Nga8f24262017-12-19 11:54:24 -0800109 } else {
Winson Chungd10ca302018-02-14 10:13:41 -0800110 mHomeButtonView.setTranslationX(pos);
Matthew Nga8f24262017-12-19 11:54:24 -0800111 }
112 };
113
114 private AnimatorListenerAdapter mQuickScrubEndListener = new AnimatorListenerAdapter() {
115 @Override
116 public void onAnimationEnd(Animator animation) {
Matthew Nga8f24262017-12-19 11:54:24 -0800117 mQuickScrubActive = false;
Matthew Ng9a223632018-03-30 16:47:22 -0700118 mDragScrubActive = false;
Matthew Nga8f24262017-12-19 11:54:24 -0800119 mTranslation = 0;
Matthew Nged166f92018-02-20 16:22:09 -0800120 mQuickScrubEndAnimator.setCurrentPlayTime(mQuickScrubEndAnimator.getDuration());
121 mHomeButtonView = null;
Matthew Nga8f24262017-12-19 11:54:24 -0800122 }
123 };
124
Matthew Ng2ea93b72018-03-14 19:43:18 +0000125 public QuickStepController(Context context) {
Matthew Nga8f24262017-12-19 11:54:24 -0800126 mContext = context;
Matthew Nga8f24262017-12-19 11:54:24 -0800127 mOverviewEventSender = Dependency.get(OverviewProxyService.class);
Matthew Nga8f24262017-12-19 11:54:24 -0800128 mTrackThickness = getDimensionPixelSize(mContext, R.dimen.nav_quick_scrub_track_thickness);
129 mTrackPadding = getDimensionPixelSize(mContext, R.dimen.nav_quick_scrub_track_edge_padding);
Matthew Ng7090a802018-01-19 13:36:22 -0800130 mTrackPaint.setAlpha(0);
Matthew Nga8f24262017-12-19 11:54:24 -0800131
132 mTrackAnimator = ObjectAnimator.ofFloat();
133 mTrackAnimator.addUpdateListener(mTrackAnimatorListener);
Matthew Ng55437a92018-02-23 15:02:07 -0800134 mTrackAnimator.setFloatValues(0);
Matthew Nga8f24262017-12-19 11:54:24 -0800135 mButtonAnimator = ObjectAnimator.ofInt();
136 mButtonAnimator.addUpdateListener(mButtonTranslationListener);
Matthew Ng55437a92018-02-23 15:02:07 -0800137 mButtonAnimator.setIntValues(0);
Matthew Nga8f24262017-12-19 11:54:24 -0800138 mQuickScrubEndAnimator = new AnimatorSet();
139 mQuickScrubEndAnimator.playTogether(mTrackAnimator, mButtonAnimator);
140 mQuickScrubEndAnimator.setDuration(ANIM_DURATION_MS);
141 mQuickScrubEndAnimator.addListener(mQuickScrubEndListener);
142 mQuickScrubEndAnimator.setInterpolator(mQuickScrubEndInterpolator);
143 }
144
145 public void setComponents(NavigationBarView navigationBarView) {
146 mNavigationBarView = navigationBarView;
147 }
148
Winson Chung4faf38a2018-02-06 08:53:37 -0800149 /**
Matthew Ngfba39692018-03-13 18:08:34 -0700150 * @return true if we want to intercept touch events for quick scrub and prevent proxying the
151 * event to the overview service.
Winson Chung4faf38a2018-02-06 08:53:37 -0800152 */
Matthew Nga8f24262017-12-19 11:54:24 -0800153 @Override
154 public boolean onInterceptTouchEvent(MotionEvent event) {
Winson Chungde2a1242018-02-07 15:59:43 -0800155 return handleTouchEvent(event);
156 }
157
158 /**
Matthew Ngfba39692018-03-13 18:08:34 -0700159 * @return true if we want to handle touch events for quick scrub or if down event (that will
160 * get consumed and ignored). No events will be proxied to the overview service.
Winson Chungde2a1242018-02-07 15:59:43 -0800161 */
162 @Override
163 public boolean onTouchEvent(MotionEvent event) {
Matthew Ng2ea93b72018-03-14 19:43:18 +0000164 // The same down event was just sent on intercept and therefore can be ignored here
165 final boolean ignoreProxyDownEvent = event.getAction() == MotionEvent.ACTION_DOWN
166 && mOverviewEventSender.getProxy() != null;
167 return ignoreProxyDownEvent || handleTouchEvent(event);
Winson Chungde2a1242018-02-07 15:59:43 -0800168 }
169
170 private boolean handleTouchEvent(MotionEvent event) {
Winson Chungd95a2252018-04-04 17:02:29 +0000171 if (mOverviewEventSender.getProxy() == null || (!mNavigationBarView.isQuickScrubEnabled()
172 && !mNavigationBarView.isQuickStepSwipeUpEnabled())) {
Matthew Ng22cf5142018-03-14 12:26:14 -0700173 mNavigationBarView.getHomeButton().setDelayTouchFeedback(false /* delay */);
174 return false;
175 }
176 mNavigationBarView.requestUnbufferedDispatch(event);
177
Winson Chungde2a1242018-02-07 15:59:43 -0800178 final ButtonDispatcher homeButton = mNavigationBarView.getHomeButton();
Matthew Ng2ea93b72018-03-14 19:43:18 +0000179 final boolean homePressed = mNavigationBarView.getDownHitTarget() == HIT_TARGET_HOME;
Matthew Ng9a223632018-03-30 16:47:22 -0700180 int action = event.getActionMasked();
181 switch (action) {
Matthew Nga8f24262017-12-19 11:54:24 -0800182 case MotionEvent.ACTION_DOWN: {
183 int x = (int) event.getX();
184 int y = (int) event.getY();
Winson Chung0be8f082018-02-15 15:52:49 -0800185 // End any existing quickscrub animations before starting the new transition
Matthew Nged166f92018-02-20 16:22:09 -0800186 if (mHomeButtonView != null) {
Winson Chung0be8f082018-02-15 15:52:49 -0800187 mQuickScrubEndAnimator.end();
188 }
Winson Chungd10ca302018-02-14 10:13:41 -0800189 mHomeButtonView = homeButton.getCurrentView();
Matthew Ng2ea93b72018-03-14 19:43:18 +0000190 homeButton.setDelayTouchFeedback(true /* delay */);
191 mTouchDownX = x;
192 mTouchDownY = y;
Matthew Ng2ea93b72018-03-14 19:43:18 +0000193 mTransformGlobalMatrix.set(Matrix.IDENTITY_MATRIX);
194 mTransformLocalMatrix.set(Matrix.IDENTITY_MATRIX);
195 mNavigationBarView.transformMatrixToGlobal(mTransformGlobalMatrix);
196 mNavigationBarView.transformMatrixToLocal(mTransformLocalMatrix);
197 mQuickStepStarted = false;
Matthew Ng2ea93b72018-03-14 19:43:18 +0000198 mAllowGestureDetection = true;
Matthew Nga8f24262017-12-19 11:54:24 -0800199 break;
200 }
201 case MotionEvent.ACTION_MOVE: {
Matthew Ng603b3292018-03-30 17:15:39 -0700202 if (mQuickStepStarted || !mAllowGestureDetection || mHomeButtonView == null){
Matthew Ng2ea93b72018-03-14 19:43:18 +0000203 break;
204 }
205 int x = (int) event.getX();
206 int y = (int) event.getY();
207 int xDiff = Math.abs(x - mTouchDownX);
208 int yDiff = Math.abs(y - mTouchDownY);
Matthew Ng9a223632018-03-30 16:47:22 -0700209
210 boolean exceededScrubTouchSlop, exceededSwipeUpTouchSlop, exceededScrubDragSlop;
Matthew Ng2ea93b72018-03-14 19:43:18 +0000211 int pos, touchDown, offset, trackSize;
Matthew Nge0903c92018-01-17 15:32:41 -0800212
Matthew Ng2ea93b72018-03-14 19:43:18 +0000213 if (mIsVertical) {
Matthew Ngf29ad752018-04-26 11:24:05 -0700214 exceededScrubTouchSlop =
215 yDiff > NavigationBarCompat.getQuickScrubTouchSlopPx() && yDiff > xDiff;
216 exceededSwipeUpTouchSlop =
217 xDiff > NavigationBarCompat.getQuickStepTouchSlopPx() && xDiff > yDiff;
218 exceededScrubDragSlop =
219 yDiff > NavigationBarCompat.getQuickScrubDragSlopPx() && yDiff > xDiff;
Matthew Ng2ea93b72018-03-14 19:43:18 +0000220 pos = y;
221 touchDown = mTouchDownY;
222 offset = pos - mTrackRect.top;
223 trackSize = mTrackRect.height();
224 } else {
Matthew Ngf29ad752018-04-26 11:24:05 -0700225 exceededScrubTouchSlop =
226 xDiff > NavigationBarCompat.getQuickScrubTouchSlopPx() && xDiff > yDiff;
227 exceededSwipeUpTouchSlop =
228 yDiff > NavigationBarCompat.getQuickStepTouchSlopPx() && yDiff > xDiff;
229 exceededScrubDragSlop =
230 xDiff > NavigationBarCompat.getQuickScrubDragSlopPx() && xDiff > yDiff;
Matthew Ng2ea93b72018-03-14 19:43:18 +0000231 pos = x;
232 touchDown = mTouchDownX;
233 offset = pos - mTrackRect.left;
234 trackSize = mTrackRect.width();
235 }
236 // Decide to start quickstep if dragging away from the navigation bar, otherwise in
237 // the parallel direction, decide to start quickscrub. Only one may run.
Matthew Ng9a223632018-03-30 16:47:22 -0700238 if (!mQuickScrubActive && exceededSwipeUpTouchSlop) {
Matthew Ng2ea93b72018-03-14 19:43:18 +0000239 if (mNavigationBarView.isQuickStepSwipeUpEnabled()) {
240 startQuickStep(event);
Winson Chung0e490d922018-03-14 16:08:43 +0000241 }
Matthew Ng2ea93b72018-03-14 19:43:18 +0000242 break;
243 }
Winson Chung0e490d922018-03-14 16:08:43 +0000244
Matthew Ngfba39692018-03-13 18:08:34 -0700245 // Do not handle quick scrub if disabled or hit target is not home button
Matthew Ng2ea93b72018-03-14 19:43:18 +0000246 if (!homePressed || !mNavigationBarView.isQuickScrubEnabled()) {
247 break;
248 }
249
250 if (!mDragPositive) {
251 offset -= mIsVertical ? mTrackRect.height() : mTrackRect.width();
252 }
253
Matthew Ng9a223632018-03-30 16:47:22 -0700254 final boolean allowDrag = !mDragPositive
255 ? offset < 0 && pos < touchDown : offset >= 0 && pos > touchDown;
256 if (allowDrag) {
257 // Passing the drag slop is for visual feedback and will not initiate anything
258 if (!mDragScrubActive && exceededScrubDragSlop) {
Matthew Ng2ea93b72018-03-14 19:43:18 +0000259 mDownOffset = offset;
Matthew Ng9a223632018-03-30 16:47:22 -0700260 mDragScrubActive = true;
261 }
262
263 // Passing the drag slop then touch slop will start quick step
264 if (!mQuickScrubActive && exceededScrubTouchSlop) {
Matthew Ng2ea93b72018-03-14 19:43:18 +0000265 homeButton.abortCurrentGesture();
Matthew Ngfba39692018-03-13 18:08:34 -0700266 startQuickScrub();
Winson Chung0e490d922018-03-14 16:08:43 +0000267 }
Matthew Ng2ea93b72018-03-14 19:43:18 +0000268 }
Matthew Ng9a223632018-03-30 16:47:22 -0700269
270 if ((mQuickScrubActive || mDragScrubActive) && (mDragPositive && offset >= 0
Matthew Ng2ea93b72018-03-14 19:43:18 +0000271 || !mDragPositive && offset <= 0)) {
Matthew Ng2ea93b72018-03-14 19:43:18 +0000272 mTranslation = !mDragPositive
Matthew Ng9a223632018-03-30 16:47:22 -0700273 ? Utilities.clamp(offset - mDownOffset, -trackSize, 0)
274 : Utilities.clamp(offset - mDownOffset, 0, trackSize);
275 if (mQuickScrubActive) {
276 float scrubFraction =
277 Utilities.clamp(Math.abs(offset) * 1f / trackSize, 0, 1);
278 try {
279 mOverviewEventSender.getProxy().onQuickScrubProgress(scrubFraction);
280 if (DEBUG_OVERVIEW_PROXY) {
281 Log.d(TAG_OPS, "Quick Scrub Progress:" + scrubFraction);
282 }
283 } catch (RemoteException e) {
284 Log.e(TAG, "Failed to send progress of quick scrub.", e);
Winson Chung0e490d922018-03-14 16:08:43 +0000285 }
Matthew Ng2ea93b72018-03-14 19:43:18 +0000286 }
287 if (mIsVertical) {
288 mHomeButtonView.setTranslationY(mTranslation);
289 } else {
290 mHomeButtonView.setTranslationX(mTranslation);
Matthew Nga8f24262017-12-19 11:54:24 -0800291 }
292 }
293 break;
294 }
295 case MotionEvent.ACTION_CANCEL:
296 case MotionEvent.ACTION_UP:
Winson Chungd10ca302018-02-14 10:13:41 -0800297 endQuickScrub(true /* animate */);
Matthew Nga8f24262017-12-19 11:54:24 -0800298 break;
299 }
Matthew Ng2ea93b72018-03-14 19:43:18 +0000300
Matthew Ngfba39692018-03-13 18:08:34 -0700301 // Proxy motion events to launcher if not handled by quick scrub
Matthew Ng9a223632018-03-30 16:47:22 -0700302 // Proxy motion events up/cancel that would be sent after long press on any nav button
303 if (!mQuickScrubActive && (mAllowGestureDetection || action == MotionEvent.ACTION_CANCEL
304 || action == MotionEvent.ACTION_UP)) {
Matthew Ng2ea93b72018-03-14 19:43:18 +0000305 proxyMotionEvents(event);
306 }
Matthew Ngfba39692018-03-13 18:08:34 -0700307 return mQuickScrubActive || mQuickStepStarted;
Matthew Nga8f24262017-12-19 11:54:24 -0800308 }
309
310 @Override
311 public void onDraw(Canvas canvas) {
Matthew Ngf781bbd2018-03-21 14:58:55 -0700312 if (!mNavigationBarView.isQuickScrubEnabled()) {
Matthew Ng2ea93b72018-03-14 19:43:18 +0000313 return;
314 }
Matthew Ng7090a802018-01-19 13:36:22 -0800315 int color = (int) mTrackColorEvaluator.evaluate(mDarkIntensity, mLightTrackColor,
316 mDarkTrackColor);
317 mTrackPaint.setColor(color);
318 mTrackPaint.setAlpha((int) (mTrackPaint.getAlpha() * mTrackAlpha));
Matthew Nga8f24262017-12-19 11:54:24 -0800319 canvas.drawRect(mTrackRect, mTrackPaint);
320 }
321
322 @Override
323 public void onLayout(boolean changed, int left, int top, int right, int bottom) {
Matthew Ng5bcd3472018-03-22 11:33:16 -0700324 final int width = (right - left) - mNavigationBarView.getPaddingEnd()
325 - mNavigationBarView.getPaddingStart();
326 final int height = (bottom - top) - mNavigationBarView.getPaddingBottom()
327 - mNavigationBarView.getPaddingTop();
Matthew Nga8f24262017-12-19 11:54:24 -0800328 final int x1, x2, y1, y2;
329 if (mIsVertical) {
Matthew Ng5bcd3472018-03-22 11:33:16 -0700330 x1 = (width - mTrackThickness) / 2 + mNavigationBarView.getPaddingStart();
Matthew Nga8f24262017-12-19 11:54:24 -0800331 x2 = x1 + mTrackThickness;
332 y1 = mDragPositive ? height / 2 : mTrackPadding;
333 y2 = y1 + height / 2 - mTrackPadding;
334 } else {
Matthew Ng5bcd3472018-03-22 11:33:16 -0700335 y1 = (height - mTrackThickness) / 2 + mNavigationBarView.getPaddingTop();
Matthew Nga8f24262017-12-19 11:54:24 -0800336 y2 = y1 + mTrackThickness;
337 x1 = mDragPositive ? width / 2 : mTrackPadding;
338 x2 = x1 + width / 2 - mTrackPadding;
339 }
340 mTrackRect.set(x1, y1, x2, y2);
Matthew Nga8f24262017-12-19 11:54:24 -0800341 }
342
343 @Override
344 public void onDarkIntensityChange(float intensity) {
Matthew Ng7090a802018-01-19 13:36:22 -0800345 mDarkIntensity = intensity;
346 mNavigationBarView.invalidate();
Matthew Nga8f24262017-12-19 11:54:24 -0800347 }
348
349 @Override
Matthew Nga8f24262017-12-19 11:54:24 -0800350 public void setBarState(boolean isVertical, boolean isRTL) {
Winson Chungd10ca302018-02-14 10:13:41 -0800351 final boolean changed = (mIsVertical != isVertical) || (mIsRTL != isRTL);
352 if (changed) {
353 // End quickscrub if the state changes mid-transition
354 endQuickScrub(false /* animate */);
355 }
Matthew Nga8f24262017-12-19 11:54:24 -0800356 mIsVertical = isVertical;
357 mIsRTL = isRTL;
358 try {
359 int navbarPos = WindowManagerGlobal.getWindowManagerService().getNavBarPosition();
360 mDragPositive = navbarPos == NAV_BAR_LEFT || navbarPos == NAV_BAR_BOTTOM;
361 if (isRTL) {
362 mDragPositive = !mDragPositive;
363 }
364 } catch (RemoteException e) {
365 Slog.e(TAG, "Failed to get nav bar position.", e);
366 }
367 }
368
Matthew Ng2ea93b72018-03-14 19:43:18 +0000369 @Override
370 public void onNavigationButtonLongPress(View v) {
371 mAllowGestureDetection = false;
372 mHandler.removeCallbacksAndMessages(null);
373 }
374
375 private void startQuickStep(MotionEvent event) {
376 mQuickStepStarted = true;
377 event.transform(mTransformGlobalMatrix);
378 try {
379 mOverviewEventSender.getProxy().onQuickStep(event);
380 if (DEBUG_OVERVIEW_PROXY) {
381 Log.d(TAG_OPS, "Quick Step Start");
382 }
383 } catch (RemoteException e) {
384 Log.e(TAG, "Failed to send quick step started.", e);
385 } finally {
386 event.transform(mTransformLocalMatrix);
387 }
388 mOverviewEventSender.notifyQuickStepStarted();
389 mNavigationBarView.getHomeButton().abortCurrentGesture();
Matthew Ng2ea93b72018-03-14 19:43:18 +0000390 mHandler.removeCallbacksAndMessages(null);
Matthew Ng9a223632018-03-30 16:47:22 -0700391
392 if (mDragScrubActive) {
393 animateEnd();
394 }
Matthew Ng2ea93b72018-03-14 19:43:18 +0000395 }
396
Matthew Nga8f24262017-12-19 11:54:24 -0800397 private void startQuickScrub() {
Matthew Ng9a223632018-03-30 16:47:22 -0700398 if (!mQuickScrubActive && mDragScrubActive) {
Matthew Nga8f24262017-12-19 11:54:24 -0800399 mQuickScrubActive = true;
Matthew Ng7090a802018-01-19 13:36:22 -0800400 mLightTrackColor = mContext.getColor(R.color.quick_step_track_background_light);
401 mDarkTrackColor = mContext.getColor(R.color.quick_step_track_background_dark);
402 mTrackAnimator.setFloatValues(0, 1);
Matthew Nga8f24262017-12-19 11:54:24 -0800403 mTrackAnimator.start();
404 try {
405 mOverviewEventSender.getProxy().onQuickScrubStart();
Matthew Ngbd824572018-01-17 16:25:56 -0800406 if (DEBUG_OVERVIEW_PROXY) {
407 Log.d(TAG_OPS, "Quick Scrub Start");
408 }
Matthew Nga8f24262017-12-19 11:54:24 -0800409 } catch (RemoteException e) {
410 Log.e(TAG, "Failed to send start of quick scrub.", e);
411 }
Tracy Zhou27599052018-04-16 15:47:29 -0700412 mOverviewEventSender.notifyQuickScrubStarted();
Matthew Nga8f24262017-12-19 11:54:24 -0800413 }
414 }
415
Winson Chungd10ca302018-02-14 10:13:41 -0800416 private void endQuickScrub(boolean animate) {
Matthew Ng9a223632018-03-30 16:47:22 -0700417 if (mQuickScrubActive || mDragScrubActive) {
Matthew Nged166f92018-02-20 16:22:09 -0800418 animateEnd();
Matthew Ng9a223632018-03-30 16:47:22 -0700419 if (mQuickScrubActive) {
420 try {
421 mOverviewEventSender.getProxy().onQuickScrubEnd();
422 if (DEBUG_OVERVIEW_PROXY) {
423 Log.d(TAG_OPS, "Quick Scrub End");
424 }
425 } catch (RemoteException e) {
426 Log.e(TAG, "Failed to send end of quick scrub.", e);
Matthew Ngbd824572018-01-17 16:25:56 -0800427 }
Matthew Nga8f24262017-12-19 11:54:24 -0800428 }
Matthew Nged166f92018-02-20 16:22:09 -0800429 }
430 if (mHomeButtonView != null && !animate) {
431 mQuickScrubEndAnimator.end();
Matthew Nga8f24262017-12-19 11:54:24 -0800432 }
Matthew Nga8f24262017-12-19 11:54:24 -0800433 }
434
Matthew Ng2ea93b72018-03-14 19:43:18 +0000435 private boolean proxyMotionEvents(MotionEvent event) {
436 final IOverviewProxy overviewProxy = mOverviewEventSender.getProxy();
437 event.transform(mTransformGlobalMatrix);
438 try {
439 if (event.getActionMasked() == MotionEvent.ACTION_DOWN) {
440 overviewProxy.onPreMotionEvent(mNavigationBarView.getDownHitTarget());
441 }
442 overviewProxy.onMotionEvent(event);
443 if (DEBUG_OVERVIEW_PROXY) {
444 Log.d(TAG_OPS, "Send MotionEvent: " + event.toString());
445 }
446 return true;
447 } catch (RemoteException e) {
448 Log.e(TAG, "Callback failed", e);
449 } finally {
450 event.transform(mTransformLocalMatrix);
Matthew Ngdb2734c2018-02-16 16:02:20 -0800451 }
Matthew Ng2ea93b72018-03-14 19:43:18 +0000452 return false;
Matthew Ngdb2734c2018-02-16 16:02:20 -0800453 }
454
Matthew Nged166f92018-02-20 16:22:09 -0800455 private void animateEnd() {
456 mButtonAnimator.setIntValues((int) mTranslation, 0);
457 mTrackAnimator.setFloatValues(mTrackAlpha, 0);
Matthew Ng55437a92018-02-23 15:02:07 -0800458 mQuickScrubEndAnimator.setCurrentPlayTime(0);
Matthew Nged166f92018-02-20 16:22:09 -0800459 mQuickScrubEndAnimator.start();
460 }
461
Matthew Nga8f24262017-12-19 11:54:24 -0800462 private int getDimensionPixelSize(Context context, @DimenRes int resId) {
463 return context.getResources().getDimensionPixelSize(resId);
464 }
465}