MotionEvent.java revision d41ba666d12a24ee4624ea9a009151e6165e3775
1/* 2 * Copyright (C) 2007 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 android.view; 18 19import android.os.Parcel; 20import android.os.Parcelable; 21import android.os.SystemClock; 22import android.util.Log; 23 24/** 25 * Object used to report movement (mouse, pen, finger, trackball) events. This 26 * class may hold either absolute or relative movements, depending on what 27 * it is being used for. 28 */ 29public final class MotionEvent implements Parcelable { 30 static final boolean DEBUG_POINTERS = false; 31 32 /** 33 * Bit mask of the parts of the action code that are the action itself. 34 */ 35 public static final int ACTION_MASK = 0xff; 36 37 /** 38 * Constant for {@link #getAction}: A pressed gesture has started, the 39 * motion contains the initial starting location. 40 */ 41 public static final int ACTION_DOWN = 0; 42 43 /** 44 * Constant for {@link #getAction}: A pressed gesture has finished, the 45 * motion contains the final release location as well as any intermediate 46 * points since the last down or move event. 47 */ 48 public static final int ACTION_UP = 1; 49 50 /** 51 * Constant for {@link #getAction}: A change has happened during a 52 * press gesture (between {@link #ACTION_DOWN} and {@link #ACTION_UP}). 53 * The motion contains the most recent point, as well as any intermediate 54 * points since the last down or move event. 55 */ 56 public static final int ACTION_MOVE = 2; 57 58 /** 59 * Constant for {@link #getAction}: The current gesture has been aborted. 60 * You will not receive any more points in it. You should treat this as 61 * an up event, but not perform any action that you normally would. 62 */ 63 public static final int ACTION_CANCEL = 3; 64 65 /** 66 * Constant for {@link #getAction}: A movement has happened outside of the 67 * normal bounds of the UI element. This does not provide a full gesture, 68 * but only the initial location of the movement/touch. 69 */ 70 public static final int ACTION_OUTSIDE = 4; 71 72 /** 73 * A non-primary pointer has gone down. The bits in 74 * {@link #ACTION_POINTER_ID_MASK} indicate which pointer changed. 75 */ 76 public static final int ACTION_POINTER_DOWN = 5; 77 78 /** 79 * Synonym for {@link #ACTION_POINTER_DOWN} with 80 * {@link #ACTION_POINTER_ID_MASK} of 0: the primary pointer has gone done. 81 */ 82 public static final int ACTION_POINTER_1_DOWN = ACTION_POINTER_DOWN | 0x0000; 83 84 /** 85 * Synonym for {@link #ACTION_POINTER_DOWN} with 86 * {@link #ACTION_POINTER_ID_MASK} of 1: the secondary pointer has gone done. 87 */ 88 public static final int ACTION_POINTER_2_DOWN = ACTION_POINTER_DOWN | 0x0100; 89 90 /** 91 * Synonym for {@link #ACTION_POINTER_DOWN} with 92 * {@link #ACTION_POINTER_ID_MASK} of 2: the tertiary pointer has gone done. 93 */ 94 public static final int ACTION_POINTER_3_DOWN = ACTION_POINTER_DOWN | 0x0200; 95 96 /** 97 * A non-primary pointer has gone up. The bits in 98 * {@link #ACTION_POINTER_ID_MASK} indicate which pointer changed. 99 */ 100 public static final int ACTION_POINTER_UP = 6; 101 102 /** 103 * Synonym for {@link #ACTION_POINTER_UP} with 104 * {@link #ACTION_POINTER_ID_MASK} of 0: the primary pointer has gone up. 105 */ 106 public static final int ACTION_POINTER_1_UP = ACTION_POINTER_UP | 0x0000; 107 108 /** 109 * Synonym for {@link #ACTION_POINTER_UP} with 110 * {@link #ACTION_POINTER_ID_MASK} of 1: the secondary pointer has gone up. 111 */ 112 public static final int ACTION_POINTER_2_UP = ACTION_POINTER_UP | 0x0100; 113 114 /** 115 * Synonym for {@link #ACTION_POINTER_UP} with 116 * {@link #ACTION_POINTER_ID_MASK} of 2: the tertiary pointer has gone up. 117 */ 118 public static final int ACTION_POINTER_3_UP = ACTION_POINTER_UP | 0x0200; 119 120 /** 121 * Bits in the action code that represent a pointer ID, used with 122 * {@link #ACTION_POINTER_DOWN} and {@link #ACTION_POINTER_UP}. Pointer IDs 123 * start at 0, with 0 being the primary (first) pointer in the motion. Note 124 * that this not <em>not</em> an index into the array of pointer values, 125 * which is compacted to only contain pointers that are down; the pointer 126 * ID for a particular index can be found with {@link #findPointerIndex}. 127 */ 128 public static final int ACTION_POINTER_ID_MASK = 0xff00; 129 130 /** 131 * Bit shift for the action bits holding the pointer identifier as 132 * defined by {@link #ACTION_POINTER_ID_MASK}. 133 */ 134 public static final int ACTION_POINTER_ID_SHIFT = 8; 135 136 private static final boolean TRACK_RECYCLED_LOCATION = false; 137 138 /** 139 * Flag indicating the motion event intersected the top edge of the screen. 140 */ 141 public static final int EDGE_TOP = 0x00000001; 142 143 /** 144 * Flag indicating the motion event intersected the bottom edge of the screen. 145 */ 146 public static final int EDGE_BOTTOM = 0x00000002; 147 148 /** 149 * Flag indicating the motion event intersected the left edge of the screen. 150 */ 151 public static final int EDGE_LEFT = 0x00000004; 152 153 /** 154 * Flag indicating the motion event intersected the right edge of the screen. 155 */ 156 public static final int EDGE_RIGHT = 0x00000008; 157 158 /** 159 * Offset for the sample's X coordinate. 160 * @hide 161 */ 162 static public final int SAMPLE_X = 0; 163 164 /** 165 * Offset for the sample's Y coordinate. 166 * @hide 167 */ 168 static public final int SAMPLE_Y = 1; 169 170 /** 171 * Offset for the sample's X coordinate. 172 * @hide 173 */ 174 static public final int SAMPLE_PRESSURE = 2; 175 176 /** 177 * Offset for the sample's X coordinate. 178 * @hide 179 */ 180 static public final int SAMPLE_SIZE = 3; 181 182 /** 183 * Number of data items for each sample. 184 * @hide 185 */ 186 static public final int NUM_SAMPLE_DATA = 4; 187 188 static private final int BASE_AVAIL_POINTERS = 2; 189 static private final int BASE_AVAIL_SAMPLES = 8; 190 191 static private final int MAX_RECYCLED = 10; 192 static private Object gRecyclerLock = new Object(); 193 static private int gRecyclerUsed = 0; 194 static private MotionEvent gRecyclerTop = null; 195 196 private long mDownTime; 197 private long mEventTimeNano; 198 private int mAction; 199 private float mRawX; 200 private float mRawY; 201 private float mXPrecision; 202 private float mYPrecision; 203 private int mDeviceId; 204 private int mEdgeFlags; 205 private int mMetaState; 206 207 // Here is the actual event data. Note that the order of the array 208 // is a little odd: the first entry is the most recent, and the ones 209 // following it are the historical data from oldest to newest. This 210 // allows us to easily retrieve the most recent data, without having 211 // to copy the arrays every time a new sample is added. 212 213 private int mNumPointers; 214 private int mNumSamples; 215 // Array of mNumPointers size of identifiers for each pointer of data. 216 private int[] mPointerIdentifiers; 217 // Array of (mNumSamples * mNumPointers * NUM_SAMPLE_DATA) size of event data. 218 private float[] mDataSamples; 219 // Array of mNumSamples size of time stamps. 220 private long[] mTimeSamples; 221 222 private MotionEvent mNext; 223 private RuntimeException mRecycledLocation; 224 private boolean mRecycled; 225 226 private MotionEvent() { 227 mPointerIdentifiers = new int[BASE_AVAIL_POINTERS]; 228 mDataSamples = new float[BASE_AVAIL_POINTERS*BASE_AVAIL_SAMPLES*NUM_SAMPLE_DATA]; 229 mTimeSamples = new long[BASE_AVAIL_SAMPLES]; 230 } 231 232 static private MotionEvent obtain() { 233 synchronized (gRecyclerLock) { 234 if (gRecyclerTop == null) { 235 return new MotionEvent(); 236 } 237 MotionEvent ev = gRecyclerTop; 238 gRecyclerTop = ev.mNext; 239 gRecyclerUsed--; 240 ev.mRecycledLocation = null; 241 ev.mRecycled = false; 242 return ev; 243 } 244 } 245 246 /** 247 * Create a new MotionEvent, filling in all of the basic values that 248 * define the motion. 249 * 250 * @param downTime The time (in ms) when the user originally pressed down to start 251 * a stream of position events. This must be obtained from {@link SystemClock#uptimeMillis()}. 252 * @param eventTime The the time (in ms) when this specific event was generated. This 253 * must be obtained from {@link SystemClock#uptimeMillis()}. 254 * @param eventTimeNano The the time (in ns) when this specific event was generated. This 255 * must be obtained from {@link System#nanoTime()}. 256 * @param action The kind of action being performed -- one of either 257 * {@link #ACTION_DOWN}, {@link #ACTION_MOVE}, {@link #ACTION_UP}, or 258 * {@link #ACTION_CANCEL}. 259 * @param pointers The number of points that will be in this event. 260 * @param inPointerIds An array of <em>pointers</em> values providing 261 * an identifier for each pointer. 262 * @param inData An array of <em>pointers*NUM_SAMPLE_DATA</em> of initial 263 * data samples for the event. 264 * @param metaState The state of any meta / modifier keys that were in effect when 265 * the event was generated. 266 * @param xPrecision The precision of the X coordinate being reported. 267 * @param yPrecision The precision of the Y coordinate being reported. 268 * @param deviceId The id for the device that this event came from. An id of 269 * zero indicates that the event didn't come from a physical device; other 270 * numbers are arbitrary and you shouldn't depend on the values. 271 * @param edgeFlags A bitfield indicating which edges, if any, where touched by this 272 * MotionEvent. 273 * 274 * @hide 275 */ 276 static public MotionEvent obtainNano(long downTime, long eventTime, long eventTimeNano, 277 int action, int pointers, int[] inPointerIds, float[] inData, int metaState, 278 float xPrecision, float yPrecision, int deviceId, int edgeFlags) { 279 MotionEvent ev = obtain(); 280 ev.mDeviceId = deviceId; 281 ev.mEdgeFlags = edgeFlags; 282 ev.mDownTime = downTime; 283 ev.mEventTimeNano = eventTimeNano; 284 ev.mAction = action; 285 ev.mMetaState = metaState; 286 ev.mRawX = inData[SAMPLE_X]; 287 ev.mRawY = inData[SAMPLE_Y]; 288 ev.mXPrecision = xPrecision; 289 ev.mYPrecision = yPrecision; 290 ev.mNumPointers = pointers; 291 ev.mNumSamples = 1; 292 293 System.arraycopy(inPointerIds, 0, ev.mPointerIdentifiers, 0, pointers); 294 System.arraycopy(inData, 0, ev.mDataSamples, 0, pointers * NUM_SAMPLE_DATA); 295 ev.mTimeSamples[0] = eventTime; 296 297 if (DEBUG_POINTERS) { 298 StringBuilder sb = new StringBuilder(128); 299 sb.append("New:"); 300 for (int i=0; i<pointers; i++) { 301 sb.append(" #"); 302 sb.append(ev.mPointerIdentifiers[i]); 303 sb.append("("); 304 sb.append(ev.mDataSamples[(i*NUM_SAMPLE_DATA) + SAMPLE_X]); 305 sb.append(","); 306 sb.append(ev.mDataSamples[(i*NUM_SAMPLE_DATA) + SAMPLE_Y]); 307 sb.append(")"); 308 } 309 Log.v("MotionEvent", sb.toString()); 310 } 311 312 return ev; 313 } 314 315 /** 316 * Create a new MotionEvent, filling in all of the basic values that 317 * define the motion. 318 * 319 * @param downTime The time (in ms) when the user originally pressed down to start 320 * a stream of position events. This must be obtained from {@link SystemClock#uptimeMillis()}. 321 * @param eventTime The the time (in ms) when this specific event was generated. This 322 * must be obtained from {@link SystemClock#uptimeMillis()}. 323 * @param action The kind of action being performed -- one of either 324 * {@link #ACTION_DOWN}, {@link #ACTION_MOVE}, {@link #ACTION_UP}, or 325 * {@link #ACTION_CANCEL}. 326 * @param x The X coordinate of this event. 327 * @param y The Y coordinate of this event. 328 * @param pressure The current pressure of this event. The pressure generally 329 * ranges from 0 (no pressure at all) to 1 (normal pressure), however 330 * values higher than 1 may be generated depending on the calibration of 331 * the input device. 332 * @param size A scaled value of the approximate size of the area being pressed when 333 * touched with the finger. The actual value in pixels corresponding to the finger 334 * touch is normalized with a device specific range of values 335 * and scaled to a value between 0 and 1. 336 * @param metaState The state of any meta / modifier keys that were in effect when 337 * the event was generated. 338 * @param xPrecision The precision of the X coordinate being reported. 339 * @param yPrecision The precision of the Y coordinate being reported. 340 * @param deviceId The id for the device that this event came from. An id of 341 * zero indicates that the event didn't come from a physical device; other 342 * numbers are arbitrary and you shouldn't depend on the values. 343 * @param edgeFlags A bitfield indicating which edges, if any, where touched by this 344 * MotionEvent. 345 */ 346 static public MotionEvent obtain(long downTime, long eventTime, int action, 347 float x, float y, float pressure, float size, int metaState, 348 float xPrecision, float yPrecision, int deviceId, int edgeFlags) { 349 MotionEvent ev = obtain(); 350 ev.mDeviceId = deviceId; 351 ev.mEdgeFlags = edgeFlags; 352 ev.mDownTime = downTime; 353 ev.mEventTimeNano = eventTime * 1000000; 354 ev.mAction = action; 355 ev.mMetaState = metaState; 356 ev.mXPrecision = xPrecision; 357 ev.mYPrecision = yPrecision; 358 359 ev.mNumPointers = 1; 360 ev.mNumSamples = 1; 361 int[] pointerIds = ev.mPointerIdentifiers; 362 pointerIds[0] = 0; 363 float[] data = ev.mDataSamples; 364 data[SAMPLE_X] = ev.mRawX = x; 365 data[SAMPLE_Y] = ev.mRawY = y; 366 data[SAMPLE_PRESSURE] = pressure; 367 data[SAMPLE_SIZE] = size; 368 ev.mTimeSamples[0] = eventTime; 369 370 return ev; 371 } 372 373 /** 374 * Create a new MotionEvent, filling in all of the basic values that 375 * define the motion. 376 * 377 * @param downTime The time (in ms) when the user originally pressed down to start 378 * a stream of position events. This must be obtained from {@link SystemClock#uptimeMillis()}. 379 * @param eventTime The the time (in ms) when this specific event was generated. This 380 * must be obtained from {@link SystemClock#uptimeMillis()}. 381 * @param action The kind of action being performed -- one of either 382 * {@link #ACTION_DOWN}, {@link #ACTION_MOVE}, {@link #ACTION_UP}, or 383 * {@link #ACTION_CANCEL}. 384 * @param pointers The number of pointers that are active in this event. 385 * @param x The X coordinate of this event. 386 * @param y The Y coordinate of this event. 387 * @param pressure The current pressure of this event. The pressure generally 388 * ranges from 0 (no pressure at all) to 1 (normal pressure), however 389 * values higher than 1 may be generated depending on the calibration of 390 * the input device. 391 * @param size A scaled value of the approximate size of the area being pressed when 392 * touched with the finger. The actual value in pixels corresponding to the finger 393 * touch is normalized with a device specific range of values 394 * and scaled to a value between 0 and 1. 395 * @param metaState The state of any meta / modifier keys that were in effect when 396 * the event was generated. 397 * @param xPrecision The precision of the X coordinate being reported. 398 * @param yPrecision The precision of the Y coordinate being reported. 399 * @param deviceId The id for the device that this event came from. An id of 400 * zero indicates that the event didn't come from a physical device; other 401 * numbers are arbitrary and you shouldn't depend on the values. 402 * @param edgeFlags A bitfield indicating which edges, if any, where touched by this 403 * MotionEvent. 404 */ 405 static public MotionEvent obtain(long downTime, long eventTime, int action, 406 int pointers, float x, float y, float pressure, float size, int metaState, 407 float xPrecision, float yPrecision, int deviceId, int edgeFlags) { 408 MotionEvent ev = obtain(); 409 ev.mDeviceId = deviceId; 410 ev.mEdgeFlags = edgeFlags; 411 ev.mDownTime = downTime; 412 ev.mEventTimeNano = eventTime * 1000000; 413 ev.mAction = action; 414 ev.mNumPointers = pointers; 415 ev.mMetaState = metaState; 416 ev.mXPrecision = xPrecision; 417 ev.mYPrecision = yPrecision; 418 419 ev.mNumPointers = 1; 420 ev.mNumSamples = 1; 421 int[] pointerIds = ev.mPointerIdentifiers; 422 pointerIds[0] = 0; 423 float[] data = ev.mDataSamples; 424 data[SAMPLE_X] = ev.mRawX = x; 425 data[SAMPLE_Y] = ev.mRawY = y; 426 data[SAMPLE_PRESSURE] = pressure; 427 data[SAMPLE_SIZE] = size; 428 ev.mTimeSamples[0] = eventTime; 429 430 return ev; 431 } 432 433 /** 434 * Create a new MotionEvent, filling in a subset of the basic motion 435 * values. Those not specified here are: device id (always 0), pressure 436 * and size (always 1), x and y precision (always 1), and edgeFlags (always 0). 437 * 438 * @param downTime The time (in ms) when the user originally pressed down to start 439 * a stream of position events. This must be obtained from {@link SystemClock#uptimeMillis()}. 440 * @param eventTime The the time (in ms) when this specific event was generated. This 441 * must be obtained from {@link SystemClock#uptimeMillis()}. 442 * @param action The kind of action being performed -- one of either 443 * {@link #ACTION_DOWN}, {@link #ACTION_MOVE}, {@link #ACTION_UP}, or 444 * {@link #ACTION_CANCEL}. 445 * @param x The X coordinate of this event. 446 * @param y The Y coordinate of this event. 447 * @param metaState The state of any meta / modifier keys that were in effect when 448 * the event was generated. 449 */ 450 static public MotionEvent obtain(long downTime, long eventTime, int action, 451 float x, float y, int metaState) { 452 MotionEvent ev = obtain(); 453 ev.mDeviceId = 0; 454 ev.mEdgeFlags = 0; 455 ev.mDownTime = downTime; 456 ev.mEventTimeNano = eventTime * 1000000; 457 ev.mAction = action; 458 ev.mNumPointers = 1; 459 ev.mMetaState = metaState; 460 ev.mXPrecision = 1.0f; 461 ev.mYPrecision = 1.0f; 462 463 ev.mNumPointers = 1; 464 ev.mNumSamples = 1; 465 int[] pointerIds = ev.mPointerIdentifiers; 466 pointerIds[0] = 0; 467 float[] data = ev.mDataSamples; 468 data[SAMPLE_X] = ev.mRawX = x; 469 data[SAMPLE_Y] = ev.mRawY = y; 470 data[SAMPLE_PRESSURE] = 1.0f; 471 data[SAMPLE_SIZE] = 1.0f; 472 ev.mTimeSamples[0] = eventTime; 473 474 return ev; 475 } 476 477 /** 478 * Scales down the coordination of this event by the given scale. 479 * 480 * @hide 481 */ 482 public void scale(float scale) { 483 mRawX *= scale; 484 mRawY *= scale; 485 mXPrecision *= scale; 486 mYPrecision *= scale; 487 float[] history = mDataSamples; 488 final int length = mNumPointers * mNumSamples * NUM_SAMPLE_DATA; 489 for (int i = 0; i < length; i += NUM_SAMPLE_DATA) { 490 history[i + SAMPLE_X] *= scale; 491 history[i + SAMPLE_Y] *= scale; 492 // no need to scale pressure 493 history[i + SAMPLE_SIZE] *= scale; // TODO: square this? 494 } 495 } 496 497 /** 498 * Create a new MotionEvent, copying from an existing one. 499 */ 500 static public MotionEvent obtain(MotionEvent o) { 501 MotionEvent ev = obtain(); 502 ev.mDeviceId = o.mDeviceId; 503 ev.mEdgeFlags = o.mEdgeFlags; 504 ev.mDownTime = o.mDownTime; 505 ev.mEventTimeNano = o.mEventTimeNano; 506 ev.mAction = o.mAction; 507 ev.mNumPointers = o.mNumPointers; 508 ev.mRawX = o.mRawX; 509 ev.mRawY = o.mRawY; 510 ev.mMetaState = o.mMetaState; 511 ev.mXPrecision = o.mXPrecision; 512 ev.mYPrecision = o.mYPrecision; 513 514 final int NS = ev.mNumSamples = o.mNumSamples; 515 if (ev.mTimeSamples.length >= NS) { 516 System.arraycopy(o.mTimeSamples, 0, ev.mTimeSamples, 0, NS); 517 } else { 518 ev.mTimeSamples = (long[])o.mTimeSamples.clone(); 519 } 520 521 final int NP = (ev.mNumPointers=o.mNumPointers); 522 if (ev.mPointerIdentifiers.length >= NP) { 523 System.arraycopy(o.mPointerIdentifiers, 0, ev.mPointerIdentifiers, 0, NP); 524 } else { 525 ev.mPointerIdentifiers = (int[])o.mPointerIdentifiers.clone(); 526 } 527 528 final int ND = NP * NS * NUM_SAMPLE_DATA; 529 if (ev.mDataSamples.length >= ND) { 530 System.arraycopy(o.mDataSamples, 0, ev.mDataSamples, 0, ND); 531 } else { 532 ev.mDataSamples = (float[])o.mDataSamples.clone(); 533 } 534 535 return ev; 536 } 537 538 /** 539 * Recycle the MotionEvent, to be re-used by a later caller. After calling 540 * this function you must not ever touch the event again. 541 */ 542 public void recycle() { 543 // Ensure recycle is only called once! 544 if (TRACK_RECYCLED_LOCATION) { 545 if (mRecycledLocation != null) { 546 throw new RuntimeException(toString() + " recycled twice!", mRecycledLocation); 547 } 548 mRecycledLocation = new RuntimeException("Last recycled here"); 549 } else if (mRecycled) { 550 throw new RuntimeException(toString() + " recycled twice!"); 551 } 552 553 //Log.w("MotionEvent", "Recycling event " + this, mRecycledLocation); 554 synchronized (gRecyclerLock) { 555 if (gRecyclerUsed < MAX_RECYCLED) { 556 gRecyclerUsed++; 557 mNumSamples = 0; 558 mNext = gRecyclerTop; 559 gRecyclerTop = this; 560 } 561 } 562 } 563 564 /** 565 * Return the kind of action being performed -- one of either 566 * {@link #ACTION_DOWN}, {@link #ACTION_MOVE}, {@link #ACTION_UP}, or 567 * {@link #ACTION_CANCEL}. 568 */ 569 public final int getAction() { 570 return mAction; 571 } 572 573 /** 574 * Returns the time (in ms) when the user originally pressed down to start 575 * a stream of position events. 576 */ 577 public final long getDownTime() { 578 return mDownTime; 579 } 580 581 /** 582 * Returns the time (in ms) when this specific event was generated. 583 */ 584 public final long getEventTime() { 585 return mTimeSamples[0]; 586 } 587 588 /** 589 * Returns the time (in ns) when this specific event was generated. 590 * The value is in nanosecond precision but it may not have nanosecond accuracy. 591 * 592 * @hide 593 */ 594 public final long getEventTimeNano() { 595 return mEventTimeNano; 596 } 597 598 /** 599 * {@link #getX(int)} for the first pointer index (may be an 600 * arbitrary pointer identifier). 601 */ 602 public final float getX() { 603 return mDataSamples[SAMPLE_X]; 604 } 605 606 /** 607 * {@link #getY(int)} for the first pointer index (may be an 608 * arbitrary pointer identifier). 609 */ 610 public final float getY() { 611 return mDataSamples[SAMPLE_Y]; 612 } 613 614 /** 615 * {@link #getPressure(int)} for the first pointer index (may be an 616 * arbitrary pointer identifier). 617 */ 618 public final float getPressure() { 619 return mDataSamples[SAMPLE_PRESSURE]; 620 } 621 622 /** 623 * {@link #getSize(int)} for the first pointer index (may be an 624 * arbitrary pointer identifier). 625 */ 626 public final float getSize() { 627 return mDataSamples[SAMPLE_SIZE]; 628 } 629 630 /** 631 * The number of pointers of data contained in this event. Always 632 * >= 1. 633 */ 634 public final int getPointerCount() { 635 return mNumPointers; 636 } 637 638 /** 639 * Return the pointer identifier associated with a particular pointer 640 * data index is this event. The identifier tells you the actual pointer 641 * number associated with the data, accounting for individual pointers 642 * going up and down since the start of the current gesture. 643 * @param pointerIndex Raw index of pointer to retrieve. Value may be from 0 644 * (the first pointer that is down) to {@link #getPointerCount()}-1. 645 */ 646 public final int getPointerId(int pointerIndex) { 647 return mPointerIdentifiers[pointerIndex]; 648 } 649 650 /** 651 * Given a pointer identifier, find the index of its data in the event. 652 * 653 * @param pointerId The identifier of the pointer to be found. 654 * @return Returns either the index of the pointer (for use with 655 * {@link #getX(int) et al.), or -1 if there is no data available for 656 * that pointer identifier. 657 */ 658 public final int findPointerIndex(int pointerId) { 659 int i = mNumPointers; 660 while (i > 0) { 661 i--; 662 if (mPointerIdentifiers[i] == pointerId) { 663 return i; 664 } 665 } 666 return -1; 667 } 668 669 /** 670 * Returns the X coordinate of this event for the given pointer 671 * <em>index</em> (use {@link #getPointerId(int)} to find the pointer 672 * identifier for this index). 673 * Whole numbers are pixels; the 674 * value may have a fraction for input devices that are sub-pixel precise. 675 * @param pointerIndex Raw index of pointer to retrieve. Value may be from 0 676 * (the first pointer that is down) to {@link #getPointerCount()}-1. 677 */ 678 public final float getX(int pointerIndex) { 679 return mDataSamples[(pointerIndex*NUM_SAMPLE_DATA) + SAMPLE_X]; 680 } 681 682 /** 683 * Returns the Y coordinate of this event for the given pointer 684 * <em>index</em> (use {@link #getPointerId(int)} to find the pointer 685 * identifier for this index). 686 * Whole numbers are pixels; the 687 * value may have a fraction for input devices that are sub-pixel precise. 688 * @param pointerIndex Raw index of pointer to retrieve. Value may be from 0 689 * (the first pointer that is down) to {@link #getPointerCount()}-1. 690 */ 691 public final float getY(int pointerIndex) { 692 return mDataSamples[(pointerIndex*NUM_SAMPLE_DATA) + SAMPLE_Y]; 693 } 694 695 /** 696 * Returns the current pressure of this event for the given pointer 697 * <em>index</em> (use {@link #getPointerId(int)} to find the pointer 698 * identifier for this index). 699 * The pressure generally 700 * ranges from 0 (no pressure at all) to 1 (normal pressure), however 701 * values higher than 1 may be generated depending on the calibration of 702 * the input device. 703 * @param pointerIndex Raw index of pointer to retrieve. Value may be from 0 704 * (the first pointer that is down) to {@link #getPointerCount()}-1. 705 */ 706 public final float getPressure(int pointerIndex) { 707 return mDataSamples[(pointerIndex*NUM_SAMPLE_DATA) + SAMPLE_PRESSURE]; 708 } 709 710 /** 711 * Returns a scaled value of the approximate size for the given pointer 712 * <em>index</em> (use {@link #getPointerId(int)} to find the pointer 713 * identifier for this index). 714 * This represents some approximation of the area of the screen being 715 * pressed; the actual value in pixels corresponding to the 716 * touch is normalized with the device specific range of values 717 * and scaled to a value between 0 and 1. The value of size can be used to 718 * determine fat touch events. 719 * @param pointerIndex Raw index of pointer to retrieve. Value may be from 0 720 * (the first pointer that is down) to {@link #getPointerCount()}-1. 721 */ 722 public final float getSize(int pointerIndex) { 723 return mDataSamples[(pointerIndex*NUM_SAMPLE_DATA) + SAMPLE_SIZE]; 724 } 725 726 /** 727 * Returns the state of any meta / modifier keys that were in effect when 728 * the event was generated. This is the same values as those 729 * returned by {@link KeyEvent#getMetaState() KeyEvent.getMetaState}. 730 * 731 * @return an integer in which each bit set to 1 represents a pressed 732 * meta key 733 * 734 * @see KeyEvent#getMetaState() 735 */ 736 public final int getMetaState() { 737 return mMetaState; 738 } 739 740 /** 741 * Returns the original raw X coordinate of this event. For touch 742 * events on the screen, this is the original location of the event 743 * on the screen, before it had been adjusted for the containing window 744 * and views. 745 */ 746 public final float getRawX() { 747 return mRawX; 748 } 749 750 /** 751 * Returns the original raw Y coordinate of this event. For touch 752 * events on the screen, this is the original location of the event 753 * on the screen, before it had been adjusted for the containing window 754 * and views. 755 */ 756 public final float getRawY() { 757 return mRawY; 758 } 759 760 /** 761 * Return the precision of the X coordinates being reported. You can 762 * multiple this number with {@link #getX} to find the actual hardware 763 * value of the X coordinate. 764 * @return Returns the precision of X coordinates being reported. 765 */ 766 public final float getXPrecision() { 767 return mXPrecision; 768 } 769 770 /** 771 * Return the precision of the Y coordinates being reported. You can 772 * multiple this number with {@link #getY} to find the actual hardware 773 * value of the Y coordinate. 774 * @return Returns the precision of Y coordinates being reported. 775 */ 776 public final float getYPrecision() { 777 return mYPrecision; 778 } 779 780 /** 781 * Returns the number of historical points in this event. These are 782 * movements that have occurred between this event and the previous event. 783 * This only applies to ACTION_MOVE events -- all other actions will have 784 * a size of 0. 785 * 786 * @return Returns the number of historical points in the event. 787 */ 788 public final int getHistorySize() { 789 return mNumSamples - 1; 790 } 791 792 /** 793 * Returns the time that a historical movement occurred between this event 794 * and the previous event. Only applies to ACTION_MOVE events. 795 * 796 * @param pos Which historical value to return; must be less than 797 * {@link #getHistorySize} 798 * 799 * @see #getHistorySize 800 * @see #getEventTime 801 */ 802 public final long getHistoricalEventTime(int pos) { 803 return mTimeSamples[pos + 1]; 804 } 805 806 /** 807 * {@link #getHistoricalX(int)} for the first pointer index (may be an 808 * arbitrary pointer identifier). 809 */ 810 public final float getHistoricalX(int pos) { 811 return mDataSamples[((pos + 1) * NUM_SAMPLE_DATA * mNumPointers) + SAMPLE_X]; 812 } 813 814 /** 815 * {@link #getHistoricalY(int)} for the first pointer index (may be an 816 * arbitrary pointer identifier). 817 */ 818 public final float getHistoricalY(int pos) { 819 return mDataSamples[((pos + 1) * NUM_SAMPLE_DATA * mNumPointers) + SAMPLE_Y]; 820 } 821 822 /** 823 * {@link #getHistoricalPressure(int)} for the first pointer index (may be an 824 * arbitrary pointer identifier). 825 */ 826 public final float getHistoricalPressure(int pos) { 827 return mDataSamples[((pos + 1) * NUM_SAMPLE_DATA * mNumPointers) + SAMPLE_PRESSURE]; 828 } 829 830 /** 831 * {@link #getHistoricalSize(int)} for the first pointer index (may be an 832 * arbitrary pointer identifier). 833 */ 834 public final float getHistoricalSize(int pos) { 835 return mDataSamples[((pos + 1) * NUM_SAMPLE_DATA * mNumPointers) + SAMPLE_SIZE]; 836 } 837 838 /** 839 * Returns a historical X coordinate, as per {@link #getX(int)}, that 840 * occurred between this event and the previous event for the given pointer. 841 * Only applies to ACTION_MOVE events. 842 * 843 * @param pointerIndex Raw index of pointer to retrieve. Value may be from 0 844 * (the first pointer that is down) to {@link #getPointerCount()}-1. 845 * @param pos Which historical value to return; must be less than 846 * {@link #getHistorySize} 847 * 848 * @see #getHistorySize 849 * @see #getX 850 */ 851 public final float getHistoricalX(int pointerIndex, int pos) { 852 return mDataSamples[((pos + 1) * NUM_SAMPLE_DATA * mNumPointers) 853 + (pointerIndex * NUM_SAMPLE_DATA) + SAMPLE_X]; 854 } 855 856 /** 857 * Returns a historical Y coordinate, as per {@link #getY(int)}, that 858 * occurred between this event and the previous event for the given pointer. 859 * Only applies to ACTION_MOVE events. 860 * 861 * @param pointerIndex Raw index of pointer to retrieve. Value may be from 0 862 * (the first pointer that is down) to {@link #getPointerCount()}-1. 863 * @param pos Which historical value to return; must be less than 864 * {@link #getHistorySize} 865 * 866 * @see #getHistorySize 867 * @see #getY 868 */ 869 public final float getHistoricalY(int pointerIndex, int pos) { 870 return mDataSamples[((pos + 1) * NUM_SAMPLE_DATA * mNumPointers) 871 + (pointerIndex * NUM_SAMPLE_DATA) + SAMPLE_Y]; 872 } 873 874 /** 875 * Returns a historical pressure coordinate, as per {@link #getPressure(int)}, 876 * that occurred between this event and the previous event for the given 877 * pointer. Only applies to ACTION_MOVE events. 878 * 879 * @param pointerIndex Raw index of pointer to retrieve. Value may be from 0 880 * (the first pointer that is down) to {@link #getPointerCount()}-1. 881 * @param pos Which historical value to return; must be less than 882 * {@link #getHistorySize} 883 * 884 * @see #getHistorySize 885 * @see #getPressure 886 */ 887 public final float getHistoricalPressure(int pointerIndex, int pos) { 888 return mDataSamples[((pos + 1) * NUM_SAMPLE_DATA * mNumPointers) 889 + (pointerIndex * NUM_SAMPLE_DATA) + SAMPLE_PRESSURE]; 890 } 891 892 /** 893 * Returns a historical size coordinate, as per {@link #getSize(int)}, that 894 * occurred between this event and the previous event for the given pointer. 895 * Only applies to ACTION_MOVE events. 896 * 897 * @param pointerIndex Raw index of pointer to retrieve. Value may be from 0 898 * (the first pointer that is down) to {@link #getPointerCount()}-1. 899 * @param pos Which historical value to return; must be less than 900 * {@link #getHistorySize} 901 * 902 * @see #getHistorySize 903 * @see #getSize 904 */ 905 public final float getHistoricalSize(int pointerIndex, int pos) { 906 return mDataSamples[((pos + 1) * NUM_SAMPLE_DATA * mNumPointers) 907 + (pointerIndex * NUM_SAMPLE_DATA) + SAMPLE_SIZE]; 908 } 909 910 /** 911 * Return the id for the device that this event came from. An id of 912 * zero indicates that the event didn't come from a physical device; other 913 * numbers are arbitrary and you shouldn't depend on the values. 914 */ 915 public final int getDeviceId() { 916 return mDeviceId; 917 } 918 919 /** 920 * Returns a bitfield indicating which edges, if any, where touched by this 921 * MotionEvent. For touch events, clients can use this to determine if the 922 * user's finger was touching the edge of the display. 923 * 924 * @see #EDGE_LEFT 925 * @see #EDGE_TOP 926 * @see #EDGE_RIGHT 927 * @see #EDGE_BOTTOM 928 */ 929 public final int getEdgeFlags() { 930 return mEdgeFlags; 931 } 932 933 934 /** 935 * Sets the bitfield indicating which edges, if any, where touched by this 936 * MotionEvent. 937 * 938 * @see #getEdgeFlags() 939 */ 940 public final void setEdgeFlags(int flags) { 941 mEdgeFlags = flags; 942 } 943 944 /** 945 * Sets this event's action. 946 */ 947 public final void setAction(int action) { 948 mAction = action; 949 } 950 951 /** 952 * Adjust this event's location. 953 * @param deltaX Amount to add to the current X coordinate of the event. 954 * @param deltaY Amount to add to the current Y coordinate of the event. 955 */ 956 public final void offsetLocation(float deltaX, float deltaY) { 957 final int N = mNumPointers*mNumSamples*4; 958 final float[] pos = mDataSamples; 959 for (int i=0; i<N; i+=NUM_SAMPLE_DATA) { 960 pos[i+SAMPLE_X] += deltaX; 961 pos[i+SAMPLE_Y] += deltaY; 962 } 963 } 964 965 /** 966 * Set this event's location. Applies {@link #offsetLocation} with a 967 * delta from the current location to the given new location. 968 * 969 * @param x New absolute X location. 970 * @param y New absolute Y location. 971 */ 972 public final void setLocation(float x, float y) { 973 float deltaX = x-mDataSamples[SAMPLE_X]; 974 float deltaY = y-mDataSamples[SAMPLE_Y]; 975 if (deltaX != 0 || deltaY != 0) { 976 offsetLocation(deltaX, deltaY); 977 } 978 } 979 980 /** 981 * Add a new movement to the batch of movements in this event. The event's 982 * current location, position and size is updated to the new values. In 983 * the future, the current values in the event will be added to a list of 984 * historic values. 985 * 986 * @param eventTime The time stamp for this data. 987 * @param x The new X position. 988 * @param y The new Y position. 989 * @param pressure The new pressure. 990 * @param size The new size. 991 * @param metaState Meta key state. 992 */ 993 public final void addBatch(long eventTime, float x, float y, 994 float pressure, float size, int metaState) { 995 float[] data = mDataSamples; 996 long[] times = mTimeSamples; 997 998 final int NP = mNumPointers; 999 final int NS = mNumSamples; 1000 final int NI = NP*NS; 1001 final int ND = NI * NUM_SAMPLE_DATA; 1002 if (data.length <= ND) { 1003 final int NEW_ND = ND + (NP * (BASE_AVAIL_SAMPLES * NUM_SAMPLE_DATA)); 1004 float[] newData = new float[NEW_ND]; 1005 System.arraycopy(data, 0, newData, 0, ND); 1006 mDataSamples = data = newData; 1007 } 1008 if (times.length <= NS) { 1009 final int NEW_NS = NS + BASE_AVAIL_SAMPLES; 1010 long[] newHistoryTimes = new long[NEW_NS]; 1011 System.arraycopy(times, 0, newHistoryTimes, 0, NS); 1012 mTimeSamples = times = newHistoryTimes; 1013 } 1014 1015 times[NS] = times[0]; 1016 times[0] = eventTime; 1017 1018 final int pos = NS*NUM_SAMPLE_DATA; 1019 data[pos+SAMPLE_X] = data[SAMPLE_X]; 1020 data[pos+SAMPLE_Y] = data[SAMPLE_Y]; 1021 data[pos+SAMPLE_PRESSURE] = data[SAMPLE_PRESSURE]; 1022 data[pos+SAMPLE_SIZE] = data[SAMPLE_SIZE]; 1023 data[SAMPLE_X] = x; 1024 data[SAMPLE_Y] = y; 1025 data[SAMPLE_PRESSURE] = pressure; 1026 data[SAMPLE_SIZE] = size; 1027 mNumSamples = NS+1; 1028 1029 mRawX = x; 1030 mRawY = y; 1031 mMetaState |= metaState; 1032 } 1033 1034 /** 1035 * Add a new movement to the batch of movements in this event. The 1036 * input data must contain (NUM_SAMPLE_DATA * {@link #getPointerCount()}) 1037 * samples of data. 1038 * 1039 * @param eventTime The time stamp for this data. 1040 * @param inData The actual data. 1041 * @param metaState Meta key state. 1042 * 1043 * @hide 1044 */ 1045 public final void addBatch(long eventTime, float[] inData, int metaState) { 1046 float[] data = mDataSamples; 1047 long[] times = mTimeSamples; 1048 1049 final int NP = mNumPointers; 1050 final int NS = mNumSamples; 1051 final int NI = NP*NS; 1052 final int ND = NI * NUM_SAMPLE_DATA; 1053 if (data.length <= ND) { 1054 final int NEW_ND = ND + (NP * (BASE_AVAIL_SAMPLES * NUM_SAMPLE_DATA)); 1055 float[] newData = new float[NEW_ND]; 1056 System.arraycopy(data, 0, newData, 0, ND); 1057 mDataSamples = data = newData; 1058 } 1059 if (times.length <= NS) { 1060 final int NEW_NS = NS + BASE_AVAIL_SAMPLES; 1061 long[] newHistoryTimes = new long[NEW_NS]; 1062 System.arraycopy(times, 0, newHistoryTimes, 0, NS); 1063 mTimeSamples = times = newHistoryTimes; 1064 } 1065 1066 times[NS] = times[0]; 1067 times[0] = eventTime; 1068 1069 System.arraycopy(data, 0, data, ND, mNumPointers*NUM_SAMPLE_DATA); 1070 System.arraycopy(inData, 0, data, 0, mNumPointers*NUM_SAMPLE_DATA); 1071 1072 mNumSamples = NS+1; 1073 1074 mRawX = inData[SAMPLE_X]; 1075 mRawY = inData[SAMPLE_Y]; 1076 mMetaState |= metaState; 1077 1078 if (DEBUG_POINTERS) { 1079 StringBuilder sb = new StringBuilder(128); 1080 sb.append("Add:"); 1081 for (int i=0; i<mNumPointers; i++) { 1082 sb.append(" #"); 1083 sb.append(mPointerIdentifiers[i]); 1084 sb.append("("); 1085 sb.append(mDataSamples[(i*NUM_SAMPLE_DATA) + SAMPLE_X]); 1086 sb.append(","); 1087 sb.append(mDataSamples[(i*NUM_SAMPLE_DATA) + SAMPLE_Y]); 1088 sb.append(")"); 1089 } 1090 Log.v("MotionEvent", sb.toString()); 1091 } 1092 } 1093 1094 @Override 1095 public String toString() { 1096 return "MotionEvent{" + Integer.toHexString(System.identityHashCode(this)) 1097 + " action=" + mAction + " x=" + getX() 1098 + " y=" + getY() + " pressure=" + getPressure() + " size=" + getSize() + "}"; 1099 } 1100 1101 public static final Parcelable.Creator<MotionEvent> CREATOR 1102 = new Parcelable.Creator<MotionEvent>() { 1103 public MotionEvent createFromParcel(Parcel in) { 1104 MotionEvent ev = obtain(); 1105 ev.readFromParcel(in); 1106 return ev; 1107 } 1108 1109 public MotionEvent[] newArray(int size) { 1110 return new MotionEvent[size]; 1111 } 1112 }; 1113 1114 public int describeContents() { 1115 return 0; 1116 } 1117 1118 public void writeToParcel(Parcel out, int flags) { 1119 out.writeLong(mDownTime); 1120 out.writeLong(mEventTimeNano); 1121 out.writeInt(mAction); 1122 out.writeInt(mMetaState); 1123 out.writeFloat(mRawX); 1124 out.writeFloat(mRawY); 1125 final int NP = mNumPointers; 1126 out.writeInt(NP); 1127 final int NS = mNumSamples; 1128 out.writeInt(NS); 1129 final int NI = NP*NS; 1130 if (NI > 0) { 1131 int i; 1132 int[] state = mPointerIdentifiers; 1133 for (i=0; i<NP; i++) { 1134 out.writeInt(state[i]); 1135 } 1136 final int ND = NI*NUM_SAMPLE_DATA; 1137 float[] history = mDataSamples; 1138 for (i=0; i<ND; i++) { 1139 out.writeFloat(history[i]); 1140 } 1141 long[] times = mTimeSamples; 1142 for (i=0; i<NS; i++) { 1143 out.writeLong(times[i]); 1144 } 1145 } 1146 out.writeFloat(mXPrecision); 1147 out.writeFloat(mYPrecision); 1148 out.writeInt(mDeviceId); 1149 out.writeInt(mEdgeFlags); 1150 } 1151 1152 private void readFromParcel(Parcel in) { 1153 mDownTime = in.readLong(); 1154 mEventTimeNano = in.readLong(); 1155 mAction = in.readInt(); 1156 mMetaState = in.readInt(); 1157 mRawX = in.readFloat(); 1158 mRawY = in.readFloat(); 1159 final int NP = in.readInt(); 1160 mNumPointers = NP; 1161 final int NS = in.readInt(); 1162 mNumSamples = NS; 1163 final int NI = NP*NS; 1164 if (NI > 0) { 1165 int[] ids = mPointerIdentifiers; 1166 if (ids.length < NP) { 1167 mPointerIdentifiers = ids = new int[NP]; 1168 } 1169 for (int i=0; i<NP; i++) { 1170 ids[i] = in.readInt(); 1171 } 1172 float[] history = mDataSamples; 1173 final int ND = NI*NUM_SAMPLE_DATA; 1174 if (history.length < ND) { 1175 mDataSamples = history = new float[ND]; 1176 } 1177 for (int i=0; i<ND; i++) { 1178 history[i] = in.readFloat(); 1179 } 1180 long[] times = mTimeSamples; 1181 if (times == null || times.length < NS) { 1182 mTimeSamples = times = new long[NS]; 1183 } 1184 for (int i=0; i<NS; i++) { 1185 times[i] = in.readLong(); 1186 } 1187 } 1188 mXPrecision = in.readFloat(); 1189 mYPrecision = in.readFloat(); 1190 mDeviceId = in.readInt(); 1191 mEdgeFlags = in.readInt(); 1192 } 1193 1194} 1195