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