Parcel.java revision 703e5d3c7fbeb8ca0978045db01d40318f838612
1/* 2 * Copyright (C) 2006 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.os; 18 19import android.text.TextUtils; 20import android.util.Log; 21import android.util.SparseArray; 22import android.util.SparseBooleanArray; 23 24import java.io.ByteArrayInputStream; 25import java.io.ByteArrayOutputStream; 26import java.io.FileDescriptor; 27import java.io.FileNotFoundException; 28import java.io.IOException; 29import java.io.ObjectInputStream; 30import java.io.ObjectOutputStream; 31import java.io.Serializable; 32import java.lang.reflect.Field; 33import java.util.ArrayList; 34import java.util.HashMap; 35import java.util.List; 36import java.util.Map; 37import java.util.Set; 38 39/** 40 * Container for a message (data and object references) that can 41 * be sent through an IBinder. A Parcel can contain both flattened data 42 * that will be unflattened on the other side of the IPC (using the various 43 * methods here for writing specific types, or the general 44 * {@link Parcelable} interface), and references to live {@link IBinder} 45 * objects that will result in the other side receiving a proxy IBinder 46 * connected with the original IBinder in the Parcel. 47 * 48 * <p class="note">Parcel is <strong>not</strong> a general-purpose 49 * serialization mechanism. This class (and the corresponding 50 * {@link Parcelable} API for placing arbitrary objects into a Parcel) is 51 * designed as a high-performance IPC transport. As such, it is not 52 * appropriate to place any Parcel data in to persistent storage: changes 53 * in the underlying implementation of any of the data in the Parcel can 54 * render older data unreadable.</p> 55 * 56 * <p>The bulk of the Parcel API revolves around reading and writing data 57 * of various types. There are six major classes of such functions available.</p> 58 * 59 * <h3>Primitives</h3> 60 * 61 * <p>The most basic data functions are for writing and reading primitive 62 * data types: {@link #writeByte}, {@link #readByte}, {@link #writeDouble}, 63 * {@link #readDouble}, {@link #writeFloat}, {@link #readFloat}, {@link #writeInt}, 64 * {@link #readInt}, {@link #writeLong}, {@link #readLong}, 65 * {@link #writeString}, {@link #readString}. Most other 66 * data operations are built on top of these. The given data is written and 67 * read using the endianess of the host CPU.</p> 68 * 69 * <h3>Primitive Arrays</h3> 70 * 71 * <p>There are a variety of methods for reading and writing raw arrays 72 * of primitive objects, which generally result in writing a 4-byte length 73 * followed by the primitive data items. The methods for reading can either 74 * read the data into an existing array, or create and return a new array. 75 * These available types are:</p> 76 * 77 * <ul> 78 * <li> {@link #writeBooleanArray(boolean[])}, 79 * {@link #readBooleanArray(boolean[])}, {@link #createBooleanArray()} 80 * <li> {@link #writeByteArray(byte[])}, 81 * {@link #writeByteArray(byte[], int, int)}, {@link #readByteArray(byte[])}, 82 * {@link #createByteArray()} 83 * <li> {@link #writeCharArray(char[])}, {@link #readCharArray(char[])}, 84 * {@link #createCharArray()} 85 * <li> {@link #writeDoubleArray(double[])}, {@link #readDoubleArray(double[])}, 86 * {@link #createDoubleArray()} 87 * <li> {@link #writeFloatArray(float[])}, {@link #readFloatArray(float[])}, 88 * {@link #createFloatArray()} 89 * <li> {@link #writeIntArray(int[])}, {@link #readIntArray(int[])}, 90 * {@link #createIntArray()} 91 * <li> {@link #writeLongArray(long[])}, {@link #readLongArray(long[])}, 92 * {@link #createLongArray()} 93 * <li> {@link #writeStringArray(String[])}, {@link #readStringArray(String[])}, 94 * {@link #createStringArray()}. 95 * <li> {@link #writeSparseBooleanArray(SparseBooleanArray)}, 96 * {@link #readSparseBooleanArray()}. 97 * </ul> 98 * 99 * <h3>Parcelables</h3> 100 * 101 * <p>The {@link Parcelable} protocol provides an extremely efficient (but 102 * low-level) protocol for objects to write and read themselves from Parcels. 103 * You can use the direct methods {@link #writeParcelable(Parcelable, int)} 104 * and {@link #readParcelable(ClassLoader)} or 105 * {@link #writeParcelableArray} and 106 * {@link #readParcelableArray(ClassLoader)} to write or read. These 107 * methods write both the class type and its data to the Parcel, allowing 108 * that class to be reconstructed from the appropriate class loader when 109 * later reading.</p> 110 * 111 * <p>There are also some methods that provide a more efficient way to work 112 * with Parcelables: {@link #writeTypedArray}, 113 * {@link #writeTypedList(List)}, 114 * {@link #readTypedArray} and {@link #readTypedList}. These methods 115 * do not write the class information of the original object: instead, the 116 * caller of the read function must know what type to expect and pass in the 117 * appropriate {@link Parcelable.Creator Parcelable.Creator} instead to 118 * properly construct the new object and read its data. (To more efficient 119 * write and read a single Parceable object, you can directly call 120 * {@link Parcelable#writeToParcel Parcelable.writeToParcel} and 121 * {@link Parcelable.Creator#createFromParcel Parcelable.Creator.createFromParcel} 122 * yourself.)</p> 123 * 124 * <h3>Bundles</h3> 125 * 126 * <p>A special type-safe container, called {@link Bundle}, is available 127 * for key/value maps of heterogeneous values. This has many optimizations 128 * for improved performance when reading and writing data, and its type-safe 129 * API avoids difficult to debug type errors when finally marshalling the 130 * data contents into a Parcel. The methods to use are 131 * {@link #writeBundle(Bundle)}, {@link #readBundle()}, and 132 * {@link #readBundle(ClassLoader)}. 133 * 134 * <h3>Active Objects</h3> 135 * 136 * <p>An unusual feature of Parcel is the ability to read and write active 137 * objects. For these objects the actual contents of the object is not 138 * written, rather a special token referencing the object is written. When 139 * reading the object back from the Parcel, you do not get a new instance of 140 * the object, but rather a handle that operates on the exact same object that 141 * was originally written. There are two forms of active objects available.</p> 142 * 143 * <p>{@link Binder} objects are a core facility of Android's general cross-process 144 * communication system. The {@link IBinder} interface describes an abstract 145 * protocol with a Binder object. Any such interface can be written in to 146 * a Parcel, and upon reading you will receive either the original object 147 * implementing that interface or a special proxy implementation 148 * that communicates calls back to the original object. The methods to use are 149 * {@link #writeStrongBinder(IBinder)}, 150 * {@link #writeStrongInterface(IInterface)}, {@link #readStrongBinder()}, 151 * {@link #writeBinderArray(IBinder[])}, {@link #readBinderArray(IBinder[])}, 152 * {@link #createBinderArray()}, 153 * {@link #writeBinderList(List)}, {@link #readBinderList(List)}, 154 * {@link #createBinderArrayList()}.</p> 155 * 156 * <p>FileDescriptor objects, representing raw Linux file descriptor identifiers, 157 * can be written and {@link ParcelFileDescriptor} objects returned to operate 158 * on the original file descriptor. The returned file descriptor is a dup 159 * of the original file descriptor: the object and fd is different, but 160 * operating on the same underlying file stream, with the same position, etc. 161 * The methods to use are {@link #writeFileDescriptor(FileDescriptor)}, 162 * {@link #readFileDescriptor()}. 163 * 164 * <h3>Untyped Containers</h3> 165 * 166 * <p>A final class of methods are for writing and reading standard Java 167 * containers of arbitrary types. These all revolve around the 168 * {@link #writeValue(Object)} and {@link #readValue(ClassLoader)} methods 169 * which define the types of objects allowed. The container methods are 170 * {@link #writeArray(Object[])}, {@link #readArray(ClassLoader)}, 171 * {@link #writeList(List)}, {@link #readList(List, ClassLoader)}, 172 * {@link #readArrayList(ClassLoader)}, 173 * {@link #writeMap(Map)}, {@link #readMap(Map, ClassLoader)}, 174 * {@link #writeSparseArray(SparseArray)}, 175 * {@link #readSparseArray(ClassLoader)}. 176 */ 177public final class Parcel { 178 private static final boolean DEBUG_RECYCLE = false; 179 private static final String TAG = "Parcel"; 180 181 @SuppressWarnings({"UnusedDeclaration"}) 182 private int mObject; // used by native code 183 @SuppressWarnings({"UnusedDeclaration"}) 184 private int mOwnObject; // used by native code 185 private RuntimeException mStack; 186 187 private static final int POOL_SIZE = 6; 188 private static final Parcel[] sOwnedPool = new Parcel[POOL_SIZE]; 189 private static final Parcel[] sHolderPool = new Parcel[POOL_SIZE]; 190 191 private static final int VAL_NULL = -1; 192 private static final int VAL_STRING = 0; 193 private static final int VAL_INTEGER = 1; 194 private static final int VAL_MAP = 2; 195 private static final int VAL_BUNDLE = 3; 196 private static final int VAL_PARCELABLE = 4; 197 private static final int VAL_SHORT = 5; 198 private static final int VAL_LONG = 6; 199 private static final int VAL_FLOAT = 7; 200 private static final int VAL_DOUBLE = 8; 201 private static final int VAL_BOOLEAN = 9; 202 private static final int VAL_CHARSEQUENCE = 10; 203 private static final int VAL_LIST = 11; 204 private static final int VAL_SPARSEARRAY = 12; 205 private static final int VAL_BYTEARRAY = 13; 206 private static final int VAL_STRINGARRAY = 14; 207 private static final int VAL_IBINDER = 15; 208 private static final int VAL_PARCELABLEARRAY = 16; 209 private static final int VAL_OBJECTARRAY = 17; 210 private static final int VAL_INTARRAY = 18; 211 private static final int VAL_LONGARRAY = 19; 212 private static final int VAL_BYTE = 20; 213 private static final int VAL_SERIALIZABLE = 21; 214 private static final int VAL_SPARSEBOOLEANARRAY = 22; 215 private static final int VAL_BOOLEANARRAY = 23; 216 private static final int VAL_CHARSEQUENCEARRAY = 24; 217 218 // The initial int32 in a Binder call's reply Parcel header: 219 private static final int EX_SECURITY = -1; 220 private static final int EX_BAD_PARCELABLE = -2; 221 private static final int EX_ILLEGAL_ARGUMENT = -3; 222 private static final int EX_NULL_POINTER = -4; 223 private static final int EX_ILLEGAL_STATE = -5; 224 private static final int EX_HAS_REPLY_HEADER = -128; // special; see below 225 226 public final static Parcelable.Creator<String> STRING_CREATOR 227 = new Parcelable.Creator<String>() { 228 public String createFromParcel(Parcel source) { 229 return source.readString(); 230 } 231 public String[] newArray(int size) { 232 return new String[size]; 233 } 234 }; 235 236 /** 237 * Retrieve a new Parcel object from the pool. 238 */ 239 public static Parcel obtain() { 240 final Parcel[] pool = sOwnedPool; 241 synchronized (pool) { 242 Parcel p; 243 for (int i=0; i<POOL_SIZE; i++) { 244 p = pool[i]; 245 if (p != null) { 246 pool[i] = null; 247 if (DEBUG_RECYCLE) { 248 p.mStack = new RuntimeException(); 249 } 250 return p; 251 } 252 } 253 } 254 return new Parcel(0); 255 } 256 257 /** 258 * Put a Parcel object back into the pool. You must not touch 259 * the object after this call. 260 */ 261 public final void recycle() { 262 if (DEBUG_RECYCLE) mStack = null; 263 freeBuffer(); 264 final Parcel[] pool = mOwnObject != 0 ? sOwnedPool : sHolderPool; 265 synchronized (pool) { 266 for (int i=0; i<POOL_SIZE; i++) { 267 if (pool[i] == null) { 268 pool[i] = this; 269 return; 270 } 271 } 272 } 273 } 274 275 /** 276 * Returns the total amount of data contained in the parcel. 277 */ 278 public final native int dataSize(); 279 280 /** 281 * Returns the amount of data remaining to be read from the 282 * parcel. That is, {@link #dataSize}-{@link #dataPosition}. 283 */ 284 public final native int dataAvail(); 285 286 /** 287 * Returns the current position in the parcel data. Never 288 * more than {@link #dataSize}. 289 */ 290 public final native int dataPosition(); 291 292 /** 293 * Returns the total amount of space in the parcel. This is always 294 * >= {@link #dataSize}. The difference between it and dataSize() is the 295 * amount of room left until the parcel needs to re-allocate its 296 * data buffer. 297 */ 298 public final native int dataCapacity(); 299 300 /** 301 * Change the amount of data in the parcel. Can be either smaller or 302 * larger than the current size. If larger than the current capacity, 303 * more memory will be allocated. 304 * 305 * @param size The new number of bytes in the Parcel. 306 */ 307 public final native void setDataSize(int size); 308 309 /** 310 * Move the current read/write position in the parcel. 311 * @param pos New offset in the parcel; must be between 0 and 312 * {@link #dataSize}. 313 */ 314 public final native void setDataPosition(int pos); 315 316 /** 317 * Change the capacity (current available space) of the parcel. 318 * 319 * @param size The new capacity of the parcel, in bytes. Can not be 320 * less than {@link #dataSize} -- that is, you can not drop existing data 321 * with this method. 322 */ 323 public final native void setDataCapacity(int size); 324 325 /** 326 * Returns the raw bytes of the parcel. 327 * 328 * <p class="note">The data you retrieve here <strong>must not</strong> 329 * be placed in any kind of persistent storage (on local disk, across 330 * a network, etc). For that, you should use standard serialization 331 * or another kind of general serialization mechanism. The Parcel 332 * marshalled representation is highly optimized for local IPC, and as 333 * such does not attempt to maintain compatibility with data created 334 * in different versions of the platform. 335 */ 336 public final native byte[] marshall(); 337 338 /** 339 * Set the bytes in data to be the raw bytes of this Parcel. 340 */ 341 public final native void unmarshall(byte[] data, int offest, int length); 342 343 public final native void appendFrom(Parcel parcel, int offset, int length); 344 345 /** 346 * Report whether the parcel contains any marshalled file descriptors. 347 */ 348 public final native boolean hasFileDescriptors(); 349 350 /** 351 * Store or read an IBinder interface token in the parcel at the current 352 * {@link #dataPosition}. This is used to validate that the marshalled 353 * transaction is intended for the target interface. 354 */ 355 public final native void writeInterfaceToken(String interfaceName); 356 public final native void enforceInterface(String interfaceName); 357 358 /** 359 * Write a byte array into the parcel at the current {#link #dataPosition}, 360 * growing {@link #dataCapacity} if needed. 361 * @param b Bytes to place into the parcel. 362 */ 363 public final void writeByteArray(byte[] b) { 364 writeByteArray(b, 0, (b != null) ? b.length : 0); 365 } 366 367 /** 368 * Write an byte array into the parcel at the current {#link #dataPosition}, 369 * growing {@link #dataCapacity} if needed. 370 * @param b Bytes to place into the parcel. 371 * @param offset Index of first byte to be written. 372 * @param len Number of bytes to write. 373 */ 374 public final void writeByteArray(byte[] b, int offset, int len) { 375 if (b == null) { 376 writeInt(-1); 377 return; 378 } 379 if (b.length < offset + len || len < 0 || offset < 0) { 380 throw new ArrayIndexOutOfBoundsException(); 381 } 382 writeNative(b, offset, len); 383 } 384 385 private native void writeNative(byte[] b, int offset, int len); 386 387 /** 388 * Write an integer value into the parcel at the current dataPosition(), 389 * growing dataCapacity() if needed. 390 */ 391 public final native void writeInt(int val); 392 393 /** 394 * Write a long integer value into the parcel at the current dataPosition(), 395 * growing dataCapacity() if needed. 396 */ 397 public final native void writeLong(long val); 398 399 /** 400 * Write a floating point value into the parcel at the current 401 * dataPosition(), growing dataCapacity() if needed. 402 */ 403 public final native void writeFloat(float val); 404 405 /** 406 * Write a double precision floating point value into the parcel at the 407 * current dataPosition(), growing dataCapacity() if needed. 408 */ 409 public final native void writeDouble(double val); 410 411 /** 412 * Write a string value into the parcel at the current dataPosition(), 413 * growing dataCapacity() if needed. 414 */ 415 public final native void writeString(String val); 416 417 /** 418 * Write a CharSequence value into the parcel at the current dataPosition(), 419 * growing dataCapacity() if needed. 420 * @hide 421 */ 422 public final void writeCharSequence(CharSequence val) { 423 TextUtils.writeToParcel(val, this, 0); 424 } 425 426 /** 427 * Write an object into the parcel at the current dataPosition(), 428 * growing dataCapacity() if needed. 429 */ 430 public final native void writeStrongBinder(IBinder val); 431 432 /** 433 * Write an object into the parcel at the current dataPosition(), 434 * growing dataCapacity() if needed. 435 */ 436 public final void writeStrongInterface(IInterface val) { 437 writeStrongBinder(val == null ? null : val.asBinder()); 438 } 439 440 /** 441 * Write a FileDescriptor into the parcel at the current dataPosition(), 442 * growing dataCapacity() if needed. 443 */ 444 public final native void writeFileDescriptor(FileDescriptor val); 445 446 /** 447 * Write an byte value into the parcel at the current dataPosition(), 448 * growing dataCapacity() if needed. 449 */ 450 public final void writeByte(byte val) { 451 writeInt(val); 452 } 453 454 /** 455 * Please use {@link #writeBundle} instead. Flattens a Map into the parcel 456 * at the current dataPosition(), 457 * growing dataCapacity() if needed. The Map keys must be String objects. 458 * The Map values are written using {@link #writeValue} and must follow 459 * the specification there. 460 * 461 * <p>It is strongly recommended to use {@link #writeBundle} instead of 462 * this method, since the Bundle class provides a type-safe API that 463 * allows you to avoid mysterious type errors at the point of marshalling. 464 */ 465 public final void writeMap(Map val) { 466 writeMapInternal((Map<String,Object>) val); 467 } 468 469 /** 470 * Flatten a Map into the parcel at the current dataPosition(), 471 * growing dataCapacity() if needed. The Map keys must be String objects. 472 */ 473 /* package */ void writeMapInternal(Map<String,Object> val) { 474 if (val == null) { 475 writeInt(-1); 476 return; 477 } 478 Set<Map.Entry<String,Object>> entries = val.entrySet(); 479 writeInt(entries.size()); 480 for (Map.Entry<String,Object> e : entries) { 481 writeValue(e.getKey()); 482 writeValue(e.getValue()); 483 } 484 } 485 486 /** 487 * Flatten a Bundle into the parcel at the current dataPosition(), 488 * growing dataCapacity() if needed. 489 */ 490 public final void writeBundle(Bundle val) { 491 if (val == null) { 492 writeInt(-1); 493 return; 494 } 495 496 val.writeToParcel(this, 0); 497 } 498 499 /** 500 * Flatten a List into the parcel at the current dataPosition(), growing 501 * dataCapacity() if needed. The List values are written using 502 * {@link #writeValue} and must follow the specification there. 503 */ 504 public final void writeList(List val) { 505 if (val == null) { 506 writeInt(-1); 507 return; 508 } 509 int N = val.size(); 510 int i=0; 511 writeInt(N); 512 while (i < N) { 513 writeValue(val.get(i)); 514 i++; 515 } 516 } 517 518 /** 519 * Flatten an Object array into the parcel at the current dataPosition(), 520 * growing dataCapacity() if needed. The array values are written using 521 * {@link #writeValue} and must follow the specification there. 522 */ 523 public final void writeArray(Object[] val) { 524 if (val == null) { 525 writeInt(-1); 526 return; 527 } 528 int N = val.length; 529 int i=0; 530 writeInt(N); 531 while (i < N) { 532 writeValue(val[i]); 533 i++; 534 } 535 } 536 537 /** 538 * Flatten a generic SparseArray into the parcel at the current 539 * dataPosition(), growing dataCapacity() if needed. The SparseArray 540 * values are written using {@link #writeValue} and must follow the 541 * specification there. 542 */ 543 public final void writeSparseArray(SparseArray<Object> val) { 544 if (val == null) { 545 writeInt(-1); 546 return; 547 } 548 int N = val.size(); 549 writeInt(N); 550 int i=0; 551 while (i < N) { 552 writeInt(val.keyAt(i)); 553 writeValue(val.valueAt(i)); 554 i++; 555 } 556 } 557 558 public final void writeSparseBooleanArray(SparseBooleanArray val) { 559 if (val == null) { 560 writeInt(-1); 561 return; 562 } 563 int N = val.size(); 564 writeInt(N); 565 int i=0; 566 while (i < N) { 567 writeInt(val.keyAt(i)); 568 writeByte((byte)(val.valueAt(i) ? 1 : 0)); 569 i++; 570 } 571 } 572 573 public final void writeBooleanArray(boolean[] val) { 574 if (val != null) { 575 int N = val.length; 576 writeInt(N); 577 for (int i=0; i<N; i++) { 578 writeInt(val[i] ? 1 : 0); 579 } 580 } else { 581 writeInt(-1); 582 } 583 } 584 585 public final boolean[] createBooleanArray() { 586 int N = readInt(); 587 // >>2 as a fast divide-by-4 works in the create*Array() functions 588 // because dataAvail() will never return a negative number. 4 is 589 // the size of a stored boolean in the stream. 590 if (N >= 0 && N <= (dataAvail() >> 2)) { 591 boolean[] val = new boolean[N]; 592 for (int i=0; i<N; i++) { 593 val[i] = readInt() != 0; 594 } 595 return val; 596 } else { 597 return null; 598 } 599 } 600 601 public final void readBooleanArray(boolean[] val) { 602 int N = readInt(); 603 if (N == val.length) { 604 for (int i=0; i<N; i++) { 605 val[i] = readInt() != 0; 606 } 607 } else { 608 throw new RuntimeException("bad array lengths"); 609 } 610 } 611 612 public final void writeCharArray(char[] val) { 613 if (val != null) { 614 int N = val.length; 615 writeInt(N); 616 for (int i=0; i<N; i++) { 617 writeInt((int)val[i]); 618 } 619 } else { 620 writeInt(-1); 621 } 622 } 623 624 public final char[] createCharArray() { 625 int N = readInt(); 626 if (N >= 0 && N <= (dataAvail() >> 2)) { 627 char[] val = new char[N]; 628 for (int i=0; i<N; i++) { 629 val[i] = (char)readInt(); 630 } 631 return val; 632 } else { 633 return null; 634 } 635 } 636 637 public final void readCharArray(char[] val) { 638 int N = readInt(); 639 if (N == val.length) { 640 for (int i=0; i<N; i++) { 641 val[i] = (char)readInt(); 642 } 643 } else { 644 throw new RuntimeException("bad array lengths"); 645 } 646 } 647 648 public final void writeIntArray(int[] val) { 649 if (val != null) { 650 int N = val.length; 651 writeInt(N); 652 for (int i=0; i<N; i++) { 653 writeInt(val[i]); 654 } 655 } else { 656 writeInt(-1); 657 } 658 } 659 660 public final int[] createIntArray() { 661 int N = readInt(); 662 if (N >= 0 && N <= (dataAvail() >> 2)) { 663 int[] val = new int[N]; 664 for (int i=0; i<N; i++) { 665 val[i] = readInt(); 666 } 667 return val; 668 } else { 669 return null; 670 } 671 } 672 673 public final void readIntArray(int[] val) { 674 int N = readInt(); 675 if (N == val.length) { 676 for (int i=0; i<N; i++) { 677 val[i] = readInt(); 678 } 679 } else { 680 throw new RuntimeException("bad array lengths"); 681 } 682 } 683 684 public final void writeLongArray(long[] val) { 685 if (val != null) { 686 int N = val.length; 687 writeInt(N); 688 for (int i=0; i<N; i++) { 689 writeLong(val[i]); 690 } 691 } else { 692 writeInt(-1); 693 } 694 } 695 696 public final long[] createLongArray() { 697 int N = readInt(); 698 // >>3 because stored longs are 64 bits 699 if (N >= 0 && N <= (dataAvail() >> 3)) { 700 long[] val = new long[N]; 701 for (int i=0; i<N; i++) { 702 val[i] = readLong(); 703 } 704 return val; 705 } else { 706 return null; 707 } 708 } 709 710 public final void readLongArray(long[] val) { 711 int N = readInt(); 712 if (N == val.length) { 713 for (int i=0; i<N; i++) { 714 val[i] = readLong(); 715 } 716 } else { 717 throw new RuntimeException("bad array lengths"); 718 } 719 } 720 721 public final void writeFloatArray(float[] val) { 722 if (val != null) { 723 int N = val.length; 724 writeInt(N); 725 for (int i=0; i<N; i++) { 726 writeFloat(val[i]); 727 } 728 } else { 729 writeInt(-1); 730 } 731 } 732 733 public final float[] createFloatArray() { 734 int N = readInt(); 735 // >>2 because stored floats are 4 bytes 736 if (N >= 0 && N <= (dataAvail() >> 2)) { 737 float[] val = new float[N]; 738 for (int i=0; i<N; i++) { 739 val[i] = readFloat(); 740 } 741 return val; 742 } else { 743 return null; 744 } 745 } 746 747 public final void readFloatArray(float[] val) { 748 int N = readInt(); 749 if (N == val.length) { 750 for (int i=0; i<N; i++) { 751 val[i] = readFloat(); 752 } 753 } else { 754 throw new RuntimeException("bad array lengths"); 755 } 756 } 757 758 public final void writeDoubleArray(double[] val) { 759 if (val != null) { 760 int N = val.length; 761 writeInt(N); 762 for (int i=0; i<N; i++) { 763 writeDouble(val[i]); 764 } 765 } else { 766 writeInt(-1); 767 } 768 } 769 770 public final double[] createDoubleArray() { 771 int N = readInt(); 772 // >>3 because stored doubles are 8 bytes 773 if (N >= 0 && N <= (dataAvail() >> 3)) { 774 double[] val = new double[N]; 775 for (int i=0; i<N; i++) { 776 val[i] = readDouble(); 777 } 778 return val; 779 } else { 780 return null; 781 } 782 } 783 784 public final void readDoubleArray(double[] val) { 785 int N = readInt(); 786 if (N == val.length) { 787 for (int i=0; i<N; i++) { 788 val[i] = readDouble(); 789 } 790 } else { 791 throw new RuntimeException("bad array lengths"); 792 } 793 } 794 795 public final void writeStringArray(String[] val) { 796 if (val != null) { 797 int N = val.length; 798 writeInt(N); 799 for (int i=0; i<N; i++) { 800 writeString(val[i]); 801 } 802 } else { 803 writeInt(-1); 804 } 805 } 806 807 public final String[] createStringArray() { 808 int N = readInt(); 809 if (N >= 0) { 810 String[] val = new String[N]; 811 for (int i=0; i<N; i++) { 812 val[i] = readString(); 813 } 814 return val; 815 } else { 816 return null; 817 } 818 } 819 820 public final void readStringArray(String[] val) { 821 int N = readInt(); 822 if (N == val.length) { 823 for (int i=0; i<N; i++) { 824 val[i] = readString(); 825 } 826 } else { 827 throw new RuntimeException("bad array lengths"); 828 } 829 } 830 831 public final void writeBinderArray(IBinder[] val) { 832 if (val != null) { 833 int N = val.length; 834 writeInt(N); 835 for (int i=0; i<N; i++) { 836 writeStrongBinder(val[i]); 837 } 838 } else { 839 writeInt(-1); 840 } 841 } 842 843 /** 844 * @hide 845 */ 846 public final void writeCharSequenceArray(CharSequence[] val) { 847 if (val != null) { 848 int N = val.length; 849 writeInt(N); 850 for (int i=0; i<N; i++) { 851 writeCharSequence(val[i]); 852 } 853 } else { 854 writeInt(-1); 855 } 856 } 857 858 public final IBinder[] createBinderArray() { 859 int N = readInt(); 860 if (N >= 0) { 861 IBinder[] val = new IBinder[N]; 862 for (int i=0; i<N; i++) { 863 val[i] = readStrongBinder(); 864 } 865 return val; 866 } else { 867 return null; 868 } 869 } 870 871 public final void readBinderArray(IBinder[] val) { 872 int N = readInt(); 873 if (N == val.length) { 874 for (int i=0; i<N; i++) { 875 val[i] = readStrongBinder(); 876 } 877 } else { 878 throw new RuntimeException("bad array lengths"); 879 } 880 } 881 882 /** 883 * Flatten a List containing a particular object type into the parcel, at 884 * the current dataPosition() and growing dataCapacity() if needed. The 885 * type of the objects in the list must be one that implements Parcelable. 886 * Unlike the generic writeList() method, however, only the raw data of the 887 * objects is written and not their type, so you must use the corresponding 888 * readTypedList() to unmarshall them. 889 * 890 * @param val The list of objects to be written. 891 * 892 * @see #createTypedArrayList 893 * @see #readTypedList 894 * @see Parcelable 895 */ 896 public final <T extends Parcelable> void writeTypedList(List<T> val) { 897 if (val == null) { 898 writeInt(-1); 899 return; 900 } 901 int N = val.size(); 902 int i=0; 903 writeInt(N); 904 while (i < N) { 905 T item = val.get(i); 906 if (item != null) { 907 writeInt(1); 908 item.writeToParcel(this, 0); 909 } else { 910 writeInt(0); 911 } 912 i++; 913 } 914 } 915 916 /** 917 * Flatten a List containing String objects into the parcel, at 918 * the current dataPosition() and growing dataCapacity() if needed. They 919 * can later be retrieved with {@link #createStringArrayList} or 920 * {@link #readStringList}. 921 * 922 * @param val The list of strings to be written. 923 * 924 * @see #createStringArrayList 925 * @see #readStringList 926 */ 927 public final void writeStringList(List<String> val) { 928 if (val == null) { 929 writeInt(-1); 930 return; 931 } 932 int N = val.size(); 933 int i=0; 934 writeInt(N); 935 while (i < N) { 936 writeString(val.get(i)); 937 i++; 938 } 939 } 940 941 /** 942 * Flatten a List containing IBinder objects into the parcel, at 943 * the current dataPosition() and growing dataCapacity() if needed. They 944 * can later be retrieved with {@link #createBinderArrayList} or 945 * {@link #readBinderList}. 946 * 947 * @param val The list of strings to be written. 948 * 949 * @see #createBinderArrayList 950 * @see #readBinderList 951 */ 952 public final void writeBinderList(List<IBinder> val) { 953 if (val == null) { 954 writeInt(-1); 955 return; 956 } 957 int N = val.size(); 958 int i=0; 959 writeInt(N); 960 while (i < N) { 961 writeStrongBinder(val.get(i)); 962 i++; 963 } 964 } 965 966 /** 967 * Flatten a heterogeneous array containing a particular object type into 968 * the parcel, at 969 * the current dataPosition() and growing dataCapacity() if needed. The 970 * type of the objects in the array must be one that implements Parcelable. 971 * Unlike the {@link #writeParcelableArray} method, however, only the 972 * raw data of the objects is written and not their type, so you must use 973 * {@link #readTypedArray} with the correct corresponding 974 * {@link Parcelable.Creator} implementation to unmarshall them. 975 * 976 * @param val The array of objects to be written. 977 * @param parcelableFlags Contextual flags as per 978 * {@link Parcelable#writeToParcel(Parcel, int) Parcelable.writeToParcel()}. 979 * 980 * @see #readTypedArray 981 * @see #writeParcelableArray 982 * @see Parcelable.Creator 983 */ 984 public final <T extends Parcelable> void writeTypedArray(T[] val, 985 int parcelableFlags) { 986 if (val != null) { 987 int N = val.length; 988 writeInt(N); 989 for (int i=0; i<N; i++) { 990 T item = val[i]; 991 if (item != null) { 992 writeInt(1); 993 item.writeToParcel(this, parcelableFlags); 994 } else { 995 writeInt(0); 996 } 997 } 998 } else { 999 writeInt(-1); 1000 } 1001 } 1002 1003 /** 1004 * Flatten a generic object in to a parcel. The given Object value may 1005 * currently be one of the following types: 1006 * 1007 * <ul> 1008 * <li> null 1009 * <li> String 1010 * <li> Byte 1011 * <li> Short 1012 * <li> Integer 1013 * <li> Long 1014 * <li> Float 1015 * <li> Double 1016 * <li> Boolean 1017 * <li> String[] 1018 * <li> boolean[] 1019 * <li> byte[] 1020 * <li> int[] 1021 * <li> long[] 1022 * <li> Object[] (supporting objects of the same type defined here). 1023 * <li> {@link Bundle} 1024 * <li> Map (as supported by {@link #writeMap}). 1025 * <li> Any object that implements the {@link Parcelable} protocol. 1026 * <li> Parcelable[] 1027 * <li> CharSequence (as supported by {@link TextUtils#writeToParcel}). 1028 * <li> List (as supported by {@link #writeList}). 1029 * <li> {@link SparseArray} (as supported by {@link #writeSparseArray}). 1030 * <li> {@link IBinder} 1031 * <li> Any object that implements Serializable (but see 1032 * {@link #writeSerializable} for caveats). Note that all of the 1033 * previous types have relatively efficient implementations for 1034 * writing to a Parcel; having to rely on the generic serialization 1035 * approach is much less efficient and should be avoided whenever 1036 * possible. 1037 * </ul> 1038 */ 1039 public final void writeValue(Object v) { 1040 if (v == null) { 1041 writeInt(VAL_NULL); 1042 } else if (v instanceof String) { 1043 writeInt(VAL_STRING); 1044 writeString((String) v); 1045 } else if (v instanceof Integer) { 1046 writeInt(VAL_INTEGER); 1047 writeInt((Integer) v); 1048 } else if (v instanceof Map) { 1049 writeInt(VAL_MAP); 1050 writeMap((Map) v); 1051 } else if (v instanceof Bundle) { 1052 // Must be before Parcelable 1053 writeInt(VAL_BUNDLE); 1054 writeBundle((Bundle) v); 1055 } else if (v instanceof Parcelable) { 1056 writeInt(VAL_PARCELABLE); 1057 writeParcelable((Parcelable) v, 0); 1058 } else if (v instanceof Short) { 1059 writeInt(VAL_SHORT); 1060 writeInt(((Short) v).intValue()); 1061 } else if (v instanceof Long) { 1062 writeInt(VAL_LONG); 1063 writeLong((Long) v); 1064 } else if (v instanceof Float) { 1065 writeInt(VAL_FLOAT); 1066 writeFloat((Float) v); 1067 } else if (v instanceof Double) { 1068 writeInt(VAL_DOUBLE); 1069 writeDouble((Double) v); 1070 } else if (v instanceof Boolean) { 1071 writeInt(VAL_BOOLEAN); 1072 writeInt((Boolean) v ? 1 : 0); 1073 } else if (v instanceof CharSequence) { 1074 // Must be after String 1075 writeInt(VAL_CHARSEQUENCE); 1076 writeCharSequence((CharSequence) v); 1077 } else if (v instanceof List) { 1078 writeInt(VAL_LIST); 1079 writeList((List) v); 1080 } else if (v instanceof SparseArray) { 1081 writeInt(VAL_SPARSEARRAY); 1082 writeSparseArray((SparseArray) v); 1083 } else if (v instanceof boolean[]) { 1084 writeInt(VAL_BOOLEANARRAY); 1085 writeBooleanArray((boolean[]) v); 1086 } else if (v instanceof byte[]) { 1087 writeInt(VAL_BYTEARRAY); 1088 writeByteArray((byte[]) v); 1089 } else if (v instanceof String[]) { 1090 writeInt(VAL_STRINGARRAY); 1091 writeStringArray((String[]) v); 1092 } else if (v instanceof CharSequence[]) { 1093 // Must be after String[] and before Object[] 1094 writeInt(VAL_CHARSEQUENCEARRAY); 1095 writeCharSequenceArray((CharSequence[]) v); 1096 } else if (v instanceof IBinder) { 1097 writeInt(VAL_IBINDER); 1098 writeStrongBinder((IBinder) v); 1099 } else if (v instanceof Parcelable[]) { 1100 writeInt(VAL_PARCELABLEARRAY); 1101 writeParcelableArray((Parcelable[]) v, 0); 1102 } else if (v instanceof Object[]) { 1103 writeInt(VAL_OBJECTARRAY); 1104 writeArray((Object[]) v); 1105 } else if (v instanceof int[]) { 1106 writeInt(VAL_INTARRAY); 1107 writeIntArray((int[]) v); 1108 } else if (v instanceof long[]) { 1109 writeInt(VAL_LONGARRAY); 1110 writeLongArray((long[]) v); 1111 } else if (v instanceof Byte) { 1112 writeInt(VAL_BYTE); 1113 writeInt((Byte) v); 1114 } else if (v instanceof Serializable) { 1115 // Must be last 1116 writeInt(VAL_SERIALIZABLE); 1117 writeSerializable((Serializable) v); 1118 } else { 1119 throw new RuntimeException("Parcel: unable to marshal value " + v); 1120 } 1121 } 1122 1123 /** 1124 * Flatten the name of the class of the Parcelable and its contents 1125 * into the parcel. 1126 * 1127 * @param p The Parcelable object to be written. 1128 * @param parcelableFlags Contextual flags as per 1129 * {@link Parcelable#writeToParcel(Parcel, int) Parcelable.writeToParcel()}. 1130 */ 1131 public final void writeParcelable(Parcelable p, int parcelableFlags) { 1132 if (p == null) { 1133 writeString(null); 1134 return; 1135 } 1136 String name = p.getClass().getName(); 1137 writeString(name); 1138 p.writeToParcel(this, parcelableFlags); 1139 } 1140 1141 /** 1142 * Write a generic serializable object in to a Parcel. It is strongly 1143 * recommended that this method be avoided, since the serialization 1144 * overhead is extremely large, and this approach will be much slower than 1145 * using the other approaches to writing data in to a Parcel. 1146 */ 1147 public final void writeSerializable(Serializable s) { 1148 if (s == null) { 1149 writeString(null); 1150 return; 1151 } 1152 String name = s.getClass().getName(); 1153 writeString(name); 1154 1155 ByteArrayOutputStream baos = new ByteArrayOutputStream(); 1156 try { 1157 ObjectOutputStream oos = new ObjectOutputStream(baos); 1158 oos.writeObject(s); 1159 oos.close(); 1160 1161 writeByteArray(baos.toByteArray()); 1162 } catch (IOException ioe) { 1163 throw new RuntimeException("Parcelable encountered " + 1164 "IOException writing serializable object (name = " + name + 1165 ")", ioe); 1166 } 1167 } 1168 1169 /** 1170 * Special function for writing an exception result at the header of 1171 * a parcel, to be used when returning an exception from a transaction. 1172 * Note that this currently only supports a few exception types; any other 1173 * exception will be re-thrown by this function as a RuntimeException 1174 * (to be caught by the system's last-resort exception handling when 1175 * dispatching a transaction). 1176 * 1177 * <p>The supported exception types are: 1178 * <ul> 1179 * <li>{@link BadParcelableException} 1180 * <li>{@link IllegalArgumentException} 1181 * <li>{@link IllegalStateException} 1182 * <li>{@link NullPointerException} 1183 * <li>{@link SecurityException} 1184 * </ul> 1185 * 1186 * @param e The Exception to be written. 1187 * 1188 * @see #writeNoException 1189 * @see #readException 1190 */ 1191 public final void writeException(Exception e) { 1192 int code = 0; 1193 if (e instanceof SecurityException) { 1194 code = EX_SECURITY; 1195 } else if (e instanceof BadParcelableException) { 1196 code = EX_BAD_PARCELABLE; 1197 } else if (e instanceof IllegalArgumentException) { 1198 code = EX_ILLEGAL_ARGUMENT; 1199 } else if (e instanceof NullPointerException) { 1200 code = EX_NULL_POINTER; 1201 } else if (e instanceof IllegalStateException) { 1202 code = EX_ILLEGAL_STATE; 1203 } 1204 writeInt(code); 1205 StrictMode.clearGatheredViolations(); 1206 if (code == 0) { 1207 if (e instanceof RuntimeException) { 1208 throw (RuntimeException) e; 1209 } 1210 throw new RuntimeException(e); 1211 } 1212 writeString(e.getMessage()); 1213 } 1214 1215 /** 1216 * Special function for writing information at the front of the Parcel 1217 * indicating that no exception occurred. 1218 * 1219 * @see #writeException 1220 * @see #readException 1221 */ 1222 public final void writeNoException() { 1223 // Despite the name of this function ("write no exception"), 1224 // it should instead be thought of as "write the RPC response 1225 // header", but because this function name is written out by 1226 // the AIDL compiler, we're not going to rename it. 1227 // 1228 // The response header, in the non-exception case (see also 1229 // writeException above, also called by the AIDL compiler), is 1230 // either a 0 (the default case), or EX_HAS_REPLY_HEADER if 1231 // StrictMode has gathered up violations that have occurred 1232 // during a Binder call, in which case we write out the number 1233 // of violations and their details, serialized, before the 1234 // actual RPC respons data. The receiving end of this is 1235 // readException(), below. 1236 if (StrictMode.hasGatheredViolations()) { 1237 writeInt(EX_HAS_REPLY_HEADER); 1238 final int sizePosition = dataPosition(); 1239 writeInt(0); // total size of fat header, to be filled in later 1240 StrictMode.writeGatheredViolationsToParcel(this); 1241 final int payloadPosition = dataPosition(); 1242 setDataPosition(sizePosition); 1243 writeInt(payloadPosition - sizePosition); // header size 1244 setDataPosition(payloadPosition); 1245 } else { 1246 writeInt(0); 1247 } 1248 } 1249 1250 /** 1251 * Special function for reading an exception result from the header of 1252 * a parcel, to be used after receiving the result of a transaction. This 1253 * will throw the exception for you if it had been written to the Parcel, 1254 * otherwise return and let you read the normal result data from the Parcel. 1255 * 1256 * @see #writeException 1257 * @see #writeNoException 1258 */ 1259 public final void readException() { 1260 int code = readExceptionCode(); 1261 if (code != 0) { 1262 String msg = readString(); 1263 readException(code, msg); 1264 } 1265 } 1266 1267 /** 1268 * Parses the header of a Binder call's response Parcel and 1269 * returns the exception code. Deals with lite or fat headers. 1270 * In the common successful case, this header is generally zero. 1271 * In less common cases, it's a small negative number and will be 1272 * followed by an error string. 1273 * 1274 * This exists purely for android.database.DatabaseUtils and 1275 * insulating it from having to handle fat headers as returned by 1276 * e.g. StrictMode-induced RPC responses. 1277 * 1278 * @hide 1279 */ 1280 public final int readExceptionCode() { 1281 int code = readInt(); 1282 if (code == EX_HAS_REPLY_HEADER) { 1283 int headerSize = readInt(); 1284 if (headerSize == 0) { 1285 Log.e(TAG, "Unexpected zero-sized Parcel reply header."); 1286 } else { 1287 // Currently the only thing in the header is StrictMode stacks, 1288 // but discussions around event/RPC tracing suggest we might 1289 // put that here too. If so, switch on sub-header tags here. 1290 // But for now, just parse out the StrictMode stuff. 1291 StrictMode.readAndHandleBinderCallViolations(this); 1292 } 1293 // And fat response headers are currently only used when 1294 // there are no exceptions, so return no error: 1295 return 0; 1296 } 1297 return code; 1298 } 1299 1300 /** 1301 * Use this function for customized exception handling. 1302 * customized method call this method for all unknown case 1303 * @param code exception code 1304 * @param msg exception message 1305 */ 1306 public final void readException(int code, String msg) { 1307 switch (code) { 1308 case EX_SECURITY: 1309 throw new SecurityException(msg); 1310 case EX_BAD_PARCELABLE: 1311 throw new BadParcelableException(msg); 1312 case EX_ILLEGAL_ARGUMENT: 1313 throw new IllegalArgumentException(msg); 1314 case EX_NULL_POINTER: 1315 throw new NullPointerException(msg); 1316 case EX_ILLEGAL_STATE: 1317 throw new IllegalStateException(msg); 1318 } 1319 throw new RuntimeException("Unknown exception code: " + code 1320 + " msg " + msg); 1321 } 1322 1323 /** 1324 * Read an integer value from the parcel at the current dataPosition(). 1325 */ 1326 public final native int readInt(); 1327 1328 /** 1329 * Read a long integer value from the parcel at the current dataPosition(). 1330 */ 1331 public final native long readLong(); 1332 1333 /** 1334 * Read a floating point value from the parcel at the current 1335 * dataPosition(). 1336 */ 1337 public final native float readFloat(); 1338 1339 /** 1340 * Read a double precision floating point value from the parcel at the 1341 * current dataPosition(). 1342 */ 1343 public final native double readDouble(); 1344 1345 /** 1346 * Read a string value from the parcel at the current dataPosition(). 1347 */ 1348 public final native String readString(); 1349 1350 /** 1351 * Read a CharSequence value from the parcel at the current dataPosition(). 1352 * @hide 1353 */ 1354 public final CharSequence readCharSequence() { 1355 return TextUtils.CHAR_SEQUENCE_CREATOR.createFromParcel(this); 1356 } 1357 1358 /** 1359 * Read an object from the parcel at the current dataPosition(). 1360 */ 1361 public final native IBinder readStrongBinder(); 1362 1363 /** 1364 * Read a FileDescriptor from the parcel at the current dataPosition(). 1365 */ 1366 public final ParcelFileDescriptor readFileDescriptor() { 1367 FileDescriptor fd = internalReadFileDescriptor(); 1368 return fd != null ? new ParcelFileDescriptor(fd) : null; 1369 } 1370 1371 private native FileDescriptor internalReadFileDescriptor(); 1372 /*package*/ static native FileDescriptor openFileDescriptor(String file, 1373 int mode) throws FileNotFoundException; 1374 /*package*/ static native void closeFileDescriptor(FileDescriptor desc) 1375 throws IOException; 1376 1377 /** 1378 * Read a byte value from the parcel at the current dataPosition(). 1379 */ 1380 public final byte readByte() { 1381 return (byte)(readInt() & 0xff); 1382 } 1383 1384 /** 1385 * Please use {@link #readBundle(ClassLoader)} instead (whose data must have 1386 * been written with {@link #writeBundle}. Read into an existing Map object 1387 * from the parcel at the current dataPosition(). 1388 */ 1389 public final void readMap(Map outVal, ClassLoader loader) { 1390 int N = readInt(); 1391 readMapInternal(outVal, N, loader); 1392 } 1393 1394 /** 1395 * Read into an existing List object from the parcel at the current 1396 * dataPosition(), using the given class loader to load any enclosed 1397 * Parcelables. If it is null, the default class loader is used. 1398 */ 1399 public final void readList(List outVal, ClassLoader loader) { 1400 int N = readInt(); 1401 readListInternal(outVal, N, loader); 1402 } 1403 1404 /** 1405 * Please use {@link #readBundle(ClassLoader)} instead (whose data must have 1406 * been written with {@link #writeBundle}. Read and return a new HashMap 1407 * object from the parcel at the current dataPosition(), using the given 1408 * class loader to load any enclosed Parcelables. Returns null if 1409 * the previously written map object was null. 1410 */ 1411 public final HashMap readHashMap(ClassLoader loader) 1412 { 1413 int N = readInt(); 1414 if (N < 0) { 1415 return null; 1416 } 1417 HashMap m = new HashMap(N); 1418 readMapInternal(m, N, loader); 1419 return m; 1420 } 1421 1422 /** 1423 * Read and return a new Bundle object from the parcel at the current 1424 * dataPosition(). Returns null if the previously written Bundle object was 1425 * null. 1426 */ 1427 public final Bundle readBundle() { 1428 return readBundle(null); 1429 } 1430 1431 /** 1432 * Read and return a new Bundle object from the parcel at the current 1433 * dataPosition(), using the given class loader to initialize the class 1434 * loader of the Bundle for later retrieval of Parcelable objects. 1435 * Returns null if the previously written Bundle object was null. 1436 */ 1437 public final Bundle readBundle(ClassLoader loader) { 1438 int length = readInt(); 1439 if (length < 0) { 1440 return null; 1441 } 1442 1443 final Bundle bundle = new Bundle(this, length); 1444 if (loader != null) { 1445 bundle.setClassLoader(loader); 1446 } 1447 return bundle; 1448 } 1449 1450 /** 1451 * Read and return a byte[] object from the parcel. 1452 */ 1453 public final native byte[] createByteArray(); 1454 1455 /** 1456 * Read a byte[] object from the parcel and copy it into the 1457 * given byte array. 1458 */ 1459 public final void readByteArray(byte[] val) { 1460 // TODO: make this a native method to avoid the extra copy. 1461 byte[] ba = createByteArray(); 1462 if (ba.length == val.length) { 1463 System.arraycopy(ba, 0, val, 0, ba.length); 1464 } else { 1465 throw new RuntimeException("bad array lengths"); 1466 } 1467 } 1468 1469 /** 1470 * Read and return a String[] object from the parcel. 1471 * {@hide} 1472 */ 1473 public final String[] readStringArray() { 1474 String[] array = null; 1475 1476 int length = readInt(); 1477 if (length >= 0) 1478 { 1479 array = new String[length]; 1480 1481 for (int i = 0 ; i < length ; i++) 1482 { 1483 array[i] = readString(); 1484 } 1485 } 1486 1487 return array; 1488 } 1489 1490 /** 1491 * Read and return a CharSequence[] object from the parcel. 1492 * {@hide} 1493 */ 1494 public final CharSequence[] readCharSequenceArray() { 1495 CharSequence[] array = null; 1496 1497 int length = readInt(); 1498 if (length >= 0) 1499 { 1500 array = new CharSequence[length]; 1501 1502 for (int i = 0 ; i < length ; i++) 1503 { 1504 array[i] = readCharSequence(); 1505 } 1506 } 1507 1508 return array; 1509 } 1510 1511 /** 1512 * Read and return a new ArrayList object from the parcel at the current 1513 * dataPosition(). Returns null if the previously written list object was 1514 * null. The given class loader will be used to load any enclosed 1515 * Parcelables. 1516 */ 1517 public final ArrayList readArrayList(ClassLoader loader) { 1518 int N = readInt(); 1519 if (N < 0) { 1520 return null; 1521 } 1522 ArrayList l = new ArrayList(N); 1523 readListInternal(l, N, loader); 1524 return l; 1525 } 1526 1527 /** 1528 * Read and return a new Object array from the parcel at the current 1529 * dataPosition(). Returns null if the previously written array was 1530 * null. The given class loader will be used to load any enclosed 1531 * Parcelables. 1532 */ 1533 public final Object[] readArray(ClassLoader loader) { 1534 int N = readInt(); 1535 if (N < 0) { 1536 return null; 1537 } 1538 Object[] l = new Object[N]; 1539 readArrayInternal(l, N, loader); 1540 return l; 1541 } 1542 1543 /** 1544 * Read and return a new SparseArray object from the parcel at the current 1545 * dataPosition(). Returns null if the previously written list object was 1546 * null. The given class loader will be used to load any enclosed 1547 * Parcelables. 1548 */ 1549 public final SparseArray readSparseArray(ClassLoader loader) { 1550 int N = readInt(); 1551 if (N < 0) { 1552 return null; 1553 } 1554 SparseArray sa = new SparseArray(N); 1555 readSparseArrayInternal(sa, N, loader); 1556 return sa; 1557 } 1558 1559 /** 1560 * Read and return a new SparseBooleanArray object from the parcel at the current 1561 * dataPosition(). Returns null if the previously written list object was 1562 * null. 1563 */ 1564 public final SparseBooleanArray readSparseBooleanArray() { 1565 int N = readInt(); 1566 if (N < 0) { 1567 return null; 1568 } 1569 SparseBooleanArray sa = new SparseBooleanArray(N); 1570 readSparseBooleanArrayInternal(sa, N); 1571 return sa; 1572 } 1573 1574 /** 1575 * Read and return a new ArrayList containing a particular object type from 1576 * the parcel that was written with {@link #writeTypedList} at the 1577 * current dataPosition(). Returns null if the 1578 * previously written list object was null. The list <em>must</em> have 1579 * previously been written via {@link #writeTypedList} with the same object 1580 * type. 1581 * 1582 * @return A newly created ArrayList containing objects with the same data 1583 * as those that were previously written. 1584 * 1585 * @see #writeTypedList 1586 */ 1587 public final <T> ArrayList<T> createTypedArrayList(Parcelable.Creator<T> c) { 1588 int N = readInt(); 1589 if (N < 0) { 1590 return null; 1591 } 1592 ArrayList<T> l = new ArrayList<T>(N); 1593 while (N > 0) { 1594 if (readInt() != 0) { 1595 l.add(c.createFromParcel(this)); 1596 } else { 1597 l.add(null); 1598 } 1599 N--; 1600 } 1601 return l; 1602 } 1603 1604 /** 1605 * Read into the given List items containing a particular object type 1606 * that were written with {@link #writeTypedList} at the 1607 * current dataPosition(). The list <em>must</em> have 1608 * previously been written via {@link #writeTypedList} with the same object 1609 * type. 1610 * 1611 * @return A newly created ArrayList containing objects with the same data 1612 * as those that were previously written. 1613 * 1614 * @see #writeTypedList 1615 */ 1616 public final <T> void readTypedList(List<T> list, Parcelable.Creator<T> c) { 1617 int M = list.size(); 1618 int N = readInt(); 1619 int i = 0; 1620 for (; i < M && i < N; i++) { 1621 if (readInt() != 0) { 1622 list.set(i, c.createFromParcel(this)); 1623 } else { 1624 list.set(i, null); 1625 } 1626 } 1627 for (; i<N; i++) { 1628 if (readInt() != 0) { 1629 list.add(c.createFromParcel(this)); 1630 } else { 1631 list.add(null); 1632 } 1633 } 1634 for (; i<M; i++) { 1635 list.remove(N); 1636 } 1637 } 1638 1639 /** 1640 * Read and return a new ArrayList containing String objects from 1641 * the parcel that was written with {@link #writeStringList} at the 1642 * current dataPosition(). Returns null if the 1643 * previously written list object was null. 1644 * 1645 * @return A newly created ArrayList containing strings with the same data 1646 * as those that were previously written. 1647 * 1648 * @see #writeStringList 1649 */ 1650 public final ArrayList<String> createStringArrayList() { 1651 int N = readInt(); 1652 if (N < 0) { 1653 return null; 1654 } 1655 ArrayList<String> l = new ArrayList<String>(N); 1656 while (N > 0) { 1657 l.add(readString()); 1658 N--; 1659 } 1660 return l; 1661 } 1662 1663 /** 1664 * Read and return a new ArrayList containing IBinder objects from 1665 * the parcel that was written with {@link #writeBinderList} at the 1666 * current dataPosition(). Returns null if the 1667 * previously written list object was null. 1668 * 1669 * @return A newly created ArrayList containing strings with the same data 1670 * as those that were previously written. 1671 * 1672 * @see #writeBinderList 1673 */ 1674 public final ArrayList<IBinder> createBinderArrayList() { 1675 int N = readInt(); 1676 if (N < 0) { 1677 return null; 1678 } 1679 ArrayList<IBinder> l = new ArrayList<IBinder>(N); 1680 while (N > 0) { 1681 l.add(readStrongBinder()); 1682 N--; 1683 } 1684 return l; 1685 } 1686 1687 /** 1688 * Read into the given List items String objects that were written with 1689 * {@link #writeStringList} at the current dataPosition(). 1690 * 1691 * @return A newly created ArrayList containing strings with the same data 1692 * as those that were previously written. 1693 * 1694 * @see #writeStringList 1695 */ 1696 public final void readStringList(List<String> list) { 1697 int M = list.size(); 1698 int N = readInt(); 1699 int i = 0; 1700 for (; i < M && i < N; i++) { 1701 list.set(i, readString()); 1702 } 1703 for (; i<N; i++) { 1704 list.add(readString()); 1705 } 1706 for (; i<M; i++) { 1707 list.remove(N); 1708 } 1709 } 1710 1711 /** 1712 * Read into the given List items IBinder objects that were written with 1713 * {@link #writeBinderList} at the current dataPosition(). 1714 * 1715 * @return A newly created ArrayList containing strings with the same data 1716 * as those that were previously written. 1717 * 1718 * @see #writeBinderList 1719 */ 1720 public final void readBinderList(List<IBinder> list) { 1721 int M = list.size(); 1722 int N = readInt(); 1723 int i = 0; 1724 for (; i < M && i < N; i++) { 1725 list.set(i, readStrongBinder()); 1726 } 1727 for (; i<N; i++) { 1728 list.add(readStrongBinder()); 1729 } 1730 for (; i<M; i++) { 1731 list.remove(N); 1732 } 1733 } 1734 1735 /** 1736 * Read and return a new array containing a particular object type from 1737 * the parcel at the current dataPosition(). Returns null if the 1738 * previously written array was null. The array <em>must</em> have 1739 * previously been written via {@link #writeTypedArray} with the same 1740 * object type. 1741 * 1742 * @return A newly created array containing objects with the same data 1743 * as those that were previously written. 1744 * 1745 * @see #writeTypedArray 1746 */ 1747 public final <T> T[] createTypedArray(Parcelable.Creator<T> c) { 1748 int N = readInt(); 1749 if (N < 0) { 1750 return null; 1751 } 1752 T[] l = c.newArray(N); 1753 for (int i=0; i<N; i++) { 1754 if (readInt() != 0) { 1755 l[i] = c.createFromParcel(this); 1756 } 1757 } 1758 return l; 1759 } 1760 1761 public final <T> void readTypedArray(T[] val, Parcelable.Creator<T> c) { 1762 int N = readInt(); 1763 if (N == val.length) { 1764 for (int i=0; i<N; i++) { 1765 if (readInt() != 0) { 1766 val[i] = c.createFromParcel(this); 1767 } else { 1768 val[i] = null; 1769 } 1770 } 1771 } else { 1772 throw new RuntimeException("bad array lengths"); 1773 } 1774 } 1775 1776 /** 1777 * @deprecated 1778 * @hide 1779 */ 1780 @Deprecated 1781 public final <T> T[] readTypedArray(Parcelable.Creator<T> c) { 1782 return createTypedArray(c); 1783 } 1784 1785 /** 1786 * Write a heterogeneous array of Parcelable objects into the Parcel. 1787 * Each object in the array is written along with its class name, so 1788 * that the correct class can later be instantiated. As a result, this 1789 * has significantly more overhead than {@link #writeTypedArray}, but will 1790 * correctly handle an array containing more than one type of object. 1791 * 1792 * @param value The array of objects to be written. 1793 * @param parcelableFlags Contextual flags as per 1794 * {@link Parcelable#writeToParcel(Parcel, int) Parcelable.writeToParcel()}. 1795 * 1796 * @see #writeTypedArray 1797 */ 1798 public final <T extends Parcelable> void writeParcelableArray(T[] value, 1799 int parcelableFlags) { 1800 if (value != null) { 1801 int N = value.length; 1802 writeInt(N); 1803 for (int i=0; i<N; i++) { 1804 writeParcelable(value[i], parcelableFlags); 1805 } 1806 } else { 1807 writeInt(-1); 1808 } 1809 } 1810 1811 /** 1812 * Read a typed object from a parcel. The given class loader will be 1813 * used to load any enclosed Parcelables. If it is null, the default class 1814 * loader will be used. 1815 */ 1816 public final Object readValue(ClassLoader loader) { 1817 int type = readInt(); 1818 1819 switch (type) { 1820 case VAL_NULL: 1821 return null; 1822 1823 case VAL_STRING: 1824 return readString(); 1825 1826 case VAL_INTEGER: 1827 return readInt(); 1828 1829 case VAL_MAP: 1830 return readHashMap(loader); 1831 1832 case VAL_PARCELABLE: 1833 return readParcelable(loader); 1834 1835 case VAL_SHORT: 1836 return (short) readInt(); 1837 1838 case VAL_LONG: 1839 return readLong(); 1840 1841 case VAL_FLOAT: 1842 return readFloat(); 1843 1844 case VAL_DOUBLE: 1845 return readDouble(); 1846 1847 case VAL_BOOLEAN: 1848 return readInt() == 1; 1849 1850 case VAL_CHARSEQUENCE: 1851 return readCharSequence(); 1852 1853 case VAL_LIST: 1854 return readArrayList(loader); 1855 1856 case VAL_BOOLEANARRAY: 1857 return createBooleanArray(); 1858 1859 case VAL_BYTEARRAY: 1860 return createByteArray(); 1861 1862 case VAL_STRINGARRAY: 1863 return readStringArray(); 1864 1865 case VAL_CHARSEQUENCEARRAY: 1866 return readCharSequenceArray(); 1867 1868 case VAL_IBINDER: 1869 return readStrongBinder(); 1870 1871 case VAL_OBJECTARRAY: 1872 return readArray(loader); 1873 1874 case VAL_INTARRAY: 1875 return createIntArray(); 1876 1877 case VAL_LONGARRAY: 1878 return createLongArray(); 1879 1880 case VAL_BYTE: 1881 return readByte(); 1882 1883 case VAL_SERIALIZABLE: 1884 return readSerializable(); 1885 1886 case VAL_PARCELABLEARRAY: 1887 return readParcelableArray(loader); 1888 1889 case VAL_SPARSEARRAY: 1890 return readSparseArray(loader); 1891 1892 case VAL_SPARSEBOOLEANARRAY: 1893 return readSparseBooleanArray(); 1894 1895 case VAL_BUNDLE: 1896 return readBundle(loader); // loading will be deferred 1897 1898 default: 1899 int off = dataPosition() - 4; 1900 throw new RuntimeException( 1901 "Parcel " + this + ": Unmarshalling unknown type code " + type + " at offset " + off); 1902 } 1903 } 1904 1905 /** 1906 * Read and return a new Parcelable from the parcel. The given class loader 1907 * will be used to load any enclosed Parcelables. If it is null, the default 1908 * class loader will be used. 1909 * @param loader A ClassLoader from which to instantiate the Parcelable 1910 * object, or null for the default class loader. 1911 * @return Returns the newly created Parcelable, or null if a null 1912 * object has been written. 1913 * @throws BadParcelableException Throws BadParcelableException if there 1914 * was an error trying to instantiate the Parcelable. 1915 */ 1916 public final <T extends Parcelable> T readParcelable(ClassLoader loader) { 1917 String name = readString(); 1918 if (name == null) { 1919 return null; 1920 } 1921 Parcelable.Creator<T> creator; 1922 synchronized (mCreators) { 1923 HashMap<String,Parcelable.Creator> map = mCreators.get(loader); 1924 if (map == null) { 1925 map = new HashMap<String,Parcelable.Creator>(); 1926 mCreators.put(loader, map); 1927 } 1928 creator = map.get(name); 1929 if (creator == null) { 1930 try { 1931 Class c = loader == null ? 1932 Class.forName(name) : Class.forName(name, true, loader); 1933 Field f = c.getField("CREATOR"); 1934 creator = (Parcelable.Creator)f.get(null); 1935 } 1936 catch (IllegalAccessException e) { 1937 Log.e(TAG, "Class not found when unmarshalling: " 1938 + name + ", e: " + e); 1939 throw new BadParcelableException( 1940 "IllegalAccessException when unmarshalling: " + name); 1941 } 1942 catch (ClassNotFoundException e) { 1943 Log.e(TAG, "Class not found when unmarshalling: " 1944 + name + ", e: " + e); 1945 throw new BadParcelableException( 1946 "ClassNotFoundException when unmarshalling: " + name); 1947 } 1948 catch (ClassCastException e) { 1949 throw new BadParcelableException("Parcelable protocol requires a " 1950 + "Parcelable.Creator object called " 1951 + " CREATOR on class " + name); 1952 } 1953 catch (NoSuchFieldException e) { 1954 throw new BadParcelableException("Parcelable protocol requires a " 1955 + "Parcelable.Creator object called " 1956 + " CREATOR on class " + name); 1957 } 1958 if (creator == null) { 1959 throw new BadParcelableException("Parcelable protocol requires a " 1960 + "Parcelable.Creator object called " 1961 + " CREATOR on class " + name); 1962 } 1963 1964 map.put(name, creator); 1965 } 1966 } 1967 1968 return creator.createFromParcel(this); 1969 } 1970 1971 /** 1972 * Read and return a new Parcelable array from the parcel. 1973 * The given class loader will be used to load any enclosed 1974 * Parcelables. 1975 * @return the Parcelable array, or null if the array is null 1976 */ 1977 public final Parcelable[] readParcelableArray(ClassLoader loader) { 1978 int N = readInt(); 1979 if (N < 0) { 1980 return null; 1981 } 1982 Parcelable[] p = new Parcelable[N]; 1983 for (int i = 0; i < N; i++) { 1984 p[i] = (Parcelable) readParcelable(loader); 1985 } 1986 return p; 1987 } 1988 1989 /** 1990 * Read and return a new Serializable object from the parcel. 1991 * @return the Serializable object, or null if the Serializable name 1992 * wasn't found in the parcel. 1993 */ 1994 public final Serializable readSerializable() { 1995 String name = readString(); 1996 if (name == null) { 1997 // For some reason we were unable to read the name of the Serializable (either there 1998 // is nothing left in the Parcel to read, or the next value wasn't a String), so 1999 // return null, which indicates that the name wasn't found in the parcel. 2000 return null; 2001 } 2002 2003 byte[] serializedData = createByteArray(); 2004 ByteArrayInputStream bais = new ByteArrayInputStream(serializedData); 2005 try { 2006 ObjectInputStream ois = new ObjectInputStream(bais); 2007 return (Serializable) ois.readObject(); 2008 } catch (IOException ioe) { 2009 throw new RuntimeException("Parcelable encountered " + 2010 "IOException reading a Serializable object (name = " + name + 2011 ")", ioe); 2012 } catch (ClassNotFoundException cnfe) { 2013 throw new RuntimeException("Parcelable encountered" + 2014 "ClassNotFoundException reading a Serializable object (name = " 2015 + name + ")", cnfe); 2016 } 2017 } 2018 2019 // Cache of previously looked up CREATOR.createFromParcel() methods for 2020 // particular classes. Keys are the names of the classes, values are 2021 // Method objects. 2022 private static final HashMap<ClassLoader,HashMap<String,Parcelable.Creator>> 2023 mCreators = new HashMap<ClassLoader,HashMap<String,Parcelable.Creator>>(); 2024 2025 static protected final Parcel obtain(int obj) { 2026 final Parcel[] pool = sHolderPool; 2027 synchronized (pool) { 2028 Parcel p; 2029 for (int i=0; i<POOL_SIZE; i++) { 2030 p = pool[i]; 2031 if (p != null) { 2032 pool[i] = null; 2033 if (DEBUG_RECYCLE) { 2034 p.mStack = new RuntimeException(); 2035 } 2036 p.init(obj); 2037 return p; 2038 } 2039 } 2040 } 2041 return new Parcel(obj); 2042 } 2043 2044 private Parcel(int obj) { 2045 if (DEBUG_RECYCLE) { 2046 mStack = new RuntimeException(); 2047 } 2048 //Log.i(TAG, "Initializing obj=0x" + Integer.toHexString(obj), mStack); 2049 init(obj); 2050 } 2051 2052 @Override 2053 protected void finalize() throws Throwable { 2054 if (DEBUG_RECYCLE) { 2055 if (mStack != null) { 2056 Log.w(TAG, "Client did not call Parcel.recycle()", mStack); 2057 } 2058 } 2059 destroy(); 2060 } 2061 2062 private native void freeBuffer(); 2063 private native void init(int obj); 2064 private native void destroy(); 2065 2066 /* package */ void readMapInternal(Map outVal, int N, 2067 ClassLoader loader) { 2068 while (N > 0) { 2069 Object key = readValue(loader); 2070 Object value = readValue(loader); 2071 outVal.put(key, value); 2072 N--; 2073 } 2074 } 2075 2076 private void readListInternal(List outVal, int N, 2077 ClassLoader loader) { 2078 while (N > 0) { 2079 Object value = readValue(loader); 2080 //Log.d(TAG, "Unmarshalling value=" + value); 2081 outVal.add(value); 2082 N--; 2083 } 2084 } 2085 2086 private void readArrayInternal(Object[] outVal, int N, 2087 ClassLoader loader) { 2088 for (int i = 0; i < N; i++) { 2089 Object value = readValue(loader); 2090 //Log.d(TAG, "Unmarshalling value=" + value); 2091 outVal[i] = value; 2092 } 2093 } 2094 2095 private void readSparseArrayInternal(SparseArray outVal, int N, 2096 ClassLoader loader) { 2097 while (N > 0) { 2098 int key = readInt(); 2099 Object value = readValue(loader); 2100 //Log.i(TAG, "Unmarshalling key=" + key + " value=" + value); 2101 outVal.append(key, value); 2102 N--; 2103 } 2104 } 2105 2106 2107 private void readSparseBooleanArrayInternal(SparseBooleanArray outVal, int N) { 2108 while (N > 0) { 2109 int key = readInt(); 2110 boolean value = this.readByte() == 1; 2111 //Log.i(TAG, "Unmarshalling key=" + key + " value=" + value); 2112 outVal.append(key, value); 2113 N--; 2114 } 2115 } 2116} 2117