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