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