blob: 80af5a6c026808a686aecc3d5dadce781d951c6d [file] [log] [blame]
Winson Chungfa7053782016-11-08 15:45:10 -08001/*
2 * Copyright (C) 2016 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.pip.phone;
18
19import android.app.IActivityManager;
20import android.graphics.PointF;
21import android.view.IPinnedStackController;
22import android.view.IPinnedStackListener;
23import android.view.IWindowManager;
24import android.view.MotionEvent;
25import android.view.VelocityTracker;
26import android.view.ViewConfiguration;
27
28/**
29 * This keeps track of the touch state throughout the current touch gesture.
30 */
31public class PipTouchState {
32
33 private ViewConfiguration mViewConfig;
34
35 private VelocityTracker mVelocityTracker;
36 private final PointF mDownTouch = new PointF();
37 private final PointF mDownDelta = new PointF();
38 private final PointF mLastTouch = new PointF();
39 private final PointF mLastDelta = new PointF();
40 private final PointF mVelocity = new PointF();
41 private boolean mIsDragging = false;
42 private boolean mStartedDragging = false;
43 private int mActivePointerId;
44
45 public PipTouchState(ViewConfiguration viewConfig) {
46 mViewConfig = viewConfig;
47 }
48
49 /**
50 * Processess a given touch event and updates the state.
51 */
52 public void onTouchEvent(MotionEvent ev) {
53 switch (ev.getAction()) {
54 case MotionEvent.ACTION_DOWN: {
55 // Initialize the velocity tracker
56 initOrResetVelocityTracker();
57 mActivePointerId = ev.getPointerId(0);
58 mLastTouch.set(ev.getX(), ev.getY());
59 mDownTouch.set(mLastTouch);
60 mIsDragging = false;
61 mStartedDragging = false;
62 break;
63 }
64 case MotionEvent.ACTION_MOVE: {
65 // Update the velocity tracker
66 mVelocityTracker.addMovement(ev);
67 int pointerIndex = ev.findPointerIndex(mActivePointerId);
68 float x = ev.getX(pointerIndex);
69 float y = ev.getY(pointerIndex);
70 mLastDelta.set(x - mLastTouch.x, y - mLastTouch.y);
71 mDownDelta.set(x - mDownTouch.x, y - mDownTouch.y);
72
73 boolean hasMovedBeyondTap = mDownDelta.length() > mViewConfig.getScaledTouchSlop();
74 if (!mIsDragging) {
75 if (hasMovedBeyondTap) {
76 mIsDragging = true;
77 mStartedDragging = true;
78 }
79 } else {
80 mStartedDragging = false;
81 }
82 mLastTouch.set(x, y);
83 break;
84 }
85 case MotionEvent.ACTION_POINTER_UP: {
86 // Update the velocity tracker
87 mVelocityTracker.addMovement(ev);
88
89 int pointerIndex = ev.getActionIndex();
90 int pointerId = ev.getPointerId(pointerIndex);
91 if (pointerId == mActivePointerId) {
92 // Select a new active pointer id and reset the movement state
93 final int newPointerIndex = (pointerIndex == 0) ? 1 : 0;
94 mActivePointerId = ev.getPointerId(newPointerIndex);
95 mLastTouch.set(ev.getX(newPointerIndex), ev.getY(newPointerIndex));
96 }
97 break;
98 }
99 case MotionEvent.ACTION_UP: {
100 // Update the velocity tracker
101 mVelocityTracker.addMovement(ev);
102 mVelocityTracker.computeCurrentVelocity(1000,
103 mViewConfig.getScaledMaximumFlingVelocity());
104 mVelocity.set(mVelocityTracker.getXVelocity(), mVelocityTracker.getYVelocity());
105
106 int pointerIndex = ev.findPointerIndex(mActivePointerId);
107 mLastTouch.set(ev.getX(pointerIndex), ev.getY(pointerIndex));
108
109 // Fall through to clean up
110 }
111 case MotionEvent.ACTION_CANCEL: {
112 recycleVelocityTracker();
113 break;
114 }
115 }
116 }
117
118 /**
119 * @return the velocity of the active touch pointer at the point it is lifted off the screen.
120 */
121 public PointF getVelocity() {
122 return mVelocity;
123 }
124
125 /**
126 * @return the last touch position of the active pointer.
127 */
128 public PointF getLastTouchPosition() {
129 return mLastTouch;
130 }
131
132 /**
133 * @return the movement delta between the last handled touch event and the previous touch
134 * position.
135 */
136 public PointF getLastTouchDelta() {
137 return mLastDelta;
138 }
139
140 /**
141 * @return the movement delta between the last handled touch event and the down touch
142 * position.
143 */
144 public PointF getDownTouchDelta() {
145 return mDownDelta;
146 }
147
148 /**
149 * @return whether the user has started dragging.
150 */
151 public boolean isDragging() {
152 return mIsDragging;
153 }
154
155 /**
156 * @return whether the user has started dragging just in the last handled touch event.
157 */
158 public boolean startedDragging() {
159 return mStartedDragging;
160 }
161
162 private void initOrResetVelocityTracker() {
163 if (mVelocityTracker == null) {
164 mVelocityTracker = VelocityTracker.obtain();
165 } else {
166 mVelocityTracker.clear();
167 }
168 }
169
170 private void recycleVelocityTracker() {
171 if (mVelocityTracker != null) {
172 mVelocityTracker.recycle();
173 mVelocityTracker = null;
174 }
175 }
176}