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