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