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