Revert "Revert "Centralized quick step/scrub/switch logic (1/2)""
This reverts commit 0e490d9208.
Reason for revert: Will be merged with fix
Bug: 74726495
Test: manual
Change-Id: I36ea9c2702107b23eff4adb1f3ba9fdc1be12999
This commit is contained in:
@@ -16,6 +16,7 @@ package com.android.systemui.plugins.statusbar.phone;
|
||||
|
||||
import android.graphics.Canvas;
|
||||
import android.view.MotionEvent;
|
||||
import android.view.View;
|
||||
|
||||
import com.android.systemui.plugins.Plugin;
|
||||
import com.android.systemui.plugins.annotations.ProvidesInterface;
|
||||
@@ -42,6 +43,8 @@ public interface NavGesture extends Plugin {
|
||||
|
||||
public void onLayout(boolean changed, int left, int top, int right, int bottom);
|
||||
|
||||
public void onNavigationButtonLongPress(View v);
|
||||
|
||||
public default void destroy() { }
|
||||
}
|
||||
|
||||
|
||||
@@ -80,4 +80,17 @@ oneway interface IOverviewProxy {
|
||||
* Sent when overview is to be hidden.
|
||||
*/
|
||||
void onOverviewHidden(boolean triggeredFromAltTab, boolean triggeredFromHomeKey);
|
||||
|
||||
/**
|
||||
* Sent when a user swipes up over the navigation bar to launch overview. Swipe up is determined
|
||||
* by passing the touch slop in the direction towards launcher from navigation bar. During and
|
||||
* after this event is sent the caller will continue to send motion events. The motion
|
||||
* {@param event} passed after the touch slop was exceeded will also be passed after by
|
||||
* {@link onMotionEvent}. Since motion events will be sent, motion up or cancel can still be
|
||||
* sent to cancel overview regardless the current state of launcher (eg. if overview is already
|
||||
* visible, this event will still be sent if user swipes up). When this signal is sent,
|
||||
* navigation bar will not handle any gestures such as quick scrub or switch and the home button
|
||||
* will cancel (long) press.
|
||||
*/
|
||||
void onQuickStep(in MotionEvent event);
|
||||
}
|
||||
|
||||
@@ -35,11 +35,6 @@ interface ISystemUiProxy {
|
||||
*/
|
||||
void startScreenPinning(int taskId) = 1;
|
||||
|
||||
/**
|
||||
* Called when the overview service has started the recents animation.
|
||||
*/
|
||||
void onRecentsAnimationStarted() = 2;
|
||||
|
||||
/**
|
||||
* Specifies the text to be shown for onboarding the new swipe-up gesture to access recents.
|
||||
*/
|
||||
|
||||
@@ -102,15 +102,6 @@ public class OverviewProxyService implements CallbackController<OverviewProxyLis
|
||||
}
|
||||
}
|
||||
|
||||
public void onRecentsAnimationStarted() {
|
||||
long token = Binder.clearCallingIdentity();
|
||||
try {
|
||||
mHandler.post(OverviewProxyService.this::notifyRecentsAnimationStarted);
|
||||
} finally {
|
||||
Binder.restoreCallingIdentity(token);
|
||||
}
|
||||
}
|
||||
|
||||
public void onSplitScreenInvoked() {
|
||||
long token = Binder.clearCallingIdentity();
|
||||
try {
|
||||
@@ -283,9 +274,9 @@ public class OverviewProxyService implements CallbackController<OverviewProxyLis
|
||||
}
|
||||
}
|
||||
|
||||
private void notifyRecentsAnimationStarted() {
|
||||
public void notifyQuickStepStarted() {
|
||||
for (int i = mConnectionCallbacks.size() - 1; i >= 0; --i) {
|
||||
mConnectionCallbacks.get(i).onRecentsAnimationStarted();
|
||||
mConnectionCallbacks.get(i).onQuickStepStarted();
|
||||
}
|
||||
}
|
||||
|
||||
@@ -300,7 +291,7 @@ public class OverviewProxyService implements CallbackController<OverviewProxyLis
|
||||
|
||||
public interface OverviewProxyListener {
|
||||
default void onConnectionChanged(boolean isConnected) {}
|
||||
default void onRecentsAnimationStarted() {}
|
||||
default void onQuickStepStarted() {}
|
||||
default void onInteractionFlagsChanged(@InteractionType int flags) {}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -189,7 +189,7 @@ public class RecentsOnboarding {
|
||||
}
|
||||
}
|
||||
|
||||
public void onRecentsAnimationStarted() {
|
||||
public void onQuickStepStarted() {
|
||||
boolean alreadySeenRecentsOnboarding = Prefs.getBoolean(mContext,
|
||||
Prefs.Key.HAS_SEEN_RECENTS_ONBOARDING, false);
|
||||
if (!alreadySeenRecentsOnboarding) {
|
||||
|
||||
@@ -175,8 +175,8 @@ public class NavigationBarFragment extends Fragment implements Callbacks {
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onRecentsAnimationStarted() {
|
||||
mNavigationBarView.setRecentsAnimationStarted(true);
|
||||
public void onQuickStepStarted() {
|
||||
mNavigationBarView.onQuickStepStarted();
|
||||
|
||||
// Use navbar dragging as a signal to hide the rotate button
|
||||
setRotateSuggestionButtonState(false);
|
||||
@@ -751,6 +751,7 @@ public class NavigationBarFragment extends Fragment implements Callbacks {
|
||||
if (shouldDisableNavbarGestures()) {
|
||||
return false;
|
||||
}
|
||||
mNavigationBarView.onNavigationButtonLongPress(v);
|
||||
mMetricsLogger.action(MetricsEvent.ACTION_ASSIST_LONG_PRESS);
|
||||
mAssistManager.startAssist(new Bundle() /* args */);
|
||||
mStatusBar.awakenDreams();
|
||||
@@ -787,10 +788,12 @@ public class NavigationBarFragment extends Fragment implements Callbacks {
|
||||
}
|
||||
|
||||
private boolean onLongPressBackHome(View v) {
|
||||
mNavigationBarView.onNavigationButtonLongPress(v);
|
||||
return onLongPressNavigationButtons(v, R.id.back, R.id.home);
|
||||
}
|
||||
|
||||
private boolean onLongPressBackRecents(View v) {
|
||||
mNavigationBarView.onNavigationButtonLongPress(v);
|
||||
return onLongPressNavigationButtons(v, R.id.back, R.id.recent_apps);
|
||||
}
|
||||
|
||||
|
||||
@@ -19,31 +19,22 @@ package com.android.systemui.statusbar.phone;
|
||||
import static android.view.WindowManager.DOCKED_INVALID;
|
||||
import static android.view.WindowManager.DOCKED_LEFT;
|
||||
import static android.view.WindowManager.DOCKED_TOP;
|
||||
import static com.android.systemui.OverviewProxyService.DEBUG_OVERVIEW_PROXY;
|
||||
import static com.android.systemui.OverviewProxyService.TAG_OPS;
|
||||
|
||||
import android.app.ActivityManager;
|
||||
import android.content.Context;
|
||||
import android.content.res.Resources;
|
||||
import android.graphics.Canvas;
|
||||
import android.graphics.Matrix;
|
||||
import android.graphics.Rect;
|
||||
import android.os.RemoteException;
|
||||
import android.util.Log;
|
||||
import android.view.MotionEvent;
|
||||
import android.view.VelocityTracker;
|
||||
import android.view.View;
|
||||
import com.android.internal.logging.nano.MetricsProto.MetricsEvent;
|
||||
import com.android.internal.policy.DividerSnapAlgorithm.SnapTarget;
|
||||
import com.android.systemui.Dependency;
|
||||
import com.android.systemui.OverviewProxyService;
|
||||
import com.android.systemui.OverviewProxyService.OverviewProxyListener;
|
||||
import com.android.systemui.R;
|
||||
import com.android.systemui.RecentsComponent;
|
||||
import com.android.systemui.SysUiServiceProvider;
|
||||
import com.android.systemui.plugins.statusbar.phone.NavGesture.GestureHelper;
|
||||
import com.android.systemui.shared.recents.IOverviewProxy;
|
||||
import com.android.systemui.shared.system.ActivityManagerWrapper;
|
||||
import com.android.systemui.stackdivider.Divider;
|
||||
import com.android.systemui.tuner.TunerService;
|
||||
|
||||
@@ -75,25 +66,14 @@ public class NavigationBarGestureHelper implements TunerService.Tunable, Gesture
|
||||
private NavigationBarView mNavigationBarView;
|
||||
private boolean mIsVertical;
|
||||
|
||||
private final QuickScrubController mQuickScrubController;
|
||||
private final QuickStepController mQuickStepController;
|
||||
private final int mScrollTouchSlop;
|
||||
private final Matrix mTransformGlobalMatrix = new Matrix();
|
||||
private final Matrix mTransformLocalMatrix = new Matrix();
|
||||
private final StatusBar mStatusBar;
|
||||
private int mTouchDownX;
|
||||
private int mTouchDownY;
|
||||
private boolean mDownOnRecents;
|
||||
private VelocityTracker mVelocityTracker;
|
||||
private OverviewProxyService mOverviewProxyService = Dependency.get(OverviewProxyService.class);
|
||||
private final OverviewProxyListener mOverviewProxyListener = new OverviewProxyListener() {
|
||||
@Override
|
||||
public void onRecentsAnimationStarted() {
|
||||
mRecentsAnimationStarted = true;
|
||||
mQuickScrubController.setRecentsAnimationStarted(true /* started */);
|
||||
}
|
||||
};
|
||||
|
||||
private boolean mRecentsAnimationStarted;
|
||||
private boolean mDockWindowEnabled;
|
||||
private boolean mDockWindowTouchSlopExceeded;
|
||||
private int mDragMode;
|
||||
@@ -103,14 +83,12 @@ public class NavigationBarGestureHelper implements TunerService.Tunable, Gesture
|
||||
mStatusBar = SysUiServiceProvider.getComponent(context, StatusBar.class);
|
||||
Resources r = context.getResources();
|
||||
mScrollTouchSlop = r.getDimensionPixelSize(R.dimen.navigation_bar_min_swipe_distance);
|
||||
mQuickScrubController = new QuickScrubController(context);
|
||||
mQuickStepController = new QuickStepController(context);
|
||||
Dependency.get(TunerService.class).addTunable(this, KEY_DOCK_WINDOW_GESTURE);
|
||||
mOverviewProxyService.addCallback(mOverviewProxyListener);
|
||||
}
|
||||
|
||||
public void destroy() {
|
||||
Dependency.get(TunerService.class).removeTunable(this);
|
||||
mOverviewProxyService.removeCallback(mOverviewProxyListener);
|
||||
}
|
||||
|
||||
public void setComponents(RecentsComponent recentsComponent, Divider divider,
|
||||
@@ -118,65 +96,19 @@ public class NavigationBarGestureHelper implements TunerService.Tunable, Gesture
|
||||
mRecentsComponent = recentsComponent;
|
||||
mDivider = divider;
|
||||
mNavigationBarView = navigationBarView;
|
||||
mQuickScrubController.setComponents(mNavigationBarView);
|
||||
mQuickStepController.setComponents(mNavigationBarView);
|
||||
}
|
||||
|
||||
public void setBarState(boolean isVertical, boolean isRTL) {
|
||||
mIsVertical = isVertical;
|
||||
mQuickScrubController.setBarState(isVertical, isRTL);
|
||||
}
|
||||
|
||||
private boolean proxyMotionEvents(MotionEvent event) {
|
||||
final IOverviewProxy overviewProxy = mOverviewProxyService.getProxy();
|
||||
if (overviewProxy != null && mNavigationBarView.isQuickStepSwipeUpEnabled()) {
|
||||
mNavigationBarView.requestUnbufferedDispatch(event);
|
||||
event.transform(mTransformGlobalMatrix);
|
||||
try {
|
||||
if (event.getActionMasked() == MotionEvent.ACTION_DOWN) {
|
||||
overviewProxy.onPreMotionEvent(mNavigationBarView.getDownHitTarget());
|
||||
}
|
||||
overviewProxy.onMotionEvent(event);
|
||||
if (DEBUG_OVERVIEW_PROXY) {
|
||||
Log.d(TAG_OPS, "Send MotionEvent: " + event.toString());
|
||||
}
|
||||
return true;
|
||||
} catch (RemoteException e) {
|
||||
Log.e(TAG, "Callback failed", e);
|
||||
} finally {
|
||||
event.transform(mTransformLocalMatrix);
|
||||
}
|
||||
}
|
||||
return false;
|
||||
mQuickStepController.setBarState(isVertical, isRTL);
|
||||
}
|
||||
|
||||
public boolean onInterceptTouchEvent(MotionEvent event) {
|
||||
if (mNavigationBarView.inScreenPinning() || mStatusBar.isKeyguardShowing()
|
||||
|| !mStatusBar.isPresenterFullyCollapsed()) {
|
||||
if (!canHandleGestures()) {
|
||||
return false;
|
||||
}
|
||||
|
||||
int action = event.getActionMasked();
|
||||
switch (action) {
|
||||
case MotionEvent.ACTION_DOWN: {
|
||||
mTouchDownX = (int) event.getX();
|
||||
mTouchDownY = (int) event.getY();
|
||||
mTransformGlobalMatrix.set(Matrix.IDENTITY_MATRIX);
|
||||
mTransformLocalMatrix.set(Matrix.IDENTITY_MATRIX);
|
||||
mNavigationBarView.transformMatrixToGlobal(mTransformGlobalMatrix);
|
||||
mNavigationBarView.transformMatrixToLocal(mTransformLocalMatrix);
|
||||
mRecentsAnimationStarted = false;
|
||||
mQuickScrubController.setRecentsAnimationStarted(false /* started */);
|
||||
break;
|
||||
}
|
||||
}
|
||||
boolean handledByQuickscrub = mQuickScrubController.onInterceptTouchEvent(event);
|
||||
if (!handledByQuickscrub) {
|
||||
// Proxy motion events until we start intercepting for quickscrub
|
||||
proxyMotionEvents(event);
|
||||
}
|
||||
|
||||
boolean result = handledByQuickscrub;
|
||||
result |= mRecentsAnimationStarted;
|
||||
boolean result = mQuickStepController.onInterceptTouchEvent(event);
|
||||
if (mDockWindowEnabled) {
|
||||
result |= interceptDockWindowEvent(event);
|
||||
}
|
||||
@@ -184,18 +116,10 @@ public class NavigationBarGestureHelper implements TunerService.Tunable, Gesture
|
||||
}
|
||||
|
||||
public boolean onTouchEvent(MotionEvent event) {
|
||||
if (mNavigationBarView.inScreenPinning() || mStatusBar.isKeyguardShowing()
|
||||
|| !mStatusBar.isPresenterFullyCollapsed()) {
|
||||
if (!canHandleGestures()) {
|
||||
return false;
|
||||
}
|
||||
|
||||
// The same down event was just sent on intercept and therefore can be ignored here
|
||||
boolean ignoreProxyDownEvent = event.getAction() == MotionEvent.ACTION_DOWN
|
||||
&& mOverviewProxyService.getProxy() != null;
|
||||
boolean result = mQuickScrubController.onTouchEvent(event)
|
||||
|| ignoreProxyDownEvent
|
||||
|| proxyMotionEvents(event);
|
||||
result |= mRecentsAnimationStarted;
|
||||
boolean result = mQuickStepController.onTouchEvent(event);
|
||||
if (mDockWindowEnabled) {
|
||||
result |= handleDockWindowEvent(event);
|
||||
}
|
||||
@@ -203,17 +127,19 @@ public class NavigationBarGestureHelper implements TunerService.Tunable, Gesture
|
||||
}
|
||||
|
||||
public void onDraw(Canvas canvas) {
|
||||
if (mNavigationBarView.isQuickScrubEnabled()) {
|
||||
mQuickScrubController.onDraw(canvas);
|
||||
}
|
||||
mQuickStepController.onDraw(canvas);
|
||||
}
|
||||
|
||||
public void onLayout(boolean changed, int left, int top, int right, int bottom) {
|
||||
mQuickScrubController.onLayout(changed, left, top, right, bottom);
|
||||
mQuickStepController.onLayout(changed, left, top, right, bottom);
|
||||
}
|
||||
|
||||
public void onDarkIntensityChange(float intensity) {
|
||||
mQuickScrubController.onDarkIntensityChange(intensity);
|
||||
mQuickStepController.onDarkIntensityChange(intensity);
|
||||
}
|
||||
|
||||
public void onNavigationButtonLongPress(View v) {
|
||||
mQuickStepController.onNavigationButtonLongPress(v);
|
||||
}
|
||||
|
||||
private boolean interceptDockWindowEvent(MotionEvent event) {
|
||||
@@ -342,6 +268,11 @@ public class NavigationBarGestureHelper implements TunerService.Tunable, Gesture
|
||||
mVelocityTracker = null;
|
||||
}
|
||||
|
||||
private boolean canHandleGestures() {
|
||||
return !mNavigationBarView.inScreenPinning() && !mStatusBar.isKeyguardShowing()
|
||||
&& mStatusBar.isPresenterFullyCollapsed();
|
||||
}
|
||||
|
||||
private int calculateDragMode() {
|
||||
if (mIsVertical && !mDivider.getView().isHorizontalDivision()) {
|
||||
return DRAG_MODE_DIVIDER;
|
||||
|
||||
@@ -290,18 +290,12 @@ public class NavigationBarView extends FrameLayout implements PluginListener<Nav
|
||||
notifyVerticalChangedListener(mVertical);
|
||||
}
|
||||
|
||||
public void setRecentsAnimationStarted(boolean started) {
|
||||
public void onQuickStepStarted() {
|
||||
if (mRecentsOnboarding != null) {
|
||||
mRecentsOnboarding.onRecentsAnimationStarted();
|
||||
mRecentsOnboarding.onQuickStepStarted();
|
||||
}
|
||||
}
|
||||
|
||||
public void onConnectionChanged(boolean isConnected) {
|
||||
updateSlippery();
|
||||
updateNavButtonIcons();
|
||||
setUpSwipeUpOnboarding(isConnected);
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean onInterceptTouchEvent(MotionEvent event) {
|
||||
switch (event.getActionMasked()) {
|
||||
@@ -675,6 +669,10 @@ public class NavigationBarView extends FrameLayout implements PluginListener<Nav
|
||||
}
|
||||
}
|
||||
|
||||
public void onNavigationButtonLongPress(View v) {
|
||||
mGestureHelper.onNavigationButtonLongPress(v);
|
||||
}
|
||||
|
||||
public void onPanelExpandedChange(boolean expanded) {
|
||||
updateSlippery();
|
||||
}
|
||||
|
||||
@@ -25,6 +25,7 @@ import android.animation.ValueAnimator;
|
||||
import android.animation.ValueAnimator.AnimatorUpdateListener;
|
||||
import android.content.Context;
|
||||
import android.graphics.Canvas;
|
||||
import android.graphics.Matrix;
|
||||
import android.graphics.Paint;
|
||||
import android.graphics.Rect;
|
||||
import android.os.Handler;
|
||||
@@ -55,10 +56,10 @@ import static com.android.systemui.shared.system.NavigationBarCompat.HIT_TARGET_
|
||||
/**
|
||||
* Class to detect gestures on the navigation bar and implement quick scrub and switch.
|
||||
*/
|
||||
public class QuickScrubController extends GestureDetector.SimpleOnGestureListener implements
|
||||
public class QuickStepController extends GestureDetector.SimpleOnGestureListener implements
|
||||
GestureHelper {
|
||||
|
||||
private static final String TAG = "QuickScrubController";
|
||||
private static final String TAG = "QuickStepController";
|
||||
private static final int QUICK_SWITCH_FLING_VELOCITY = 0;
|
||||
private static final int ANIM_DURATION_MS = 200;
|
||||
private static final long LONG_PRESS_DELAY_MS = 225;
|
||||
@@ -75,7 +76,8 @@ public class QuickScrubController extends GestureDetector.SimpleOnGestureListene
|
||||
private boolean mDraggingActive;
|
||||
private boolean mQuickScrubActive;
|
||||
private boolean mAllowQuickSwitch;
|
||||
private boolean mRecentsAnimationStarted;
|
||||
private boolean mAllowGestureDetection;
|
||||
private boolean mQuickStepStarted;
|
||||
private float mDownOffset;
|
||||
private float mTranslation;
|
||||
private int mTouchDownX;
|
||||
@@ -101,6 +103,8 @@ public class QuickScrubController extends GestureDetector.SimpleOnGestureListene
|
||||
private final ValueAnimator mButtonAnimator;
|
||||
private final AnimatorSet mQuickScrubEndAnimator;
|
||||
private final Context mContext;
|
||||
private final Matrix mTransformGlobalMatrix = new Matrix();
|
||||
private final Matrix mTransformLocalMatrix = new Matrix();
|
||||
private final ArgbEvaluator mTrackColorEvaluator = new ArgbEvaluator();
|
||||
|
||||
private final AnimatorUpdateListener mTrackAnimatorListener = valueAnimator -> {
|
||||
@@ -123,7 +127,6 @@ public class QuickScrubController extends GestureDetector.SimpleOnGestureListene
|
||||
private AnimatorListenerAdapter mQuickScrubEndListener = new AnimatorListenerAdapter() {
|
||||
@Override
|
||||
public void onAnimationEnd(Animator animation) {
|
||||
mNavigationBarView.getHomeButton().setClickable(true);
|
||||
mQuickScrubActive = false;
|
||||
mTranslation = 0;
|
||||
mQuickScrubEndAnimator.setCurrentPlayTime(mQuickScrubEndAnimator.getDuration());
|
||||
@@ -165,7 +168,7 @@ public class QuickScrubController extends GestureDetector.SimpleOnGestureListene
|
||||
}
|
||||
};
|
||||
|
||||
public QuickScrubController(Context context) {
|
||||
public QuickStepController(Context context) {
|
||||
mContext = context;
|
||||
mScrollTouchSlop = ViewConfiguration.get(context).getScaledTouchSlop();
|
||||
mOverviewEventSender = Dependency.get(OverviewProxyService.class);
|
||||
@@ -197,31 +200,34 @@ public class QuickScrubController extends GestureDetector.SimpleOnGestureListene
|
||||
*/
|
||||
@Override
|
||||
public boolean onInterceptTouchEvent(MotionEvent event) {
|
||||
final ButtonDispatcher homeButton = mNavigationBarView.getHomeButton();
|
||||
if (!mNavigationBarView.isQuickScrubEnabled()) {
|
||||
homeButton.setDelayTouchFeedback(false);
|
||||
if (!mNavigationBarView.isQuickScrubEnabled()
|
||||
&& !mNavigationBarView.isQuickStepSwipeUpEnabled()) {
|
||||
mNavigationBarView.getHomeButton().setDelayTouchFeedback(false /* delay */);
|
||||
return false;
|
||||
}
|
||||
|
||||
mNavigationBarView.requestUnbufferedDispatch(event);
|
||||
return handleTouchEvent(event);
|
||||
}
|
||||
|
||||
/**
|
||||
* @return true if we want to handle touch events for quick scrub/switch and prevent proxying
|
||||
* the event to the overview service.
|
||||
* @return true if we want to handle touch events for quick scrub/switch or if down event (that
|
||||
* will get consumed and ignored). No events will be proxied to the overview service.
|
||||
*/
|
||||
@Override
|
||||
public boolean onTouchEvent(MotionEvent event) {
|
||||
return handleTouchEvent(event);
|
||||
// The same down event was just sent on intercept and therefore can be ignored here
|
||||
final boolean ignoreProxyDownEvent = event.getAction() == MotionEvent.ACTION_DOWN
|
||||
&& mOverviewEventSender.getProxy() != null;
|
||||
return ignoreProxyDownEvent || handleTouchEvent(event);
|
||||
}
|
||||
|
||||
private boolean handleTouchEvent(MotionEvent event) {
|
||||
final IOverviewProxy overviewProxy = mOverviewEventSender.getProxy();
|
||||
final ButtonDispatcher homeButton = mNavigationBarView.getHomeButton();
|
||||
if (mGestureDetector.onTouchEvent(event)) {
|
||||
// If the fling has been handled on UP, then skip proxying the UP
|
||||
return true;
|
||||
}
|
||||
final boolean homePressed = mNavigationBarView.getDownHitTarget() == HIT_TARGET_HOME;
|
||||
int action = event.getAction();
|
||||
switch (action & MotionEvent.ACTION_MASK) {
|
||||
case MotionEvent.ACTION_DOWN: {
|
||||
@@ -232,89 +238,99 @@ public class QuickScrubController extends GestureDetector.SimpleOnGestureListene
|
||||
mQuickScrubEndAnimator.end();
|
||||
}
|
||||
mHomeButtonView = homeButton.getCurrentView();
|
||||
if (mNavigationBarView.isQuickScrubEnabled()
|
||||
&& mNavigationBarView.getDownHitTarget() == HIT_TARGET_HOME) {
|
||||
mTouchDownX = x;
|
||||
mTouchDownY = y;
|
||||
homeButton.setDelayTouchFeedback(true);
|
||||
homeButton.setDelayTouchFeedback(true /* delay */);
|
||||
mTouchDownX = x;
|
||||
mTouchDownY = y;
|
||||
if (homePressed) {
|
||||
mHandler.postDelayed(mLongPressRunnable, LONG_PRESS_DELAY_MS);
|
||||
} else {
|
||||
homeButton.setDelayTouchFeedback(false);
|
||||
mTouchDownX = mTouchDownY = -1;
|
||||
}
|
||||
mTransformGlobalMatrix.set(Matrix.IDENTITY_MATRIX);
|
||||
mTransformLocalMatrix.set(Matrix.IDENTITY_MATRIX);
|
||||
mNavigationBarView.transformMatrixToGlobal(mTransformGlobalMatrix);
|
||||
mNavigationBarView.transformMatrixToLocal(mTransformLocalMatrix);
|
||||
mQuickStepStarted = false;
|
||||
mAllowQuickSwitch = true;
|
||||
mAllowGestureDetection = true;
|
||||
break;
|
||||
}
|
||||
case MotionEvent.ACTION_MOVE: {
|
||||
if (mTouchDownX != -1) {
|
||||
int x = (int) event.getX();
|
||||
int y = (int) event.getY();
|
||||
int xDiff = Math.abs(x - mTouchDownX);
|
||||
int yDiff = Math.abs(y - mTouchDownY);
|
||||
boolean exceededTouchSlopX = xDiff > mScrollTouchSlop && xDiff > yDiff;
|
||||
boolean exceededTouchSlopY = yDiff > mScrollTouchSlop && yDiff > xDiff;
|
||||
boolean exceededTouchSlop, exceededPerpendicularTouchSlop;
|
||||
int pos, touchDown, offset, trackSize;
|
||||
if (mQuickStepStarted || !mAllowGestureDetection){
|
||||
break;
|
||||
}
|
||||
int x = (int) event.getX();
|
||||
int y = (int) event.getY();
|
||||
int xDiff = Math.abs(x - mTouchDownX);
|
||||
int yDiff = Math.abs(y - mTouchDownY);
|
||||
boolean exceededTouchSlopX = xDiff > mScrollTouchSlop && xDiff > yDiff;
|
||||
boolean exceededTouchSlopY = yDiff > mScrollTouchSlop && yDiff > xDiff;
|
||||
boolean exceededTouchSlop, exceededPerpendicularTouchSlop;
|
||||
int pos, touchDown, offset, trackSize;
|
||||
|
||||
if (mIsVertical) {
|
||||
exceededTouchSlop = exceededTouchSlopY;
|
||||
exceededPerpendicularTouchSlop = exceededTouchSlopX;
|
||||
pos = y;
|
||||
touchDown = mTouchDownY;
|
||||
offset = pos - mTrackRect.top;
|
||||
trackSize = mTrackRect.height();
|
||||
} else {
|
||||
exceededTouchSlop = exceededTouchSlopX;
|
||||
exceededPerpendicularTouchSlop = exceededTouchSlopY;
|
||||
pos = x;
|
||||
touchDown = mTouchDownX;
|
||||
offset = pos - mTrackRect.left;
|
||||
trackSize = mTrackRect.width();
|
||||
}
|
||||
// Do not start scrubbing when dragging in the perpendicular direction if we
|
||||
// haven't already started quickscrub
|
||||
if (!mDraggingActive && !mQuickScrubActive && exceededPerpendicularTouchSlop) {
|
||||
mHandler.removeCallbacksAndMessages(null);
|
||||
return false;
|
||||
}
|
||||
if (!mDragPositive) {
|
||||
offset -= mIsVertical ? mTrackRect.height() : mTrackRect.width();
|
||||
if (mIsVertical) {
|
||||
exceededTouchSlop = exceededTouchSlopY;
|
||||
exceededPerpendicularTouchSlop = exceededTouchSlopX;
|
||||
pos = y;
|
||||
touchDown = mTouchDownY;
|
||||
offset = pos - mTrackRect.top;
|
||||
trackSize = mTrackRect.height();
|
||||
} else {
|
||||
exceededTouchSlop = exceededTouchSlopX;
|
||||
exceededPerpendicularTouchSlop = exceededTouchSlopY;
|
||||
pos = x;
|
||||
touchDown = mTouchDownX;
|
||||
offset = pos - mTrackRect.left;
|
||||
trackSize = mTrackRect.width();
|
||||
}
|
||||
// Decide to start quickstep if dragging away from the navigation bar, otherwise in
|
||||
// the parallel direction, decide to start quickscrub. Only one may run.
|
||||
if (!mDraggingActive && !mQuickScrubActive && exceededPerpendicularTouchSlop) {
|
||||
if (mNavigationBarView.isQuickStepSwipeUpEnabled()) {
|
||||
startQuickStep(event);
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
// Control the button movement
|
||||
if (!mDraggingActive && exceededTouchSlop && !mRecentsAnimationStarted) {
|
||||
boolean allowDrag = !mDragPositive
|
||||
? offset < 0 && pos < touchDown : offset >= 0 && pos > touchDown;
|
||||
if (allowDrag) {
|
||||
mDownOffset = offset;
|
||||
homeButton.setClickable(false);
|
||||
mDraggingActive = true;
|
||||
}
|
||||
// Do not handle quick scrub/switch if disabled or hit target is not home button
|
||||
if (!homePressed || !mNavigationBarView.isQuickScrubEnabled()) {
|
||||
break;
|
||||
}
|
||||
|
||||
if (!mDragPositive) {
|
||||
offset -= mIsVertical ? mTrackRect.height() : mTrackRect.width();
|
||||
}
|
||||
|
||||
// Control the button movement
|
||||
if (!mDraggingActive && exceededTouchSlop) {
|
||||
boolean allowDrag = !mDragPositive
|
||||
? offset < 0 && pos < touchDown : offset >= 0 && pos > touchDown;
|
||||
if (allowDrag) {
|
||||
mDownOffset = offset;
|
||||
homeButton.abortCurrentGesture();
|
||||
mDraggingActive = true;
|
||||
}
|
||||
if (mDraggingActive && (mDragPositive && offset >= 0
|
||||
|| !mDragPositive && offset <= 0)) {
|
||||
float scrubFraction =
|
||||
Utilities.clamp(Math.abs(offset) * 1f / trackSize, 0, 1);
|
||||
mTranslation = !mDragPositive
|
||||
? Utilities.clamp(offset - mDownOffset, -trackSize, 0)
|
||||
: Utilities.clamp(offset - mDownOffset, 0, trackSize);
|
||||
if (mQuickScrubActive) {
|
||||
try {
|
||||
mOverviewEventSender.getProxy().onQuickScrubProgress(scrubFraction);
|
||||
if (DEBUG_OVERVIEW_PROXY) {
|
||||
Log.d(TAG_OPS, "Quick Scrub Progress:" + scrubFraction);
|
||||
}
|
||||
} catch (RemoteException e) {
|
||||
Log.e(TAG, "Failed to send progress of quick scrub.", e);
|
||||
}
|
||||
if (mDraggingActive && (mDragPositive && offset >= 0
|
||||
|| !mDragPositive && offset <= 0)) {
|
||||
float scrubFraction = Utilities.clamp(Math.abs(offset) * 1f / trackSize, 0, 1);
|
||||
mTranslation = !mDragPositive
|
||||
? Utilities.clamp(offset - mDownOffset, -trackSize, 0)
|
||||
: Utilities.clamp(offset - mDownOffset, 0, trackSize);
|
||||
if (mQuickScrubActive) {
|
||||
try {
|
||||
mOverviewEventSender.getProxy().onQuickScrubProgress(scrubFraction);
|
||||
if (DEBUG_OVERVIEW_PROXY) {
|
||||
Log.d(TAG_OPS, "Quick Scrub Progress:" + scrubFraction);
|
||||
}
|
||||
} else {
|
||||
mTranslation /= SWITCH_STICKINESS;
|
||||
}
|
||||
if (mIsVertical) {
|
||||
mHomeButtonView.setTranslationY(mTranslation);
|
||||
} else {
|
||||
mHomeButtonView.setTranslationX(mTranslation);
|
||||
} catch (RemoteException e) {
|
||||
Log.e(TAG, "Failed to send progress of quick scrub.", e);
|
||||
}
|
||||
} else {
|
||||
mTranslation /= SWITCH_STICKINESS;
|
||||
}
|
||||
if (mIsVertical) {
|
||||
mHomeButtonView.setTranslationY(mTranslation);
|
||||
} else {
|
||||
mHomeButtonView.setTranslationX(mTranslation);
|
||||
}
|
||||
}
|
||||
break;
|
||||
@@ -324,11 +340,20 @@ public class QuickScrubController extends GestureDetector.SimpleOnGestureListene
|
||||
endQuickScrub(true /* animate */);
|
||||
break;
|
||||
}
|
||||
return mDraggingActive || mQuickScrubActive;
|
||||
|
||||
// Proxy motion events to launcher if not handled by quick scrub/switch
|
||||
boolean handled = mDraggingActive || mQuickScrubActive;
|
||||
if (!handled && mAllowGestureDetection) {
|
||||
proxyMotionEvents(event);
|
||||
}
|
||||
return handled || mQuickStepStarted;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onDraw(Canvas canvas) {
|
||||
if (mNavigationBarView.isQuickScrubEnabled()) {
|
||||
return;
|
||||
}
|
||||
int color = (int) mTrackColorEvaluator.evaluate(mDarkIntensity, mLightTrackColor,
|
||||
mDarkTrackColor);
|
||||
mTrackPaint.setColor(color);
|
||||
@@ -381,6 +406,31 @@ public class QuickScrubController extends GestureDetector.SimpleOnGestureListene
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onNavigationButtonLongPress(View v) {
|
||||
mAllowGestureDetection = false;
|
||||
mHandler.removeCallbacksAndMessages(null);
|
||||
}
|
||||
|
||||
private void startQuickStep(MotionEvent event) {
|
||||
mQuickStepStarted = true;
|
||||
event.transform(mTransformGlobalMatrix);
|
||||
try {
|
||||
mOverviewEventSender.getProxy().onQuickStep(event);
|
||||
if (DEBUG_OVERVIEW_PROXY) {
|
||||
Log.d(TAG_OPS, "Quick Step Start");
|
||||
}
|
||||
} catch (RemoteException e) {
|
||||
Log.e(TAG, "Failed to send quick step started.", e);
|
||||
} finally {
|
||||
event.transform(mTransformLocalMatrix);
|
||||
}
|
||||
mOverviewEventSender.notifyQuickStepStarted();
|
||||
mNavigationBarView.getHomeButton().abortCurrentGesture();
|
||||
cancelQuickSwitch();
|
||||
mHandler.removeCallbacksAndMessages(null);
|
||||
}
|
||||
|
||||
private void startQuickScrub() {
|
||||
if (!mQuickScrubActive && mDraggingActive) {
|
||||
mQuickScrubActive = true;
|
||||
@@ -396,9 +446,6 @@ public class QuickScrubController extends GestureDetector.SimpleOnGestureListene
|
||||
} catch (RemoteException e) {
|
||||
Log.e(TAG, "Failed to send start of quick scrub.", e);
|
||||
}
|
||||
} else {
|
||||
// After long press do not allow quick scrub/switch
|
||||
mTouchDownX = -1;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -421,11 +468,24 @@ public class QuickScrubController extends GestureDetector.SimpleOnGestureListene
|
||||
mDraggingActive = false;
|
||||
}
|
||||
|
||||
public void setRecentsAnimationStarted(boolean started) {
|
||||
mRecentsAnimationStarted = started;
|
||||
if (started) {
|
||||
cancelQuickSwitch();
|
||||
private boolean proxyMotionEvents(MotionEvent event) {
|
||||
final IOverviewProxy overviewProxy = mOverviewEventSender.getProxy();
|
||||
event.transform(mTransformGlobalMatrix);
|
||||
try {
|
||||
if (event.getActionMasked() == MotionEvent.ACTION_DOWN) {
|
||||
overviewProxy.onPreMotionEvent(mNavigationBarView.getDownHitTarget());
|
||||
}
|
||||
overviewProxy.onMotionEvent(event);
|
||||
if (DEBUG_OVERVIEW_PROXY) {
|
||||
Log.d(TAG_OPS, "Send MotionEvent: " + event.toString());
|
||||
}
|
||||
return true;
|
||||
} catch (RemoteException e) {
|
||||
Log.e(TAG, "Callback failed", e);
|
||||
} finally {
|
||||
event.transform(mTransformLocalMatrix);
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
public void cancelQuickSwitch() {
|
||||
@@ -224,8 +224,10 @@ public class KeyButtonView extends ImageView implements ButtonInterface {
|
||||
case MotionEvent.ACTION_DOWN:
|
||||
mDownTime = SystemClock.uptimeMillis();
|
||||
mLongClicked = false;
|
||||
mTouchDownX = (int) ev.getX();
|
||||
mTouchDownY = (int) ev.getY();
|
||||
|
||||
// Use raw X and Y to detect gestures in case a parent changes the x and y values
|
||||
mTouchDownX = (int) ev.getRawX();
|
||||
mTouchDownY = (int) ev.getRawY();
|
||||
if (mCode != 0) {
|
||||
sendEvent(KeyEvent.ACTION_DOWN, 0, mDownTime);
|
||||
} else {
|
||||
@@ -241,8 +243,8 @@ public class KeyButtonView extends ImageView implements ButtonInterface {
|
||||
postDelayed(mCheckLongPress, ViewConfiguration.getLongPressTimeout());
|
||||
break;
|
||||
case MotionEvent.ACTION_MOVE:
|
||||
x = (int)ev.getX();
|
||||
y = (int)ev.getY();
|
||||
x = (int)ev.getRawX();
|
||||
y = (int)ev.getRawY();
|
||||
boolean exceededTouchSlopX = Math.abs(x - mTouchDownX) > mTouchSlop;
|
||||
boolean exceededTouchSlopY = Math.abs(y - mTouchDownY) > mTouchSlop;
|
||||
if (exceededTouchSlopX || exceededTouchSlopY) {
|
||||
|
||||
Reference in New Issue
Block a user