1 package js.kbars; 2 3 import android.content.Context; 4 import android.util.Log; 5 import android.view.MotionEvent; 6 7 public class SystemGestureDebugger { 8 private static final boolean DEBUG = false; 9 private static final int MAX_TRACKED_POINTERS = 32; 10 private static final int SWIPE_FROM_BOTTOM = 2; 11 private static final int SWIPE_FROM_RIGHT = 3; 12 private static final int SWIPE_FROM_TOP = 1; 13 private static final int SWIPE_NONE = 0; 14 private static final long SWIPE_TIMEOUT_MS = 500; 15 private static final String TAG = Util.logTag(SystemGestureDebugger.class); 16 private static final int UNTRACKED_POINTER = -1; 17 private final Callbacks mCallbacks; 18 private final float[] mCurrentX = new float[MAX_TRACKED_POINTERS]; 19 private final float[] mCurrentY = new float[MAX_TRACKED_POINTERS]; 20 private boolean mDebugFireable; 21 private final int[] mDownPointerId = new int[MAX_TRACKED_POINTERS]; 22 private int mDownPointers; 23 private final long[] mDownTime = new long[MAX_TRACKED_POINTERS]; 24 private final float[] mDownX = new float[MAX_TRACKED_POINTERS]; 25 private final float[] mDownY = new float[MAX_TRACKED_POINTERS]; 26 private final long[] mElapsedThreshold = new long[MAX_TRACKED_POINTERS]; 27 private final int mSwipeDistanceThreshold; 28 private boolean mSwipeFireable; 29 private final int mSwipeStartThreshold; 30 int screenHeight; 31 int screenWidth; 32 33 interface Callbacks { onDebug()34 void onDebug(); 35 onSwipeFromBottom()36 void onSwipeFromBottom(); 37 onSwipeFromRight()38 void onSwipeFromRight(); 39 onSwipeFromTop()40 void onSwipeFromTop(); 41 } 42 43 public static class DownPointerInfo { 44 public float currentX; 45 public float currentY; 46 public int downPointerId; 47 public long downTime; 48 public float downX; 49 public float downY; 50 public long elapsedThreshold; 51 } 52 53 public static class ThresholdInfo { 54 public int distance; 55 public long elapsed; 56 public int start; 57 } 58 SystemGestureDebugger(Context context, Callbacks callbacks)59 public SystemGestureDebugger(Context context, Callbacks callbacks) { 60 this.mCallbacks = (Callbacks) checkNull("callbacks", callbacks); 61 this.mSwipeStartThreshold = ((Context) checkNull("context", context)).getResources().getDimensionPixelSize(((Integer) Util.getField("com.android.internal.R$dimen", "status_bar_height")).intValue()); 62 this.mSwipeDistanceThreshold = this.mSwipeStartThreshold; 63 Log.d(TAG, String.format("startThreshold=%s endThreshold=%s", new Object[]{Integer.valueOf(this.mSwipeStartThreshold), Integer.valueOf(this.mSwipeDistanceThreshold)})); 64 } 65 checkNull(String name, T arg)66 private static <T> T checkNull(String name, T arg) { 67 if (arg != null) { 68 return arg; 69 } 70 throw new IllegalArgumentException(new StringBuilder(String.valueOf(name)).append(" must not be null").toString()); 71 } 72 onPointerEvent(MotionEvent event)73 public void onPointerEvent(MotionEvent event) { 74 boolean z = true; 75 boolean z2 = DEBUG; 76 switch (event.getActionMasked()) { 77 case SWIPE_NONE /*0*/: 78 this.mSwipeFireable = true; 79 this.mDebugFireable = true; 80 this.mDownPointers = SWIPE_NONE; 81 captureDown(event, SWIPE_NONE); 82 return; 83 case 1: 84 case SWIPE_FROM_RIGHT /*3*/: 85 this.mSwipeFireable = DEBUG; 86 this.mDebugFireable = DEBUG; 87 return; 88 case 2: 89 if (this.mSwipeFireable) { 90 int swipe = detectSwipe(event); 91 if (swipe == 0) { 92 z2 = true; 93 } 94 this.mSwipeFireable = z2; 95 if (swipe == 1) { 96 this.mCallbacks.onSwipeFromTop(); 97 return; 98 } else if (swipe == 2) { 99 this.mCallbacks.onSwipeFromBottom(); 100 return; 101 } else if (swipe == SWIPE_FROM_RIGHT) { 102 this.mCallbacks.onSwipeFromRight(); 103 return; 104 } else { 105 return; 106 } 107 } 108 return; 109 case 5: 110 captureDown(event, event.getActionIndex()); 111 if (this.mDebugFireable) { 112 if (event.getPointerCount() >= 5) { 113 z = DEBUG; 114 } 115 this.mDebugFireable = z; 116 if (!this.mDebugFireable) { 117 this.mCallbacks.onDebug(); 118 return; 119 } 120 return; 121 } 122 return; 123 default: 124 return; 125 } 126 } 127 captureDown(MotionEvent event, int pointerIndex)128 private void captureDown(MotionEvent event, int pointerIndex) { 129 int i = findIndex(event.getPointerId(pointerIndex)); 130 if (i != UNTRACKED_POINTER) { 131 this.mDownX[i] = event.getX(pointerIndex); 132 this.mDownY[i] = event.getY(pointerIndex); 133 this.mDownTime[i] = event.getEventTime(); 134 } 135 } 136 findIndex(int pointerId)137 private int findIndex(int pointerId) { 138 for (int i = SWIPE_NONE; i < this.mDownPointers; i++) { 139 if (this.mDownPointerId[i] == pointerId) { 140 return i; 141 } 142 } 143 if (this.mDownPointers == MAX_TRACKED_POINTERS || pointerId == UNTRACKED_POINTER) { 144 return UNTRACKED_POINTER; 145 } 146 int[] iArr = this.mDownPointerId; 147 int i2 = this.mDownPointers; 148 this.mDownPointers = i2 + 1; 149 iArr[i2] = pointerId; 150 return this.mDownPointers + UNTRACKED_POINTER; 151 } 152 detectSwipe(MotionEvent move)153 private int detectSwipe(MotionEvent move) { 154 int historySize = move.getHistorySize(); 155 int pointerCount = move.getPointerCount(); 156 for (int p = SWIPE_NONE; p < pointerCount; p++) { 157 int i = findIndex(move.getPointerId(p)); 158 if (i != UNTRACKED_POINTER) { 159 int swipe; 160 for (int h = SWIPE_NONE; h < historySize; h++) { 161 swipe = detectSwipe(i, move.getHistoricalEventTime(h), move.getHistoricalX(p, h), move.getHistoricalY(p, h)); 162 if (swipe != 0) { 163 return swipe; 164 } 165 } 166 swipe = detectSwipe(i, move.getEventTime(), move.getX(p), move.getY(p)); 167 if (swipe != 0) { 168 return swipe; 169 } 170 } 171 } 172 return SWIPE_NONE; 173 } 174 detectSwipe(int i, long time, float x, float y)175 private int detectSwipe(int i, long time, float x, float y) { 176 float fromX = this.mDownX[i]; 177 float fromY = this.mDownY[i]; 178 long elapsed = time - this.mDownTime[i]; 179 this.mCurrentX[i] = x; 180 this.mCurrentY[i] = y; 181 boolean reachedThreshold = ((fromY > ((float) this.mSwipeStartThreshold) || y <= ((float) this.mSwipeDistanceThreshold) + fromY) && ((fromY < ((float) (this.screenHeight - this.mSwipeStartThreshold)) || y >= fromY - ((float) this.mSwipeDistanceThreshold)) && (fromX < ((float) (this.screenWidth - this.mSwipeStartThreshold)) || x >= fromX - ((float) this.mSwipeDistanceThreshold)))) ? DEBUG : true; 182 if (!reachedThreshold) { 183 this.mElapsedThreshold[i] = elapsed; 184 } 185 if (fromY <= ((float) this.mSwipeStartThreshold) && y > ((float) this.mSwipeDistanceThreshold) + fromY && elapsed < SWIPE_TIMEOUT_MS) { 186 return 1; 187 } 188 if (fromY >= ((float) (this.screenHeight - this.mSwipeStartThreshold)) && y < fromY - ((float) this.mSwipeDistanceThreshold) && elapsed < SWIPE_TIMEOUT_MS) { 189 return 2; 190 } 191 if (fromX < ((float) (this.screenWidth - this.mSwipeStartThreshold)) || x >= fromX - ((float) this.mSwipeDistanceThreshold) || elapsed >= SWIPE_TIMEOUT_MS) { 192 return SWIPE_NONE; 193 } 194 return SWIPE_FROM_RIGHT; 195 } 196 getDownPointers()197 public int getDownPointers() { 198 return this.mDownPointers; 199 } 200 getDownPointerInfo(int index, DownPointerInfo out)201 public void getDownPointerInfo(int index, DownPointerInfo out) { 202 out.downPointerId = this.mDownPointerId[index]; 203 out.downX = this.mDownX[index]; 204 out.downY = this.mDownY[index]; 205 out.downTime = this.mDownTime[index]; 206 out.currentX = this.mCurrentX[index]; 207 out.currentY = this.mCurrentY[index]; 208 out.elapsedThreshold = this.mElapsedThreshold[index]; 209 } 210 getThresholdInfo(ThresholdInfo out)211 public void getThresholdInfo(ThresholdInfo out) { 212 out.start = this.mSwipeStartThreshold; 213 out.distance = this.mSwipeDistanceThreshold; 214 out.elapsed = SWIPE_TIMEOUT_MS; 215 } 216 } 217