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
17package com.android.systemui.statusbar.phone;
18
19import android.content.Context;
20import android.content.res.Resources;
21import android.view.GestureDetector;
22import android.view.MotionEvent;
23import android.view.ViewConfiguration;
24import com.android.systemui.R;
25import com.android.systemui.statusbar.BaseStatusBar;
26
27public 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