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