1 /* 2 * Copyright (C) 2014 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 17 package com.android.systemui.statusbar.phone; 18 19 import android.content.Context; 20 import android.view.GestureDetector; 21 import android.view.MotionEvent; 22 import android.view.ViewConfiguration; 23 import com.android.systemui.statusbar.BaseStatusBar; 24 25 public class NavigationBarViewTaskSwitchHelper extends GestureDetector.SimpleOnGestureListener { 26 27 private BaseStatusBar mBar; 28 private boolean mIsVertical; 29 private boolean mIsRTL; 30 31 private final GestureDetector mTaskSwitcherDetector; 32 private final int mScrollTouchSlop; 33 private final int mMinFlingVelocity; 34 private int mTouchDownX; 35 private int mTouchDownY; 36 37 public NavigationBarViewTaskSwitchHelper(Context context) { 38 ViewConfiguration configuration = ViewConfiguration.get(context); 39 mScrollTouchSlop = 4 * configuration.getScaledTouchSlop(); 40 mMinFlingVelocity = configuration.getScaledMinimumFlingVelocity(); 41 mTaskSwitcherDetector = new GestureDetector(context, this); 42 } 43 44 public void setBar(BaseStatusBar phoneStatusBar) { 45 mBar = phoneStatusBar; 46 } 47 48 public void setBarState(boolean isVertical, boolean isRTL) { 49 mIsVertical = isVertical; 50 mIsRTL = isRTL; 51 } 52 53 public boolean onInterceptTouchEvent(MotionEvent event) { 54 // If we move more than a fixed amount, then start capturing for the 55 // task switcher detector 56 mTaskSwitcherDetector.onTouchEvent(event); 57 int action = event.getAction(); 58 boolean intercepted = false; 59 switch (action & MotionEvent.ACTION_MASK) { 60 case MotionEvent.ACTION_DOWN: { 61 mTouchDownX = (int) event.getX(); 62 mTouchDownY = (int) event.getY(); 63 break; 64 } 65 case MotionEvent.ACTION_MOVE: { 66 int x = (int) event.getX(); 67 int y = (int) event.getY(); 68 int xDiff = Math.abs(x - mTouchDownX); 69 int yDiff = Math.abs(y - mTouchDownY); 70 boolean exceededTouchSlop = !mIsVertical 71 ? xDiff > mScrollTouchSlop && xDiff > yDiff 72 : yDiff > mScrollTouchSlop && yDiff > xDiff; 73 if (exceededTouchSlop) { 74 return true; 75 } 76 break; 77 } 78 case MotionEvent.ACTION_CANCEL: 79 case MotionEvent.ACTION_UP: 80 break; 81 } 82 return intercepted; 83 } 84 85 public boolean onTouchEvent(MotionEvent event) { 86 return mTaskSwitcherDetector.onTouchEvent(event); 87 } 88 89 @Override 90 public boolean onFling(MotionEvent e1, MotionEvent e2, float velocityX, float velocityY) { 91 float absVelX = Math.abs(velocityX); 92 float absVelY = Math.abs(velocityY); 93 boolean isValidFling = absVelX > mMinFlingVelocity && 94 mIsVertical ? (absVelY > absVelX) : (absVelX > absVelY); 95 if (isValidFling) { 96 boolean showNext; 97 if (!mIsRTL) { 98 showNext = mIsVertical ? (velocityY < 0) : (velocityX < 0); 99 } else { 100 // In RTL, vertical is still the same, but horizontal is flipped 101 showNext = mIsVertical ? (velocityY < 0) : (velocityX > 0); 102 } 103 if (showNext) { 104 mBar.showNextAffiliatedTask(); 105 } else { 106 mBar.showPreviousAffiliatedTask(); 107 } 108 } 109 return true; 110 } 111 } 112