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