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