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