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