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