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