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 static com.android.internal.util.Preconditions.checkArgument; 20 21 import static java.util.Objects.requireNonNull; 22 23 import android.annotation.IntDef; 24 import android.annotation.NonNull; 25 import android.annotation.Nullable; 26 import android.annotation.SuppressLint; 27 import android.annotation.TestApi; 28 import android.app.AppOpsManager; 29 import android.compat.annotation.UnsupportedAppUsage; 30 import android.text.TextUtils; 31 import android.util.ArrayMap; 32 import android.util.ArraySet; 33 import android.util.ExceptionUtils; 34 import android.util.Log; 35 import android.util.MathUtils; 36 import android.util.Size; 37 import android.util.SizeF; 38 import android.util.Slog; 39 import android.util.SparseArray; 40 import android.util.SparseBooleanArray; 41 import android.util.SparseIntArray; 42 43 import com.android.internal.annotations.GuardedBy; 44 import com.android.internal.util.ArrayUtils; 45 46 import dalvik.annotation.optimization.CriticalNative; 47 import dalvik.annotation.optimization.FastNative; 48 49 import libcore.util.SneakyThrow; 50 51 import java.io.ByteArrayInputStream; 52 import java.io.ByteArrayOutputStream; 53 import java.io.FileDescriptor; 54 import java.io.IOException; 55 import java.io.ObjectInputStream; 56 import java.io.ObjectOutputStream; 57 import java.io.ObjectStreamClass; 58 import java.io.Serializable; 59 import java.lang.annotation.Retention; 60 import java.lang.annotation.RetentionPolicy; 61 import java.lang.reflect.Array; 62 import java.lang.reflect.Field; 63 import java.lang.reflect.Modifier; 64 import java.util.ArrayList; 65 import java.util.HashMap; 66 import java.util.List; 67 import java.util.Map; 68 import java.util.Objects; 69 import java.util.Set; 70 import java.util.function.BiFunction; 71 import java.util.function.Function; 72 import java.util.function.IntFunction; 73 import java.util.function.Supplier; 74 75 /** 76 * Container for a message (data and object references) that can 77 * be sent through an IBinder. A Parcel can contain both flattened data 78 * that will be unflattened on the other side of the IPC (using the various 79 * methods here for writing specific types, or the general 80 * {@link Parcelable} interface), and references to live {@link IBinder} 81 * objects that will result in the other side receiving a proxy IBinder 82 * connected with the original IBinder in the Parcel. 83 * 84 * <p class="note">Parcel is <strong>not</strong> a general-purpose 85 * serialization mechanism. This class (and the corresponding 86 * {@link Parcelable} API for placing arbitrary objects into a Parcel) is 87 * designed as a high-performance IPC transport. As such, it is not 88 * appropriate to place any Parcel data in to persistent storage: changes 89 * in the underlying implementation of any of the data in the Parcel can 90 * render older data unreadable.</p> 91 * 92 * <p>The bulk of the Parcel API revolves around reading and writing data 93 * of various types. There are six major classes of such functions available.</p> 94 * 95 * <h3>Primitives</h3> 96 * 97 * <p>The most basic data functions are for writing and reading primitive 98 * data types: {@link #writeByte}, {@link #readByte}, {@link #writeDouble}, 99 * {@link #readDouble}, {@link #writeFloat}, {@link #readFloat}, {@link #writeInt}, 100 * {@link #readInt}, {@link #writeLong}, {@link #readLong}, 101 * {@link #writeString}, {@link #readString}. Most other 102 * data operations are built on top of these. The given data is written and 103 * read using the endianess of the host CPU.</p> 104 * 105 * <h3>Primitive Arrays</h3> 106 * 107 * <p>There are a variety of methods for reading and writing raw arrays 108 * of primitive objects, which generally result in writing a 4-byte length 109 * followed by the primitive data items. The methods for reading can either 110 * read the data into an existing array, or create and return a new array. 111 * These available types are:</p> 112 * 113 * <ul> 114 * <li> {@link #writeBooleanArray(boolean[])}, 115 * {@link #readBooleanArray(boolean[])}, {@link #createBooleanArray()} 116 * <li> {@link #writeByteArray(byte[])}, 117 * {@link #writeByteArray(byte[], int, int)}, {@link #readByteArray(byte[])}, 118 * {@link #createByteArray()} 119 * <li> {@link #writeCharArray(char[])}, {@link #readCharArray(char[])}, 120 * {@link #createCharArray()} 121 * <li> {@link #writeDoubleArray(double[])}, {@link #readDoubleArray(double[])}, 122 * {@link #createDoubleArray()} 123 * <li> {@link #writeFloatArray(float[])}, {@link #readFloatArray(float[])}, 124 * {@link #createFloatArray()} 125 * <li> {@link #writeIntArray(int[])}, {@link #readIntArray(int[])}, 126 * {@link #createIntArray()} 127 * <li> {@link #writeLongArray(long[])}, {@link #readLongArray(long[])}, 128 * {@link #createLongArray()} 129 * <li> {@link #writeStringArray(String[])}, {@link #readStringArray(String[])}, 130 * {@link #createStringArray()}. 131 * <li> {@link #writeSparseBooleanArray(SparseBooleanArray)}, 132 * {@link #readSparseBooleanArray()}. 133 * </ul> 134 * 135 * <h3>Parcelables</h3> 136 * 137 * <p>The {@link Parcelable} protocol provides an extremely efficient (but 138 * low-level) protocol for objects to write and read themselves from Parcels. 139 * You can use the direct methods {@link #writeParcelable(Parcelable, int)} 140 * and {@link #readParcelable(ClassLoader)} or 141 * {@link #writeParcelableArray} and 142 * {@link #readParcelableArray(ClassLoader)} to write or read. These 143 * methods write both the class type and its data to the Parcel, allowing 144 * that class to be reconstructed from the appropriate class loader when 145 * later reading.</p> 146 * 147 * <p>There are also some methods that provide a more efficient way to work 148 * with Parcelables: {@link #writeTypedObject}, {@link #writeTypedArray}, 149 * {@link #writeTypedList}, {@link #readTypedObject}, 150 * {@link #createTypedArray} and {@link #createTypedArrayList}. These methods 151 * do not write the class information of the original object: instead, the 152 * caller of the read function must know what type to expect and pass in the 153 * appropriate {@link Parcelable.Creator Parcelable.Creator} instead to 154 * properly construct the new object and read its data. (To more efficient 155 * write and read a single Parcelable object that is not null, you can directly 156 * call {@link Parcelable#writeToParcel Parcelable.writeToParcel} and 157 * {@link Parcelable.Creator#createFromParcel Parcelable.Creator.createFromParcel} 158 * yourself.)</p> 159 * 160 * <h3>Bundles</h3> 161 * 162 * <p>A special type-safe container, called {@link Bundle}, is available 163 * for key/value maps of heterogeneous values. This has many optimizations 164 * for improved performance when reading and writing data, and its type-safe 165 * API avoids difficult to debug type errors when finally marshalling the 166 * data contents into a Parcel. The methods to use are 167 * {@link #writeBundle(Bundle)}, {@link #readBundle()}, and 168 * {@link #readBundle(ClassLoader)}. 169 * 170 * <h3>Active Objects</h3> 171 * 172 * <p>An unusual feature of Parcel is the ability to read and write active 173 * objects. For these objects the actual contents of the object is not 174 * written, rather a special token referencing the object is written. When 175 * reading the object back from the Parcel, you do not get a new instance of 176 * the object, but rather a handle that operates on the exact same object that 177 * was originally written. There are two forms of active objects available.</p> 178 * 179 * <p>{@link Binder} objects are a core facility of Android's general cross-process 180 * communication system. The {@link IBinder} interface describes an abstract 181 * protocol with a Binder object. Any such interface can be written in to 182 * a Parcel, and upon reading you will receive either the original object 183 * implementing that interface or a special proxy implementation 184 * that communicates calls back to the original object. The methods to use are 185 * {@link #writeStrongBinder(IBinder)}, 186 * {@link #writeStrongInterface(IInterface)}, {@link #readStrongBinder()}, 187 * {@link #writeBinderArray(IBinder[])}, {@link #readBinderArray(IBinder[])}, 188 * {@link #createBinderArray()}, 189 * {@link #writeInterfaceArray(T[])}, {@link #readInterfaceArray(T[], Function)}, 190 * {@link #createInterfaceArray(IntFunction, Function)}, 191 * {@link #writeBinderList(List)}, {@link #readBinderList(List)}, 192 * {@link #createBinderArrayList()}, 193 * {@link #writeInterfaceList(List)}, {@link #readInterfaceList(List, Function)}, 194 * {@link #createInterfaceArrayList(Function)}.</p> 195 * 196 * <p>FileDescriptor objects, representing raw Linux file descriptor identifiers, 197 * can be written and {@link ParcelFileDescriptor} objects returned to operate 198 * on the original file descriptor. The returned file descriptor is a dup 199 * of the original file descriptor: the object and fd is different, but 200 * operating on the same underlying file stream, with the same position, etc. 201 * The methods to use are {@link #writeFileDescriptor(FileDescriptor)}, 202 * {@link #readFileDescriptor()}. 203 * 204 * <h3>Parcelable Containers</h3> 205 * 206 * <p>A final class of methods are for writing and reading standard Java 207 * containers of arbitrary types. These all revolve around the 208 * {@link #writeValue(Object)} and {@link #readValue(ClassLoader)} methods 209 * which define the types of objects allowed. The container methods are 210 * {@link #writeArray(Object[])}, {@link #readArray(ClassLoader)}, 211 * {@link #writeList(List)}, {@link #readList(List, ClassLoader)}, 212 * {@link #readArrayList(ClassLoader)}, 213 * {@link #writeMap(Map)}, {@link #readMap(Map, ClassLoader)}, 214 * {@link #writeSparseArray(SparseArray)}, 215 * {@link #readSparseArray(ClassLoader)}. 216 * 217 * <h3>Restricted Parcelable Containers</h3> 218 * 219 * <p>A final class of methods are for reading standard Java containers of restricted types. 220 * These methods replace methods for reading containers of arbitrary types from previous section 221 * starting from Android {@link Build.VERSION_CODES#TIRAMISU}. The pairing writing methods are 222 * still the same from previous section. 223 * These methods accepts additional {@code clazz} parameters as the required types. 224 * The Restricted Parcelable container methods are {@link #readArray(ClassLoader, Class)}, 225 * {@link #readList(List, ClassLoader, Class)}, 226 * {@link #readArrayList(ClassLoader, Class)}, 227 * {@link #readMap(Map, ClassLoader, Class, Class)}, 228 * {@link #readSparseArray(ClassLoader, Class)}. 229 */ 230 public final class Parcel { 231 232 private static final boolean DEBUG_RECYCLE = false; 233 private static final boolean DEBUG_ARRAY_MAP = false; 234 private static final String TAG = "Parcel"; 235 236 @UnsupportedAppUsage 237 @SuppressWarnings({"UnusedDeclaration"}) 238 private long mNativePtr; // used by native code 239 240 /** 241 * Flag indicating if {@link #mNativePtr} was allocated by this object, 242 * indicating that we're responsible for its lifecycle. 243 */ 244 private boolean mOwnsNativeParcelObject; 245 private long mNativeSize; 246 247 private ArrayMap<Class, Object> mClassCookies; 248 249 private RuntimeException mStack; 250 251 /** @hide */ 252 @TestApi 253 public static final int FLAG_IS_REPLY_FROM_BLOCKING_ALLOWED_OBJECT = 1 << 0; 254 255 /** @hide */ 256 @TestApi 257 public static final int FLAG_PROPAGATE_ALLOW_BLOCKING = 1 << 1; 258 259 /** @hide */ 260 @IntDef(flag = true, prefix = { "FLAG_" }, value = { 261 FLAG_IS_REPLY_FROM_BLOCKING_ALLOWED_OBJECT, 262 FLAG_PROPAGATE_ALLOW_BLOCKING, 263 }) 264 @Retention(RetentionPolicy.SOURCE) 265 public @interface ParcelFlags {} 266 267 @ParcelFlags 268 private int mFlags; 269 270 /** 271 * Whether or not to parcel the stack trace of an exception. This has a performance 272 * impact, so should only be included in specific processes and only on debug builds. 273 */ 274 private static boolean sParcelExceptionStackTrace; 275 276 private static final Object sPoolSync = new Object(); 277 278 /** Next item in the linked list pool, if any */ 279 @GuardedBy("sPoolSync") 280 private Parcel mPoolNext; 281 282 /** Head of a linked list pool of {@link Parcel} objects */ 283 @GuardedBy("sPoolSync") 284 private static Parcel sOwnedPool; 285 /** Head of a linked list pool of {@link Parcel} objects */ 286 @GuardedBy("sPoolSync") 287 private static Parcel sHolderPool; 288 289 /** Total size of pool with head at {@link #sOwnedPool} */ 290 @GuardedBy("sPoolSync") 291 private static int sOwnedPoolSize = 0; 292 /** Total size of pool with head at {@link #sHolderPool} */ 293 @GuardedBy("sPoolSync") 294 private static int sHolderPoolSize = 0; 295 296 /** 297 * We're willing to pool up to 32 objects, which is sized to accommodate 298 * both a data and reply Parcel for the maximum of 16 Binder threads. 299 */ 300 private static final int POOL_SIZE = 32; 301 302 // Keep in sync with frameworks/native/include/private/binder/ParcelValTypes.h. 303 private static final int VAL_NULL = -1; 304 private static final int VAL_STRING = 0; 305 private static final int VAL_INTEGER = 1; 306 private static final int VAL_MAP = 2; // length-prefixed 307 private static final int VAL_BUNDLE = 3; 308 private static final int VAL_PARCELABLE = 4; // length-prefixed 309 private static final int VAL_SHORT = 5; 310 private static final int VAL_LONG = 6; 311 private static final int VAL_FLOAT = 7; 312 private static final int VAL_DOUBLE = 8; 313 private static final int VAL_BOOLEAN = 9; 314 private static final int VAL_CHARSEQUENCE = 10; 315 private static final int VAL_LIST = 11; // length-prefixed 316 private static final int VAL_SPARSEARRAY = 12; // length-prefixed 317 private static final int VAL_BYTEARRAY = 13; 318 private static final int VAL_STRINGARRAY = 14; 319 private static final int VAL_IBINDER = 15; 320 private static final int VAL_PARCELABLEARRAY = 16; // length-prefixed 321 private static final int VAL_OBJECTARRAY = 17; // length-prefixed 322 private static final int VAL_INTARRAY = 18; 323 private static final int VAL_LONGARRAY = 19; 324 private static final int VAL_BYTE = 20; 325 private static final int VAL_SERIALIZABLE = 21; // length-prefixed 326 private static final int VAL_SPARSEBOOLEANARRAY = 22; 327 private static final int VAL_BOOLEANARRAY = 23; 328 private static final int VAL_CHARSEQUENCEARRAY = 24; 329 private static final int VAL_PERSISTABLEBUNDLE = 25; 330 private static final int VAL_SIZE = 26; 331 private static final int VAL_SIZEF = 27; 332 private static final int VAL_DOUBLEARRAY = 28; 333 private static final int VAL_CHAR = 29; 334 private static final int VAL_SHORTARRAY = 30; 335 private static final int VAL_CHARARRAY = 31; 336 private static final int VAL_FLOATARRAY = 32; 337 338 // The initial int32 in a Binder call's reply Parcel header: 339 // Keep these in sync with libbinder's binder/Status.h. 340 private static final int EX_SECURITY = -1; 341 private static final int EX_BAD_PARCELABLE = -2; 342 private static final int EX_ILLEGAL_ARGUMENT = -3; 343 private static final int EX_NULL_POINTER = -4; 344 private static final int EX_ILLEGAL_STATE = -5; 345 private static final int EX_NETWORK_MAIN_THREAD = -6; 346 private static final int EX_UNSUPPORTED_OPERATION = -7; 347 private static final int EX_SERVICE_SPECIFIC = -8; 348 private static final int EX_PARCELABLE = -9; 349 /** @hide */ 350 public static final int EX_HAS_NOTED_APPOPS_REPLY_HEADER = -127; // special; see below 351 private static final int EX_HAS_STRICTMODE_REPLY_HEADER = -128; // special; see below 352 // EX_TRANSACTION_FAILED is used exclusively in native code. 353 // see libbinder's binder/Status.h 354 private static final int EX_TRANSACTION_FAILED = -129; 355 356 @CriticalNative nativeMarkSensitive(long nativePtr)357 private static native void nativeMarkSensitive(long nativePtr); 358 @FastNative nativeMarkForBinder(long nativePtr, IBinder binder)359 private static native void nativeMarkForBinder(long nativePtr, IBinder binder); 360 @CriticalNative nativeDataSize(long nativePtr)361 private static native int nativeDataSize(long nativePtr); 362 @CriticalNative nativeDataAvail(long nativePtr)363 private static native int nativeDataAvail(long nativePtr); 364 @CriticalNative nativeDataPosition(long nativePtr)365 private static native int nativeDataPosition(long nativePtr); 366 @CriticalNative nativeDataCapacity(long nativePtr)367 private static native int nativeDataCapacity(long nativePtr); 368 @FastNative nativeSetDataSize(long nativePtr, int size)369 private static native void nativeSetDataSize(long nativePtr, int size); 370 @CriticalNative nativeSetDataPosition(long nativePtr, int pos)371 private static native void nativeSetDataPosition(long nativePtr, int pos); 372 @FastNative nativeSetDataCapacity(long nativePtr, int size)373 private static native void nativeSetDataCapacity(long nativePtr, int size); 374 375 @CriticalNative nativePushAllowFds(long nativePtr, boolean allowFds)376 private static native boolean nativePushAllowFds(long nativePtr, boolean allowFds); 377 @CriticalNative nativeRestoreAllowFds(long nativePtr, boolean lastValue)378 private static native void nativeRestoreAllowFds(long nativePtr, boolean lastValue); 379 nativeWriteByteArray(long nativePtr, byte[] b, int offset, int len)380 private static native void nativeWriteByteArray(long nativePtr, byte[] b, int offset, int len); nativeWriteBlob(long nativePtr, byte[] b, int offset, int len)381 private static native void nativeWriteBlob(long nativePtr, byte[] b, int offset, int len); 382 @CriticalNative nativeWriteInt(long nativePtr, int val)383 private static native int nativeWriteInt(long nativePtr, int val); 384 @CriticalNative nativeWriteLong(long nativePtr, long val)385 private static native int nativeWriteLong(long nativePtr, long val); 386 @CriticalNative nativeWriteFloat(long nativePtr, float val)387 private static native int nativeWriteFloat(long nativePtr, float val); 388 @CriticalNative nativeWriteDouble(long nativePtr, double val)389 private static native int nativeWriteDouble(long nativePtr, double val); nativeSignalExceptionForError(int error)390 private static native void nativeSignalExceptionForError(int error); 391 @FastNative nativeWriteString8(long nativePtr, String val)392 private static native void nativeWriteString8(long nativePtr, String val); 393 @FastNative nativeWriteString16(long nativePtr, String val)394 private static native void nativeWriteString16(long nativePtr, String val); 395 @FastNative nativeWriteStrongBinder(long nativePtr, IBinder val)396 private static native void nativeWriteStrongBinder(long nativePtr, IBinder val); 397 @FastNative nativeWriteFileDescriptor(long nativePtr, FileDescriptor val)398 private static native void nativeWriteFileDescriptor(long nativePtr, FileDescriptor val); 399 nativeCreateByteArray(long nativePtr)400 private static native byte[] nativeCreateByteArray(long nativePtr); nativeReadByteArray(long nativePtr, byte[] dest, int destLen)401 private static native boolean nativeReadByteArray(long nativePtr, byte[] dest, int destLen); nativeReadBlob(long nativePtr)402 private static native byte[] nativeReadBlob(long nativePtr); 403 @CriticalNative nativeReadInt(long nativePtr)404 private static native int nativeReadInt(long nativePtr); 405 @CriticalNative nativeReadLong(long nativePtr)406 private static native long nativeReadLong(long nativePtr); 407 @CriticalNative nativeReadFloat(long nativePtr)408 private static native float nativeReadFloat(long nativePtr); 409 @CriticalNative nativeReadDouble(long nativePtr)410 private static native double nativeReadDouble(long nativePtr); 411 @FastNative nativeReadString8(long nativePtr)412 private static native String nativeReadString8(long nativePtr); 413 @FastNative nativeReadString16(long nativePtr)414 private static native String nativeReadString16(long nativePtr); 415 @FastNative nativeReadStrongBinder(long nativePtr)416 private static native IBinder nativeReadStrongBinder(long nativePtr); 417 @FastNative nativeReadFileDescriptor(long nativePtr)418 private static native FileDescriptor nativeReadFileDescriptor(long nativePtr); 419 nativeCreate()420 private static native long nativeCreate(); nativeFreeBuffer(long nativePtr)421 private static native void nativeFreeBuffer(long nativePtr); nativeDestroy(long nativePtr)422 private static native void nativeDestroy(long nativePtr); 423 nativeMarshall(long nativePtr)424 private static native byte[] nativeMarshall(long nativePtr); nativeUnmarshall( long nativePtr, byte[] data, int offset, int length)425 private static native void nativeUnmarshall( 426 long nativePtr, byte[] data, int offset, int length); nativeCompareData(long thisNativePtr, long otherNativePtr)427 private static native int nativeCompareData(long thisNativePtr, long otherNativePtr); nativeCompareDataInRange( long ptrA, int offsetA, long ptrB, int offsetB, int length)428 private static native boolean nativeCompareDataInRange( 429 long ptrA, int offsetA, long ptrB, int offsetB, int length); nativeAppendFrom( long thisNativePtr, long otherNativePtr, int offset, int length)430 private static native void nativeAppendFrom( 431 long thisNativePtr, long otherNativePtr, int offset, int length); 432 @CriticalNative nativeHasFileDescriptors(long nativePtr)433 private static native boolean nativeHasFileDescriptors(long nativePtr); nativeHasFileDescriptorsInRange( long nativePtr, int offset, int length)434 private static native boolean nativeHasFileDescriptorsInRange( 435 long nativePtr, int offset, int length); nativeWriteInterfaceToken(long nativePtr, String interfaceName)436 private static native void nativeWriteInterfaceToken(long nativePtr, String interfaceName); nativeEnforceInterface(long nativePtr, String interfaceName)437 private static native void nativeEnforceInterface(long nativePtr, String interfaceName); 438 439 @CriticalNative nativeReplaceCallingWorkSourceUid( long nativePtr, int workSourceUid)440 private static native boolean nativeReplaceCallingWorkSourceUid( 441 long nativePtr, int workSourceUid); 442 @CriticalNative nativeReadCallingWorkSourceUid(long nativePtr)443 private static native int nativeReadCallingWorkSourceUid(long nativePtr); 444 445 /** Last time exception with a stack trace was written */ 446 private static volatile long sLastWriteExceptionStackTrace; 447 /** Used for throttling of writing stack trace, which is costly */ 448 private static final int WRITE_EXCEPTION_STACK_TRACE_THRESHOLD_MS = 1000; 449 450 @CriticalNative nativeGetOpenAshmemSize(long nativePtr)451 private static native long nativeGetOpenAshmemSize(long nativePtr); 452 453 public final static Parcelable.Creator<String> STRING_CREATOR 454 = new Parcelable.Creator<String>() { 455 public String createFromParcel(Parcel source) { 456 return source.readString(); 457 } 458 public String[] newArray(int size) { 459 return new String[size]; 460 } 461 }; 462 463 /** 464 * @hide 465 */ 466 public static class ReadWriteHelper { 467 468 @UnsupportedAppUsage ReadWriteHelper()469 public ReadWriteHelper() { 470 } 471 472 public static final ReadWriteHelper DEFAULT = new ReadWriteHelper(); 473 474 /** 475 * Called when writing a string to a parcel. Subclasses wanting to write a string 476 * must use {@link #writeStringNoHelper(String)} to avoid 477 * infinity recursive calls. 478 */ writeString8(Parcel p, String s)479 public void writeString8(Parcel p, String s) { 480 p.writeString8NoHelper(s); 481 } 482 writeString16(Parcel p, String s)483 public void writeString16(Parcel p, String s) { 484 p.writeString16NoHelper(s); 485 } 486 487 /** 488 * Called when reading a string to a parcel. Subclasses wanting to read a string 489 * must use {@link #readStringNoHelper()} to avoid 490 * infinity recursive calls. 491 */ readString8(Parcel p)492 public String readString8(Parcel p) { 493 return p.readString8NoHelper(); 494 } 495 readString16(Parcel p)496 public String readString16(Parcel p) { 497 return p.readString16NoHelper(); 498 } 499 } 500 501 private ReadWriteHelper mReadWriteHelper = ReadWriteHelper.DEFAULT; 502 503 /** 504 * Retrieve a new Parcel object from the pool. 505 */ 506 @NonNull obtain()507 public static Parcel obtain() { 508 Parcel res = null; 509 synchronized (sPoolSync) { 510 if (sOwnedPool != null) { 511 res = sOwnedPool; 512 sOwnedPool = res.mPoolNext; 513 res.mPoolNext = null; 514 sOwnedPoolSize--; 515 } 516 } 517 518 // When no cache found above, create from scratch; otherwise prepare the 519 // cached object to be used 520 if (res == null) { 521 res = new Parcel(0); 522 } else { 523 if (DEBUG_RECYCLE) { 524 res.mStack = new RuntimeException(); 525 } 526 res.mReadWriteHelper = ReadWriteHelper.DEFAULT; 527 } 528 return res; 529 } 530 531 /** 532 * Retrieve a new Parcel object from the pool for use with a specific binder. 533 * 534 * Associate this parcel with a binder object. This marks the parcel as being prepared for a 535 * transaction on this specific binder object. Based on this, the format of the wire binder 536 * protocol may change. For future compatibility, it is recommended to use this for all 537 * Parcels. 538 */ 539 @NonNull obtain(@onNull IBinder binder)540 public static Parcel obtain(@NonNull IBinder binder) { 541 Parcel parcel = Parcel.obtain(); 542 parcel.markForBinder(binder); 543 return parcel; 544 } 545 546 /** 547 * Put a Parcel object back into the pool. You must not touch 548 * the object after this call. 549 */ recycle()550 public final void recycle() { 551 if (DEBUG_RECYCLE) mStack = null; 552 mClassCookies = null; 553 freeBuffer(); 554 555 if (mOwnsNativeParcelObject) { 556 synchronized (sPoolSync) { 557 if (sOwnedPoolSize < POOL_SIZE) { 558 mPoolNext = sOwnedPool; 559 sOwnedPool = this; 560 sOwnedPoolSize++; 561 } 562 } 563 } else { 564 mNativePtr = 0; 565 synchronized (sPoolSync) { 566 if (sHolderPoolSize < POOL_SIZE) { 567 mPoolNext = sHolderPool; 568 sHolderPool = this; 569 sHolderPoolSize++; 570 } 571 } 572 } 573 } 574 575 /** 576 * Set a {@link ReadWriteHelper}, which can be used to avoid having duplicate strings, for 577 * example. 578 * 579 * @hide 580 */ setReadWriteHelper(@ullable ReadWriteHelper helper)581 public void setReadWriteHelper(@Nullable ReadWriteHelper helper) { 582 mReadWriteHelper = helper != null ? helper : ReadWriteHelper.DEFAULT; 583 } 584 585 /** 586 * @return whether this parcel has a {@link ReadWriteHelper}. 587 * 588 * @hide 589 */ hasReadWriteHelper()590 public boolean hasReadWriteHelper() { 591 return (mReadWriteHelper != null) && (mReadWriteHelper != ReadWriteHelper.DEFAULT); 592 } 593 594 /** @hide */ 595 @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.R, trackingBug = 170729553) getGlobalAllocSize()596 public static native long getGlobalAllocSize(); 597 598 /** @hide */ 599 @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.R, trackingBug = 170729553) getGlobalAllocCount()600 public static native long getGlobalAllocCount(); 601 602 /** 603 * Parcel data should be zero'd before realloc'd or deleted. 604 * 605 * Note: currently this feature requires multiple things to work in concert: 606 * - markSensitive must be called on every relative Parcel 607 * - FLAG_CLEAR_BUF must be passed into the kernel 608 * This requires having code which does the right thing in every method and in every backend 609 * of AIDL. Rather than exposing this API, it should be replaced with a single API on 610 * IBinder objects which can be called once, and the information should be fed into the 611 * Parcel using markForBinder APIs. In terms of code size and number of API calls, this is 612 * much more extensible. 613 * 614 * @hide 615 */ markSensitive()616 public final void markSensitive() { 617 nativeMarkSensitive(mNativePtr); 618 } 619 620 /** 621 * @hide 622 */ markForBinder(@onNull IBinder binder)623 private void markForBinder(@NonNull IBinder binder) { 624 nativeMarkForBinder(mNativePtr, binder); 625 } 626 627 /** @hide */ 628 @ParcelFlags 629 @TestApi getFlags()630 public int getFlags() { 631 return mFlags; 632 } 633 634 /** @hide */ setFlags(@arcelFlags int flags)635 public void setFlags(@ParcelFlags int flags) { 636 mFlags = flags; 637 } 638 639 /** @hide */ addFlags(@arcelFlags int flags)640 public void addFlags(@ParcelFlags int flags) { 641 mFlags |= flags; 642 } 643 644 /** @hide */ hasFlags(@arcelFlags int flags)645 private boolean hasFlags(@ParcelFlags int flags) { 646 return (mFlags & flags) == flags; 647 } 648 649 /** 650 * This method is used by the AIDL compiler for system components. Not intended to be 651 * used by non-system apps. 652 */ 653 // Note: Ideally this method should be @SystemApi(client = SystemApi.Client.MODULE_LIBRARIES), 654 // but we need to make this method public due to the way the aidl compiler is compiled. 655 // We don't really need to protect it; even if 3p / non-system apps, nothing would happen. 656 // This would only work when used on a reply parcel by a binder object that's allowed-blocking. setPropagateAllowBlocking()657 public void setPropagateAllowBlocking() { 658 addFlags(FLAG_PROPAGATE_ALLOW_BLOCKING); 659 } 660 661 /** 662 * Returns the total amount of data contained in the parcel. 663 */ dataSize()664 public int dataSize() { 665 return nativeDataSize(mNativePtr); 666 } 667 668 /** 669 * Returns the amount of data remaining to be read from the 670 * parcel. That is, {@link #dataSize}-{@link #dataPosition}. 671 */ dataAvail()672 public final int dataAvail() { 673 return nativeDataAvail(mNativePtr); 674 } 675 676 /** 677 * Returns the current position in the parcel data. Never 678 * more than {@link #dataSize}. 679 */ dataPosition()680 public final int dataPosition() { 681 return nativeDataPosition(mNativePtr); 682 } 683 684 /** 685 * Returns the total amount of space in the parcel. This is always 686 * >= {@link #dataSize}. The difference between it and dataSize() is the 687 * amount of room left until the parcel needs to re-allocate its 688 * data buffer. 689 */ dataCapacity()690 public final int dataCapacity() { 691 return nativeDataCapacity(mNativePtr); 692 } 693 694 /** 695 * Change the amount of data in the parcel. Can be either smaller or 696 * larger than the current size. If larger than the current capacity, 697 * more memory will be allocated. 698 * 699 * @param size The new number of bytes in the Parcel. 700 */ setDataSize(int size)701 public final void setDataSize(int size) { 702 nativeSetDataSize(mNativePtr, size); 703 } 704 705 /** 706 * Move the current read/write position in the parcel. 707 * @param pos New offset in the parcel; must be between 0 and 708 * {@link #dataSize}. 709 */ setDataPosition(int pos)710 public final void setDataPosition(int pos) { 711 nativeSetDataPosition(mNativePtr, pos); 712 } 713 714 /** 715 * Change the capacity (current available space) of the parcel. 716 * 717 * @param size The new capacity of the parcel, in bytes. Can not be 718 * less than {@link #dataSize} -- that is, you can not drop existing data 719 * with this method. 720 */ setDataCapacity(int size)721 public final void setDataCapacity(int size) { 722 nativeSetDataCapacity(mNativePtr, size); 723 } 724 725 /** @hide */ pushAllowFds(boolean allowFds)726 public final boolean pushAllowFds(boolean allowFds) { 727 return nativePushAllowFds(mNativePtr, allowFds); 728 } 729 730 /** @hide */ restoreAllowFds(boolean lastValue)731 public final void restoreAllowFds(boolean lastValue) { 732 nativeRestoreAllowFds(mNativePtr, lastValue); 733 } 734 735 /** 736 * Returns the raw bytes of the parcel. 737 * 738 * <p class="note">The data you retrieve here <strong>must not</strong> 739 * be placed in any kind of persistent storage (on local disk, across 740 * a network, etc). For that, you should use standard serialization 741 * or another kind of general serialization mechanism. The Parcel 742 * marshalled representation is highly optimized for local IPC, and as 743 * such does not attempt to maintain compatibility with data created 744 * in different versions of the platform. 745 */ marshall()746 public final byte[] marshall() { 747 return nativeMarshall(mNativePtr); 748 } 749 750 /** 751 * Set the bytes in data to be the raw bytes of this Parcel. 752 */ unmarshall(@onNull byte[] data, int offset, int length)753 public final void unmarshall(@NonNull byte[] data, int offset, int length) { 754 nativeUnmarshall(mNativePtr, data, offset, length); 755 } 756 appendFrom(Parcel parcel, int offset, int length)757 public final void appendFrom(Parcel parcel, int offset, int length) { 758 nativeAppendFrom(mNativePtr, parcel.mNativePtr, offset, length); 759 } 760 761 /** @hide */ compareData(Parcel other)762 public int compareData(Parcel other) { 763 return nativeCompareData(mNativePtr, other.mNativePtr); 764 } 765 766 /** @hide */ compareData(Parcel a, int offsetA, Parcel b, int offsetB, int length)767 public static boolean compareData(Parcel a, int offsetA, Parcel b, int offsetB, int length) { 768 return nativeCompareDataInRange(a.mNativePtr, offsetA, b.mNativePtr, offsetB, length); 769 } 770 771 /** @hide */ setClassCookie(Class clz, Object cookie)772 public final void setClassCookie(Class clz, Object cookie) { 773 if (mClassCookies == null) { 774 mClassCookies = new ArrayMap<>(); 775 } 776 mClassCookies.put(clz, cookie); 777 } 778 779 /** @hide */ 780 @Nullable getClassCookie(Class clz)781 public final Object getClassCookie(Class clz) { 782 return mClassCookies != null ? mClassCookies.get(clz) : null; 783 } 784 785 /** @hide */ adoptClassCookies(Parcel from)786 public final void adoptClassCookies(Parcel from) { 787 mClassCookies = from.mClassCookies; 788 } 789 790 /** @hide */ copyClassCookies()791 public Map<Class, Object> copyClassCookies() { 792 return new ArrayMap<>(mClassCookies); 793 } 794 795 /** @hide */ putClassCookies(Map<Class, Object> cookies)796 public void putClassCookies(Map<Class, Object> cookies) { 797 if (cookies == null) { 798 return; 799 } 800 if (mClassCookies == null) { 801 mClassCookies = new ArrayMap<>(); 802 } 803 mClassCookies.putAll(cookies); 804 } 805 806 /** 807 * Report whether the parcel contains any marshalled file descriptors. 808 */ hasFileDescriptors()809 public boolean hasFileDescriptors() { 810 return nativeHasFileDescriptors(mNativePtr); 811 } 812 813 /** 814 * Report whether the parcel contains any marshalled file descriptors in the range defined by 815 * {@code offset} and {@code length}. 816 * 817 * @param offset The offset from which the range starts. Should be between 0 and 818 * {@link #dataSize()}. 819 * @param length The length of the range. Should be between 0 and {@link #dataSize()} - {@code 820 * offset}. 821 * @return whether there are file descriptors or not. 822 * @throws IllegalArgumentException if the parameters are out of the permitted ranges. 823 */ hasFileDescriptors(int offset, int length)824 public boolean hasFileDescriptors(int offset, int length) { 825 return nativeHasFileDescriptorsInRange(mNativePtr, offset, length); 826 } 827 828 /** 829 * Check if the object has file descriptors. 830 * 831 * <p>Objects supported are {@link Parcel} and objects that can be passed to {@link 832 * #writeValue(Object)}} 833 * 834 * <p>For most cases, it will use the self-reported {@link Parcelable#describeContents()} method 835 * for that. 836 * 837 * @throws IllegalArgumentException if you provide any object not supported by above methods 838 * (including if the unsupported object is inside a nested container). 839 * 840 * @hide 841 */ hasFileDescriptors(Object value)842 public static boolean hasFileDescriptors(Object value) { 843 if (value instanceof Parcel) { 844 Parcel parcel = (Parcel) value; 845 if (parcel.hasFileDescriptors()) { 846 return true; 847 } 848 } else if (value instanceof LazyValue) { 849 LazyValue lazy = (LazyValue) value; 850 if (lazy.hasFileDescriptors()) { 851 return true; 852 } 853 } else if (value instanceof Parcelable) { 854 Parcelable parcelable = (Parcelable) value; 855 if ((parcelable.describeContents() & Parcelable.CONTENTS_FILE_DESCRIPTOR) != 0) { 856 return true; 857 } 858 } else if (value instanceof ArrayMap<?, ?>) { 859 ArrayMap<?, ?> map = (ArrayMap<?, ?>) value; 860 for (int i = 0, n = map.size(); i < n; i++) { 861 if (hasFileDescriptors(map.keyAt(i)) 862 || hasFileDescriptors(map.valueAt(i))) { 863 return true; 864 } 865 } 866 } else if (value instanceof Map<?, ?>) { 867 Map<?, ?> map = (Map<?, ?>) value; 868 for (Map.Entry<?, ?> entry : map.entrySet()) { 869 if (hasFileDescriptors(entry.getKey()) 870 || hasFileDescriptors(entry.getValue())) { 871 return true; 872 } 873 } 874 } else if (value instanceof List<?>) { 875 List<?> list = (List<?>) value; 876 for (int i = 0, n = list.size(); i < n; i++) { 877 if (hasFileDescriptors(list.get(i))) { 878 return true; 879 } 880 } 881 } else if (value instanceof SparseArray<?>) { 882 SparseArray<?> array = (SparseArray<?>) value; 883 for (int i = 0, n = array.size(); i < n; i++) { 884 if (hasFileDescriptors(array.valueAt(i))) { 885 return true; 886 } 887 } 888 } else if (value instanceof Object[]) { 889 Object[] array = (Object[]) value; 890 for (int i = 0, n = array.length; i < n; i++) { 891 if (hasFileDescriptors(array[i])) { 892 return true; 893 } 894 } 895 } else { 896 getValueType(value); // Will throw if value is not supported 897 } 898 return false; 899 } 900 901 /** 902 * Store or read an IBinder interface token in the parcel at the current 903 * {@link #dataPosition}. This is used to validate that the marshalled 904 * transaction is intended for the target interface. This is typically written 905 * at the beginning of transactions as a header. 906 */ writeInterfaceToken(@onNull String interfaceName)907 public final void writeInterfaceToken(@NonNull String interfaceName) { 908 nativeWriteInterfaceToken(mNativePtr, interfaceName); 909 } 910 911 /** 912 * Read the header written by writeInterfaceToken and verify it matches 913 * the interface name in question. If the wrong interface type is present, 914 * {@link SecurityException} is thrown. When used over binder, this exception 915 * should propagate to the caller. 916 */ enforceInterface(@onNull String interfaceName)917 public final void enforceInterface(@NonNull String interfaceName) { 918 nativeEnforceInterface(mNativePtr, interfaceName); 919 } 920 921 /** 922 * Verify there are no bytes left to be read on the Parcel. 923 * 924 * @throws BadParcelableException If the current position hasn't reached the end of the Parcel. 925 * When used over binder, this exception should propagate to the caller. 926 */ enforceNoDataAvail()927 public void enforceNoDataAvail() { 928 final int n = dataAvail(); 929 if (n > 0) { 930 throw new BadParcelableException("Parcel data not fully consumed, unread size: " + n); 931 } 932 } 933 934 /** 935 * Writes the work source uid to the request headers. 936 * 937 * <p>It requires the headers to have been written/read already to replace the work source. 938 * 939 * @return true if the request headers have been updated. 940 * 941 * @hide 942 */ replaceCallingWorkSourceUid(int workSourceUid)943 public boolean replaceCallingWorkSourceUid(int workSourceUid) { 944 return nativeReplaceCallingWorkSourceUid(mNativePtr, workSourceUid); 945 } 946 947 /** 948 * Reads the work source uid from the request headers. 949 * 950 * <p>Unlike other read methods, this method does not read the parcel at the current 951 * {@link #dataPosition}. It will set the {@link #dataPosition} before the read and restore the 952 * position after reading the request header. 953 * 954 * @return the work source uid or {@link Binder#UNSET_WORKSOURCE} if headers have not been 955 * written/parsed yet. 956 * 957 * @hide 958 */ readCallingWorkSourceUid()959 public int readCallingWorkSourceUid() { 960 return nativeReadCallingWorkSourceUid(mNativePtr); 961 } 962 963 /** 964 * Write a byte array into the parcel at the current {@link #dataPosition}, 965 * growing {@link #dataCapacity} if needed. 966 * @param b Bytes to place into the parcel. 967 */ writeByteArray(@ullable byte[] b)968 public final void writeByteArray(@Nullable byte[] b) { 969 writeByteArray(b, 0, (b != null) ? b.length : 0); 970 } 971 972 /** 973 * Write a byte array into the parcel at the current {@link #dataPosition}, 974 * growing {@link #dataCapacity} if needed. 975 * @param b Bytes to place into the parcel. 976 * @param offset Index of first byte to be written. 977 * @param len Number of bytes to write. 978 */ writeByteArray(@ullable byte[] b, int offset, int len)979 public final void writeByteArray(@Nullable byte[] b, int offset, int len) { 980 if (b == null) { 981 writeInt(-1); 982 return; 983 } 984 ArrayUtils.throwsIfOutOfBounds(b.length, offset, len); 985 nativeWriteByteArray(mNativePtr, b, offset, len); 986 } 987 988 /** 989 * Write a blob of data into the parcel at the current {@link #dataPosition}, 990 * growing {@link #dataCapacity} if needed. 991 * 992 * <p> If the blob is small, then it is stored in-place, otherwise it is transferred by way of 993 * an anonymous shared memory region. If you prefer send in-place, please use 994 * {@link #writeByteArray(byte[])}. 995 * 996 * @param b Bytes to place into the parcel. 997 * 998 * @see #readBlob() 999 */ writeBlob(@ullable byte[] b)1000 public final void writeBlob(@Nullable byte[] b) { 1001 writeBlob(b, 0, (b != null) ? b.length : 0); 1002 } 1003 1004 /** 1005 * Write a blob of data into the parcel at the current {@link #dataPosition}, 1006 * growing {@link #dataCapacity} if needed. 1007 * 1008 * <p> If the blob is small, then it is stored in-place, otherwise it is transferred by way of 1009 * an anonymous shared memory region. If you prefer send in-place, please use 1010 * {@link #writeByteArray(byte[], int, int)}. 1011 * 1012 * @param b Bytes to place into the parcel. 1013 * @param offset Index of first byte to be written. 1014 * @param len Number of bytes to write. 1015 * 1016 * @see #readBlob() 1017 */ writeBlob(@ullable byte[] b, int offset, int len)1018 public final void writeBlob(@Nullable byte[] b, int offset, int len) { 1019 if (b == null) { 1020 writeInt(-1); 1021 return; 1022 } 1023 ArrayUtils.throwsIfOutOfBounds(b.length, offset, len); 1024 nativeWriteBlob(mNativePtr, b, offset, len); 1025 } 1026 1027 // The OK status from system/core/libutils/include/utils/Errors.h . 1028 // We shall pass all other error codes back to native for throwing exceptions. The error 1029 // check is done in Java to allow using @CriticalNative calls for the success path. 1030 private static final int OK = 0; 1031 1032 /** 1033 * Write an integer value into the parcel at the current dataPosition(), 1034 * growing dataCapacity() if needed. 1035 */ writeInt(int val)1036 public final void writeInt(int val) { 1037 int err = nativeWriteInt(mNativePtr, val); 1038 if (err != OK) { 1039 nativeSignalExceptionForError(err); 1040 } 1041 } 1042 1043 /** 1044 * Write a long integer value into the parcel at the current dataPosition(), 1045 * growing dataCapacity() if needed. 1046 */ writeLong(long val)1047 public final void writeLong(long val) { 1048 int err = nativeWriteLong(mNativePtr, val); 1049 if (err != OK) { 1050 nativeSignalExceptionForError(err); 1051 } 1052 } 1053 1054 /** 1055 * Write a floating point value into the parcel at the current 1056 * dataPosition(), growing dataCapacity() if needed. 1057 */ writeFloat(float val)1058 public final void writeFloat(float val) { 1059 int err = nativeWriteFloat(mNativePtr, val); 1060 if (err != OK) { 1061 nativeSignalExceptionForError(err); 1062 } 1063 } 1064 1065 /** 1066 * Write a double precision floating point value into the parcel at the 1067 * current dataPosition(), growing dataCapacity() if needed. 1068 */ writeDouble(double val)1069 public final void writeDouble(double val) { 1070 int err = nativeWriteDouble(mNativePtr, val); 1071 if (err != OK) { 1072 nativeSignalExceptionForError(err); 1073 } 1074 } 1075 1076 /** 1077 * Write a string value into the parcel at the current dataPosition(), 1078 * growing dataCapacity() if needed. 1079 */ writeString(@ullable String val)1080 public final void writeString(@Nullable String val) { 1081 writeString16(val); 1082 } 1083 1084 /** {@hide} */ writeString8(@ullable String val)1085 public final void writeString8(@Nullable String val) { 1086 mReadWriteHelper.writeString8(this, val); 1087 } 1088 1089 /** {@hide} */ writeString16(@ullable String val)1090 public final void writeString16(@Nullable String val) { 1091 mReadWriteHelper.writeString16(this, val); 1092 } 1093 1094 /** 1095 * Write a string without going though a {@link ReadWriteHelper}. Subclasses of 1096 * {@link ReadWriteHelper} must use this method instead of {@link #writeString} to avoid 1097 * infinity recursive calls. 1098 * 1099 * @hide 1100 */ writeStringNoHelper(@ullable String val)1101 public void writeStringNoHelper(@Nullable String val) { 1102 writeString16NoHelper(val); 1103 } 1104 1105 /** {@hide} */ writeString8NoHelper(@ullable String val)1106 public void writeString8NoHelper(@Nullable String val) { 1107 nativeWriteString8(mNativePtr, val); 1108 } 1109 1110 /** {@hide} */ writeString16NoHelper(@ullable String val)1111 public void writeString16NoHelper(@Nullable String val) { 1112 nativeWriteString16(mNativePtr, val); 1113 } 1114 1115 /** 1116 * Write a boolean value into the parcel at the current dataPosition(), 1117 * growing dataCapacity() if needed. 1118 * 1119 * <p>Note: This method currently delegates to writeInt with a value of 1 or 0 1120 * for true or false, respectively, but may change in the future. 1121 */ writeBoolean(boolean val)1122 public final void writeBoolean(boolean val) { 1123 writeInt(val ? 1 : 0); 1124 } 1125 1126 /** 1127 * Write a CharSequence value into the parcel at the current dataPosition(), 1128 * growing dataCapacity() if needed. 1129 * @hide 1130 */ 1131 @UnsupportedAppUsage writeCharSequence(@ullable CharSequence val)1132 public final void writeCharSequence(@Nullable CharSequence val) { 1133 TextUtils.writeToParcel(val, this, 0); 1134 } 1135 1136 /** 1137 * Write an object into the parcel at the current dataPosition(), 1138 * growing dataCapacity() if needed. 1139 */ writeStrongBinder(IBinder val)1140 public final void writeStrongBinder(IBinder val) { 1141 nativeWriteStrongBinder(mNativePtr, val); 1142 } 1143 1144 /** 1145 * Write an object into the parcel at the current dataPosition(), 1146 * growing dataCapacity() if needed. 1147 */ writeStrongInterface(IInterface val)1148 public final void writeStrongInterface(IInterface val) { 1149 writeStrongBinder(val == null ? null : val.asBinder()); 1150 } 1151 1152 /** 1153 * Write a FileDescriptor into the parcel at the current dataPosition(), 1154 * growing dataCapacity() if needed. 1155 * 1156 * <p class="caution">The file descriptor will not be closed, which may 1157 * result in file descriptor leaks when objects are returned from Binder 1158 * calls. Use {@link ParcelFileDescriptor#writeToParcel} instead, which 1159 * accepts contextual flags and will close the original file descriptor 1160 * if {@link Parcelable#PARCELABLE_WRITE_RETURN_VALUE} is set.</p> 1161 */ writeFileDescriptor(@onNull FileDescriptor val)1162 public final void writeFileDescriptor(@NonNull FileDescriptor val) { 1163 nativeWriteFileDescriptor(mNativePtr, val); 1164 } 1165 1166 /** 1167 * {@hide} 1168 * This will be the new name for writeFileDescriptor, for consistency. 1169 **/ writeRawFileDescriptor(@onNull FileDescriptor val)1170 public final void writeRawFileDescriptor(@NonNull FileDescriptor val) { 1171 nativeWriteFileDescriptor(mNativePtr, val); 1172 } 1173 1174 /** 1175 * {@hide} 1176 * Write an array of FileDescriptor objects into the Parcel. 1177 * 1178 * @param value The array of objects to be written. 1179 */ writeRawFileDescriptorArray(@ullable FileDescriptor[] value)1180 public final void writeRawFileDescriptorArray(@Nullable FileDescriptor[] value) { 1181 if (value != null) { 1182 int N = value.length; 1183 writeInt(N); 1184 for (int i=0; i<N; i++) { 1185 writeRawFileDescriptor(value[i]); 1186 } 1187 } else { 1188 writeInt(-1); 1189 } 1190 } 1191 1192 /** 1193 * Write a byte value into the parcel at the current dataPosition(), 1194 * growing dataCapacity() if needed. 1195 * 1196 * <p>Note: This method currently delegates to writeInt but may change in 1197 * the future. 1198 */ writeByte(byte val)1199 public final void writeByte(byte val) { 1200 writeInt(val); 1201 } 1202 1203 /** 1204 * Please use {@link #writeBundle} instead. Flattens a Map into the parcel 1205 * at the current dataPosition(), 1206 * growing dataCapacity() if needed. The Map keys must be String objects. 1207 * The Map values are written using {@link #writeValue} and must follow 1208 * the specification there. 1209 * 1210 * <p>It is strongly recommended to use {@link #writeBundle} instead of 1211 * this method, since the Bundle class provides a type-safe API that 1212 * allows you to avoid mysterious type errors at the point of marshalling. 1213 */ writeMap(@ullable Map val)1214 public final void writeMap(@Nullable Map val) { 1215 writeMapInternal((Map<String, Object>) val); 1216 } 1217 1218 /** 1219 * Flatten a Map into the parcel at the current dataPosition(), 1220 * growing dataCapacity() if needed. The Map keys must be String objects. 1221 */ writeMapInternal(@ullable Map<String,Object> val)1222 /* package */ void writeMapInternal(@Nullable Map<String,Object> val) { 1223 if (val == null) { 1224 writeInt(-1); 1225 return; 1226 } 1227 Set<Map.Entry<String,Object>> entries = val.entrySet(); 1228 int size = entries.size(); 1229 writeInt(size); 1230 1231 for (Map.Entry<String,Object> e : entries) { 1232 writeValue(e.getKey()); 1233 writeValue(e.getValue()); 1234 size--; 1235 } 1236 1237 if (size != 0) { 1238 throw new BadParcelableException("Map size does not match number of entries!"); 1239 } 1240 1241 } 1242 1243 /** 1244 * Flatten an ArrayMap into the parcel at the current dataPosition(), 1245 * growing dataCapacity() if needed. The Map keys must be String objects. 1246 */ writeArrayMapInternal(@ullable ArrayMap<String, Object> val)1247 /* package */ void writeArrayMapInternal(@Nullable ArrayMap<String, Object> val) { 1248 if (val == null) { 1249 writeInt(-1); 1250 return; 1251 } 1252 // Keep the format of this Parcel in sync with writeToParcelInner() in 1253 // frameworks/native/libs/binder/PersistableBundle.cpp. 1254 final int N = val.size(); 1255 writeInt(N); 1256 if (DEBUG_ARRAY_MAP) { 1257 RuntimeException here = new RuntimeException("here"); 1258 here.fillInStackTrace(); 1259 Log.d(TAG, "Writing " + N + " ArrayMap entries", here); 1260 } 1261 int startPos; 1262 for (int i=0; i<N; i++) { 1263 if (DEBUG_ARRAY_MAP) startPos = dataPosition(); 1264 writeString(val.keyAt(i)); 1265 writeValue(val.valueAt(i)); 1266 if (DEBUG_ARRAY_MAP) Log.d(TAG, " Write #" + i + " " 1267 + (dataPosition()-startPos) + " bytes: key=0x" 1268 + Integer.toHexString(val.keyAt(i) != null ? val.keyAt(i).hashCode() : 0) 1269 + " " + val.keyAt(i)); 1270 } 1271 } 1272 1273 /** 1274 * @hide For testing only. 1275 */ 1276 @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.R, trackingBug = 170729553) writeArrayMap(@ullable ArrayMap<String, Object> val)1277 public void writeArrayMap(@Nullable ArrayMap<String, Object> val) { 1278 writeArrayMapInternal(val); 1279 } 1280 1281 /** 1282 * Flatten an {@link ArrayMap} with string keys containing a particular object 1283 * type into the parcel at the current dataPosition() and growing dataCapacity() 1284 * if needed. The type of the objects in the array must be one that implements 1285 * Parcelable. Only the raw data of the objects is written and not their type, 1286 * so you must use the corresponding {@link #createTypedArrayMap(Parcelable.Creator)} 1287 * 1288 * @param val The map of objects to be written. 1289 * @param parcelableFlags The parcelable flags to use. 1290 * 1291 * @see #createTypedArrayMap(Parcelable.Creator) 1292 * @see Parcelable 1293 */ writeTypedArrayMap(@ullable ArrayMap<String, T> val, int parcelableFlags)1294 public <T extends Parcelable> void writeTypedArrayMap(@Nullable ArrayMap<String, T> val, 1295 int parcelableFlags) { 1296 if (val == null) { 1297 writeInt(-1); 1298 return; 1299 } 1300 final int count = val.size(); 1301 writeInt(count); 1302 for (int i = 0; i < count; i++) { 1303 writeString(val.keyAt(i)); 1304 writeTypedObject(val.valueAt(i), parcelableFlags); 1305 } 1306 } 1307 1308 /** 1309 * Write an array set to the parcel. 1310 * 1311 * @param val The array set to write. 1312 * 1313 * @hide 1314 */ 1315 @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.R, trackingBug = 170729553) writeArraySet(@ullable ArraySet<? extends Object> val)1316 public void writeArraySet(@Nullable ArraySet<? extends Object> val) { 1317 final int size = (val != null) ? val.size() : -1; 1318 writeInt(size); 1319 for (int i = 0; i < size; i++) { 1320 writeValue(val.valueAt(i)); 1321 } 1322 } 1323 1324 /** 1325 * Flatten a Bundle into the parcel at the current dataPosition(), 1326 * growing dataCapacity() if needed. 1327 */ writeBundle(@ullable Bundle val)1328 public final void writeBundle(@Nullable Bundle val) { 1329 if (val == null) { 1330 writeInt(-1); 1331 return; 1332 } 1333 1334 val.writeToParcel(this, 0); 1335 } 1336 1337 /** 1338 * Flatten a PersistableBundle into the parcel at the current dataPosition(), 1339 * growing dataCapacity() if needed. 1340 */ writePersistableBundle(@ullable PersistableBundle val)1341 public final void writePersistableBundle(@Nullable PersistableBundle val) { 1342 if (val == null) { 1343 writeInt(-1); 1344 return; 1345 } 1346 1347 val.writeToParcel(this, 0); 1348 } 1349 1350 /** 1351 * Flatten a Size into the parcel at the current dataPosition(), 1352 * growing dataCapacity() if needed. 1353 */ writeSize(@onNull Size val)1354 public final void writeSize(@NonNull Size val) { 1355 writeInt(val.getWidth()); 1356 writeInt(val.getHeight()); 1357 } 1358 1359 /** 1360 * Flatten a SizeF into the parcel at the current dataPosition(), 1361 * growing dataCapacity() if needed. 1362 */ writeSizeF(@onNull SizeF val)1363 public final void writeSizeF(@NonNull SizeF val) { 1364 writeFloat(val.getWidth()); 1365 writeFloat(val.getHeight()); 1366 } 1367 1368 /** 1369 * Flatten a List into the parcel at the current dataPosition(), growing 1370 * dataCapacity() if needed. The List values are written using 1371 * {@link #writeValue} and must follow the specification there. 1372 */ writeList(@ullable List val)1373 public final void writeList(@Nullable List val) { 1374 if (val == null) { 1375 writeInt(-1); 1376 return; 1377 } 1378 int N = val.size(); 1379 int i=0; 1380 writeInt(N); 1381 while (i < N) { 1382 writeValue(val.get(i)); 1383 i++; 1384 } 1385 } 1386 1387 /** 1388 * Flatten an Object array into the parcel at the current dataPosition(), 1389 * growing dataCapacity() if needed. The array values are written using 1390 * {@link #writeValue} and must follow the specification there. 1391 */ writeArray(@ullable Object[] val)1392 public final void writeArray(@Nullable Object[] val) { 1393 if (val == null) { 1394 writeInt(-1); 1395 return; 1396 } 1397 int N = val.length; 1398 int i=0; 1399 writeInt(N); 1400 while (i < N) { 1401 writeValue(val[i]); 1402 i++; 1403 } 1404 } 1405 1406 /** 1407 * Flatten a generic SparseArray into the parcel at the current 1408 * dataPosition(), growing dataCapacity() if needed. The SparseArray 1409 * values are written using {@link #writeValue} and must follow the 1410 * specification there. 1411 */ writeSparseArray(@ullable SparseArray<T> val)1412 public final <T> void writeSparseArray(@Nullable SparseArray<T> val) { 1413 if (val == null) { 1414 writeInt(-1); 1415 return; 1416 } 1417 int N = val.size(); 1418 writeInt(N); 1419 int i=0; 1420 while (i < N) { 1421 writeInt(val.keyAt(i)); 1422 writeValue(val.valueAt(i)); 1423 i++; 1424 } 1425 } 1426 writeSparseBooleanArray(@ullable SparseBooleanArray val)1427 public final void writeSparseBooleanArray(@Nullable SparseBooleanArray val) { 1428 if (val == null) { 1429 writeInt(-1); 1430 return; 1431 } 1432 int N = val.size(); 1433 writeInt(N); 1434 int i=0; 1435 while (i < N) { 1436 writeInt(val.keyAt(i)); 1437 writeByte((byte)(val.valueAt(i) ? 1 : 0)); 1438 i++; 1439 } 1440 } 1441 1442 /** 1443 * @hide 1444 */ writeSparseIntArray(@ullable SparseIntArray val)1445 public final void writeSparseIntArray(@Nullable SparseIntArray val) { 1446 if (val == null) { 1447 writeInt(-1); 1448 return; 1449 } 1450 int N = val.size(); 1451 writeInt(N); 1452 int i=0; 1453 while (i < N) { 1454 writeInt(val.keyAt(i)); 1455 writeInt(val.valueAt(i)); 1456 i++; 1457 } 1458 } 1459 writeBooleanArray(@ullable boolean[] val)1460 public final void writeBooleanArray(@Nullable boolean[] val) { 1461 if (val != null) { 1462 int N = val.length; 1463 writeInt(N); 1464 for (int i=0; i<N; i++) { 1465 writeInt(val[i] ? 1 : 0); 1466 } 1467 } else { 1468 writeInt(-1); 1469 } 1470 } 1471 1472 @Nullable createBooleanArray()1473 public final boolean[] createBooleanArray() { 1474 int N = readInt(); 1475 // >>2 as a fast divide-by-4 works in the create*Array() functions 1476 // because dataAvail() will never return a negative number. 4 is 1477 // the size of a stored boolean in the stream. 1478 if (N >= 0 && N <= (dataAvail() >> 2)) { 1479 boolean[] val = new boolean[N]; 1480 for (int i=0; i<N; i++) { 1481 val[i] = readInt() != 0; 1482 } 1483 return val; 1484 } else { 1485 return null; 1486 } 1487 } 1488 readBooleanArray(@onNull boolean[] val)1489 public final void readBooleanArray(@NonNull boolean[] val) { 1490 int N = readInt(); 1491 if (N == val.length) { 1492 for (int i=0; i<N; i++) { 1493 val[i] = readInt() != 0; 1494 } 1495 } else { 1496 throw new RuntimeException("bad array lengths"); 1497 } 1498 } 1499 1500 /** @hide */ writeShortArray(@ullable short[] val)1501 public void writeShortArray(@Nullable short[] val) { 1502 if (val != null) { 1503 int n = val.length; 1504 writeInt(n); 1505 for (int i = 0; i < n; i++) { 1506 writeInt(val[i]); 1507 } 1508 } else { 1509 writeInt(-1); 1510 } 1511 } 1512 1513 /** @hide */ 1514 @Nullable createShortArray()1515 public short[] createShortArray() { 1516 int n = readInt(); 1517 if (n >= 0 && n <= (dataAvail() >> 2)) { 1518 short[] val = new short[n]; 1519 for (int i = 0; i < n; i++) { 1520 val[i] = (short) readInt(); 1521 } 1522 return val; 1523 } else { 1524 return null; 1525 } 1526 } 1527 1528 /** @hide */ readShortArray(@onNull short[] val)1529 public void readShortArray(@NonNull short[] val) { 1530 int n = readInt(); 1531 if (n == val.length) { 1532 for (int i = 0; i < n; i++) { 1533 val[i] = (short) readInt(); 1534 } 1535 } else { 1536 throw new RuntimeException("bad array lengths"); 1537 } 1538 } 1539 writeCharArray(@ullable char[] val)1540 public final void writeCharArray(@Nullable char[] val) { 1541 if (val != null) { 1542 int N = val.length; 1543 writeInt(N); 1544 for (int i=0; i<N; i++) { 1545 writeInt((int)val[i]); 1546 } 1547 } else { 1548 writeInt(-1); 1549 } 1550 } 1551 1552 @Nullable createCharArray()1553 public final char[] createCharArray() { 1554 int N = readInt(); 1555 if (N >= 0 && N <= (dataAvail() >> 2)) { 1556 char[] val = new char[N]; 1557 for (int i=0; i<N; i++) { 1558 val[i] = (char)readInt(); 1559 } 1560 return val; 1561 } else { 1562 return null; 1563 } 1564 } 1565 readCharArray(@onNull char[] val)1566 public final void readCharArray(@NonNull char[] val) { 1567 int N = readInt(); 1568 if (N == val.length) { 1569 for (int i=0; i<N; i++) { 1570 val[i] = (char)readInt(); 1571 } 1572 } else { 1573 throw new RuntimeException("bad array lengths"); 1574 } 1575 } 1576 writeIntArray(@ullable int[] val)1577 public final void writeIntArray(@Nullable int[] val) { 1578 if (val != null) { 1579 int N = val.length; 1580 writeInt(N); 1581 for (int i=0; i<N; i++) { 1582 writeInt(val[i]); 1583 } 1584 } else { 1585 writeInt(-1); 1586 } 1587 } 1588 1589 @Nullable createIntArray()1590 public final int[] createIntArray() { 1591 int N = readInt(); 1592 if (N >= 0 && N <= (dataAvail() >> 2)) { 1593 int[] val = new int[N]; 1594 for (int i=0; i<N; i++) { 1595 val[i] = readInt(); 1596 } 1597 return val; 1598 } else { 1599 return null; 1600 } 1601 } 1602 readIntArray(@onNull int[] val)1603 public final void readIntArray(@NonNull int[] val) { 1604 int N = readInt(); 1605 if (N == val.length) { 1606 for (int i=0; i<N; i++) { 1607 val[i] = readInt(); 1608 } 1609 } else { 1610 throw new RuntimeException("bad array lengths"); 1611 } 1612 } 1613 writeLongArray(@ullable long[] val)1614 public final void writeLongArray(@Nullable long[] val) { 1615 if (val != null) { 1616 int N = val.length; 1617 writeInt(N); 1618 for (int i=0; i<N; i++) { 1619 writeLong(val[i]); 1620 } 1621 } else { 1622 writeInt(-1); 1623 } 1624 } 1625 1626 @Nullable createLongArray()1627 public final long[] createLongArray() { 1628 int N = readInt(); 1629 // >>3 because stored longs are 64 bits 1630 if (N >= 0 && N <= (dataAvail() >> 3)) { 1631 long[] val = new long[N]; 1632 for (int i=0; i<N; i++) { 1633 val[i] = readLong(); 1634 } 1635 return val; 1636 } else { 1637 return null; 1638 } 1639 } 1640 readLongArray(@onNull long[] val)1641 public final void readLongArray(@NonNull long[] val) { 1642 int N = readInt(); 1643 if (N == val.length) { 1644 for (int i=0; i<N; i++) { 1645 val[i] = readLong(); 1646 } 1647 } else { 1648 throw new RuntimeException("bad array lengths"); 1649 } 1650 } 1651 writeFloatArray(@ullable float[] val)1652 public final void writeFloatArray(@Nullable float[] val) { 1653 if (val != null) { 1654 int N = val.length; 1655 writeInt(N); 1656 for (int i=0; i<N; i++) { 1657 writeFloat(val[i]); 1658 } 1659 } else { 1660 writeInt(-1); 1661 } 1662 } 1663 1664 @Nullable createFloatArray()1665 public final float[] createFloatArray() { 1666 int N = readInt(); 1667 // >>2 because stored floats are 4 bytes 1668 if (N >= 0 && N <= (dataAvail() >> 2)) { 1669 float[] val = new float[N]; 1670 for (int i=0; i<N; i++) { 1671 val[i] = readFloat(); 1672 } 1673 return val; 1674 } else { 1675 return null; 1676 } 1677 } 1678 readFloatArray(@onNull float[] val)1679 public final void readFloatArray(@NonNull float[] val) { 1680 int N = readInt(); 1681 if (N == val.length) { 1682 for (int i=0; i<N; i++) { 1683 val[i] = readFloat(); 1684 } 1685 } else { 1686 throw new RuntimeException("bad array lengths"); 1687 } 1688 } 1689 writeDoubleArray(@ullable double[] val)1690 public final void writeDoubleArray(@Nullable double[] val) { 1691 if (val != null) { 1692 int N = val.length; 1693 writeInt(N); 1694 for (int i=0; i<N; i++) { 1695 writeDouble(val[i]); 1696 } 1697 } else { 1698 writeInt(-1); 1699 } 1700 } 1701 1702 @Nullable createDoubleArray()1703 public final double[] createDoubleArray() { 1704 int N = readInt(); 1705 // >>3 because stored doubles are 8 bytes 1706 if (N >= 0 && N <= (dataAvail() >> 3)) { 1707 double[] val = new double[N]; 1708 for (int i=0; i<N; i++) { 1709 val[i] = readDouble(); 1710 } 1711 return val; 1712 } else { 1713 return null; 1714 } 1715 } 1716 readDoubleArray(@onNull double[] val)1717 public final void readDoubleArray(@NonNull double[] val) { 1718 int N = readInt(); 1719 if (N == val.length) { 1720 for (int i=0; i<N; i++) { 1721 val[i] = readDouble(); 1722 } 1723 } else { 1724 throw new RuntimeException("bad array lengths"); 1725 } 1726 } 1727 writeStringArray(@ullable String[] val)1728 public final void writeStringArray(@Nullable String[] val) { 1729 writeString16Array(val); 1730 } 1731 1732 @Nullable createStringArray()1733 public final String[] createStringArray() { 1734 return createString16Array(); 1735 } 1736 readStringArray(@onNull String[] val)1737 public final void readStringArray(@NonNull String[] val) { 1738 readString16Array(val); 1739 } 1740 1741 /** {@hide} */ writeString8Array(@ullable String[] val)1742 public final void writeString8Array(@Nullable String[] val) { 1743 if (val != null) { 1744 int N = val.length; 1745 writeInt(N); 1746 for (int i=0; i<N; i++) { 1747 writeString8(val[i]); 1748 } 1749 } else { 1750 writeInt(-1); 1751 } 1752 } 1753 1754 /** {@hide} */ 1755 @Nullable createString8Array()1756 public final String[] createString8Array() { 1757 int N = readInt(); 1758 if (N >= 0) { 1759 String[] val = new String[N]; 1760 for (int i=0; i<N; i++) { 1761 val[i] = readString8(); 1762 } 1763 return val; 1764 } else { 1765 return null; 1766 } 1767 } 1768 1769 /** {@hide} */ readString8Array(@onNull String[] val)1770 public final void readString8Array(@NonNull String[] val) { 1771 int N = readInt(); 1772 if (N == val.length) { 1773 for (int i=0; i<N; i++) { 1774 val[i] = readString8(); 1775 } 1776 } else { 1777 throw new RuntimeException("bad array lengths"); 1778 } 1779 } 1780 1781 /** {@hide} */ writeString16Array(@ullable String[] val)1782 public final void writeString16Array(@Nullable String[] val) { 1783 if (val != null) { 1784 int N = val.length; 1785 writeInt(N); 1786 for (int i=0; i<N; i++) { 1787 writeString16(val[i]); 1788 } 1789 } else { 1790 writeInt(-1); 1791 } 1792 } 1793 1794 /** {@hide} */ 1795 @Nullable createString16Array()1796 public final String[] createString16Array() { 1797 int N = readInt(); 1798 if (N >= 0) { 1799 String[] val = new String[N]; 1800 for (int i=0; i<N; i++) { 1801 val[i] = readString16(); 1802 } 1803 return val; 1804 } else { 1805 return null; 1806 } 1807 } 1808 1809 /** {@hide} */ readString16Array(@onNull String[] val)1810 public final void readString16Array(@NonNull String[] val) { 1811 int N = readInt(); 1812 if (N == val.length) { 1813 for (int i=0; i<N; i++) { 1814 val[i] = readString16(); 1815 } 1816 } else { 1817 throw new RuntimeException("bad array lengths"); 1818 } 1819 } 1820 writeBinderArray(@ullable IBinder[] val)1821 public final void writeBinderArray(@Nullable IBinder[] val) { 1822 if (val != null) { 1823 int N = val.length; 1824 writeInt(N); 1825 for (int i=0; i<N; i++) { 1826 writeStrongBinder(val[i]); 1827 } 1828 } else { 1829 writeInt(-1); 1830 } 1831 } 1832 1833 /** 1834 * Flatten a homogeneous array containing an IInterface type into the parcel, 1835 * at the current dataPosition() and growing dataCapacity() if needed. The 1836 * type of the objects in the array must be one that implements IInterface. 1837 * 1838 * @param val The array of objects to be written. 1839 * 1840 * @see #createInterfaceArray 1841 * @see #readInterfaceArray 1842 * @see IInterface 1843 */ writeInterfaceArray( @uppressLint"ArrayReturn") @ullable T[] val)1844 public final <T extends IInterface> void writeInterfaceArray( 1845 @SuppressLint("ArrayReturn") @Nullable T[] val) { 1846 if (val != null) { 1847 int N = val.length; 1848 writeInt(N); 1849 for (int i=0; i<N; i++) { 1850 writeStrongInterface(val[i]); 1851 } 1852 } else { 1853 writeInt(-1); 1854 } 1855 } 1856 1857 /** 1858 * @hide 1859 */ writeCharSequenceArray(@ullable CharSequence[] val)1860 public final void writeCharSequenceArray(@Nullable CharSequence[] val) { 1861 if (val != null) { 1862 int N = val.length; 1863 writeInt(N); 1864 for (int i=0; i<N; i++) { 1865 writeCharSequence(val[i]); 1866 } 1867 } else { 1868 writeInt(-1); 1869 } 1870 } 1871 1872 /** 1873 * @hide 1874 */ writeCharSequenceList(@ullable ArrayList<CharSequence> val)1875 public final void writeCharSequenceList(@Nullable ArrayList<CharSequence> val) { 1876 if (val != null) { 1877 int N = val.size(); 1878 writeInt(N); 1879 for (int i=0; i<N; i++) { 1880 writeCharSequence(val.get(i)); 1881 } 1882 } else { 1883 writeInt(-1); 1884 } 1885 } 1886 1887 @Nullable createBinderArray()1888 public final IBinder[] createBinderArray() { 1889 int N = readInt(); 1890 if (N >= 0) { 1891 IBinder[] val = new IBinder[N]; 1892 for (int i=0; i<N; i++) { 1893 val[i] = readStrongBinder(); 1894 } 1895 return val; 1896 } else { 1897 return null; 1898 } 1899 } 1900 readBinderArray(@onNull IBinder[] val)1901 public final void readBinderArray(@NonNull IBinder[] val) { 1902 int N = readInt(); 1903 if (N == val.length) { 1904 for (int i=0; i<N; i++) { 1905 val[i] = readStrongBinder(); 1906 } 1907 } else { 1908 throw new RuntimeException("bad array lengths"); 1909 } 1910 } 1911 1912 /** 1913 * Read and return a new array of T (IInterface) from the parcel. 1914 * 1915 * @return the IInterface array of type T 1916 * @param newArray a function to create an array of T with a given length 1917 * @param asInterface a function to convert IBinder object into T (IInterface) 1918 */ 1919 @SuppressLint({"ArrayReturn", "NullableCollection", "SamShouldBeLast"}) 1920 @Nullable createInterfaceArray( @onNull IntFunction<T[]> newArray, @NonNull Function<IBinder, T> asInterface)1921 public final <T extends IInterface> T[] createInterfaceArray( 1922 @NonNull IntFunction<T[]> newArray, @NonNull Function<IBinder, T> asInterface) { 1923 int N = readInt(); 1924 if (N >= 0) { 1925 T[] val = newArray.apply(N); 1926 for (int i=0; i<N; i++) { 1927 val[i] = asInterface.apply(readStrongBinder()); 1928 } 1929 return val; 1930 } else { 1931 return null; 1932 } 1933 } 1934 1935 /** 1936 * Read an array of T (IInterface) from a parcel. 1937 * 1938 * @param asInterface a function to convert IBinder object into T (IInterface) 1939 * 1940 * @throws BadParcelableException Throws BadParcelableException if the length of `val` 1941 * mismatches the number of items in the parcel. 1942 */ readInterfaceArray( @uppressLint"ArrayReturn") @onNull T[] val, @NonNull Function<IBinder, T> asInterface)1943 public final <T extends IInterface> void readInterfaceArray( 1944 @SuppressLint("ArrayReturn") @NonNull T[] val, 1945 @NonNull Function<IBinder, T> asInterface) { 1946 int N = readInt(); 1947 if (N == val.length) { 1948 for (int i=0; i<N; i++) { 1949 val[i] = asInterface.apply(readStrongBinder()); 1950 } 1951 } else { 1952 throw new BadParcelableException("bad array lengths"); 1953 } 1954 } 1955 1956 /** 1957 * Flatten a List containing a particular object type into the parcel, at 1958 * the current dataPosition() and growing dataCapacity() if needed. The 1959 * type of the objects in the list must be one that implements Parcelable. 1960 * Unlike the generic writeList() method, however, only the raw data of the 1961 * objects is written and not their type, so you must use the corresponding 1962 * readTypedList() to unmarshall them. 1963 * 1964 * @param val The list of objects to be written. 1965 * 1966 * @see #createTypedArrayList 1967 * @see #readTypedList 1968 * @see Parcelable 1969 */ writeTypedList(@ullable List<T> val)1970 public final <T extends Parcelable> void writeTypedList(@Nullable List<T> val) { 1971 writeTypedList(val, 0); 1972 } 1973 1974 /** 1975 * Flatten a {@link SparseArray} containing a particular object type into the parcel 1976 * at the current dataPosition() and growing dataCapacity() if needed. The 1977 * type of the objects in the array must be one that implements Parcelable. 1978 * Unlike the generic {@link #writeSparseArray(SparseArray)} method, however, only 1979 * the raw data of the objects is written and not their type, so you must use the 1980 * corresponding {@link #createTypedSparseArray(Parcelable.Creator)}. 1981 * 1982 * @param val The list of objects to be written. 1983 * @param parcelableFlags The parcelable flags to use. 1984 * 1985 * @see #createTypedSparseArray(Parcelable.Creator) 1986 * @see Parcelable 1987 */ writeTypedSparseArray(@ullable SparseArray<T> val, int parcelableFlags)1988 public final <T extends Parcelable> void writeTypedSparseArray(@Nullable SparseArray<T> val, 1989 int parcelableFlags) { 1990 if (val == null) { 1991 writeInt(-1); 1992 return; 1993 } 1994 final int count = val.size(); 1995 writeInt(count); 1996 for (int i = 0; i < count; i++) { 1997 writeInt(val.keyAt(i)); 1998 writeTypedObject(val.valueAt(i), parcelableFlags); 1999 } 2000 } 2001 2002 /** 2003 * @hide 2004 */ writeTypedList(@ullable List<T> val, int parcelableFlags)2005 public <T extends Parcelable> void writeTypedList(@Nullable List<T> val, int parcelableFlags) { 2006 if (val == null) { 2007 writeInt(-1); 2008 return; 2009 } 2010 int N = val.size(); 2011 int i=0; 2012 writeInt(N); 2013 while (i < N) { 2014 writeTypedObject(val.get(i), parcelableFlags); 2015 i++; 2016 } 2017 } 2018 2019 /** 2020 * Flatten a List containing String objects into the parcel, at 2021 * the current dataPosition() and growing dataCapacity() if needed. They 2022 * can later be retrieved with {@link #createStringArrayList} or 2023 * {@link #readStringList}. 2024 * 2025 * @param val The list of strings to be written. 2026 * 2027 * @see #createStringArrayList 2028 * @see #readStringList 2029 */ writeStringList(@ullable List<String> val)2030 public final void writeStringList(@Nullable List<String> val) { 2031 if (val == null) { 2032 writeInt(-1); 2033 return; 2034 } 2035 int N = val.size(); 2036 int i=0; 2037 writeInt(N); 2038 while (i < N) { 2039 writeString(val.get(i)); 2040 i++; 2041 } 2042 } 2043 2044 /** 2045 * Flatten a List containing IBinder objects into the parcel, at 2046 * the current dataPosition() and growing dataCapacity() if needed. They 2047 * can later be retrieved with {@link #createBinderArrayList} or 2048 * {@link #readBinderList}. 2049 * 2050 * @param val The list of strings to be written. 2051 * 2052 * @see #createBinderArrayList 2053 * @see #readBinderList 2054 */ writeBinderList(@ullable List<IBinder> val)2055 public final void writeBinderList(@Nullable List<IBinder> val) { 2056 if (val == null) { 2057 writeInt(-1); 2058 return; 2059 } 2060 int N = val.size(); 2061 int i=0; 2062 writeInt(N); 2063 while (i < N) { 2064 writeStrongBinder(val.get(i)); 2065 i++; 2066 } 2067 } 2068 2069 /** 2070 * Flatten a {@code List} containing T (IInterface) objects into this parcel 2071 * at the current position. They can later be retrieved with 2072 * {@link #createInterfaceArrayList} or {@link #readInterfaceList}. 2073 * 2074 * @see #createInterfaceArrayList 2075 * @see #readInterfaceList 2076 */ writeInterfaceList(@ullable List<T> val)2077 public final <T extends IInterface> void writeInterfaceList(@Nullable List<T> val) { 2078 if (val == null) { 2079 writeInt(-1); 2080 return; 2081 } 2082 int N = val.size(); 2083 int i=0; 2084 writeInt(N); 2085 while (i < N) { 2086 writeStrongInterface(val.get(i)); 2087 i++; 2088 } 2089 } 2090 2091 /** 2092 * Flatten a {@code List} containing arbitrary {@code Parcelable} objects into this parcel 2093 * at the current position. They can later be retrieved using 2094 * {@link #readParcelableList(List, ClassLoader)} if required. 2095 * 2096 * @see #readParcelableList(List, ClassLoader) 2097 */ writeParcelableList(@ullable List<T> val, int flags)2098 public final <T extends Parcelable> void writeParcelableList(@Nullable List<T> val, int flags) { 2099 if (val == null) { 2100 writeInt(-1); 2101 return; 2102 } 2103 2104 int N = val.size(); 2105 int i=0; 2106 writeInt(N); 2107 while (i < N) { 2108 writeParcelable(val.get(i), flags); 2109 i++; 2110 } 2111 } 2112 2113 /** 2114 * Flatten a homogeneous array containing a particular object type into 2115 * the parcel, at 2116 * the current dataPosition() and growing dataCapacity() if needed. The 2117 * type of the objects in the array must be one that implements Parcelable. 2118 * Unlike the {@link #writeParcelableArray} method, however, only the 2119 * raw data of the objects is written and not their type, so you must use 2120 * {@link #readTypedArray} with the correct corresponding 2121 * {@link Parcelable.Creator} implementation to unmarshall them. 2122 * 2123 * @param val The array of objects to be written. 2124 * @param parcelableFlags Contextual flags as per 2125 * {@link Parcelable#writeToParcel(Parcel, int) Parcelable.writeToParcel()}. 2126 * 2127 * @see #readTypedArray 2128 * @see #writeParcelableArray 2129 * @see Parcelable.Creator 2130 */ writeTypedArray(@ullable T[] val, int parcelableFlags)2131 public final <T extends Parcelable> void writeTypedArray(@Nullable T[] val, 2132 int parcelableFlags) { 2133 if (val != null) { 2134 int N = val.length; 2135 writeInt(N); 2136 for (int i = 0; i < N; i++) { 2137 writeTypedObject(val[i], parcelableFlags); 2138 } 2139 } else { 2140 writeInt(-1); 2141 } 2142 } 2143 2144 /** 2145 * Flatten the Parcelable object into the parcel. 2146 * 2147 * @param val The Parcelable object to be written. 2148 * @param parcelableFlags Contextual flags as per 2149 * {@link Parcelable#writeToParcel(Parcel, int) Parcelable.writeToParcel()}. 2150 * 2151 * @see #readTypedObject 2152 */ writeTypedObject(@ullable T val, int parcelableFlags)2153 public final <T extends Parcelable> void writeTypedObject(@Nullable T val, 2154 int parcelableFlags) { 2155 if (val != null) { 2156 writeInt(1); 2157 val.writeToParcel(this, parcelableFlags); 2158 } else { 2159 writeInt(0); 2160 } 2161 } 2162 2163 /** 2164 * Flatten a homogeneous multi-dimensional array with fixed-size. This delegates to other 2165 * APIs to write a one-dimensional array. Use {@link #readFixedArray(Object)} or 2166 * {@link #createFixedArray(Class, int[])} with the same dimensions to unmarshal. 2167 * 2168 * @param val The array to be written. 2169 * @param parcelableFlags Contextual flags as per 2170 * {@link Parcelable#writeToParcel(Parcel, int) Parcelable.writeToParcel()}. 2171 * Used only if val is an array of Parcelable objects. 2172 * @param dimensions an array of int representing length of each dimension. The array should be 2173 * sized with the exact size of dimensions. 2174 * 2175 * @see #readFixedArray 2176 * @see #createFixedArray createFixedArray(Class<T>, Parcelable.Creator<S>, int...) 2177 * @see #writeBooleanArray 2178 * @see #writeByteArray 2179 * @see #writeCharArray 2180 * @see #writeIntArray 2181 * @see #writeLongArray 2182 * @see #writeFloatArray 2183 * @see #writeDoubleArray 2184 * @see #writeBinderArray 2185 * @see #writeInterfaceArray 2186 * @see #writeTypedArray 2187 * @throws BadParcelableException If the array's component type is not supported or if its 2188 * size doesn't match with the given dimensions. 2189 */ writeFixedArray(@ullable T val, int parcelableFlags, @NonNull int... dimensions)2190 public <T> void writeFixedArray(@Nullable T val, int parcelableFlags, 2191 @NonNull int... dimensions) { 2192 if (val == null) { 2193 writeInt(-1); 2194 return; 2195 } 2196 writeFixedArrayInternal(val, parcelableFlags, /*index=*/0, dimensions); 2197 } 2198 writeFixedArrayInternal(T val, int parcelableFlags, int index, int[] dimensions)2199 private <T> void writeFixedArrayInternal(T val, int parcelableFlags, int index, 2200 int[] dimensions) { 2201 if (index >= dimensions.length) { 2202 throw new BadParcelableException("Array has more dimensions than expected: " 2203 + dimensions.length); 2204 } 2205 2206 int length = dimensions[index]; 2207 2208 // val should be an array of length N 2209 if (val == null) { 2210 throw new BadParcelableException("Non-null array shouldn't have a null array."); 2211 } 2212 if (!val.getClass().isArray()) { 2213 throw new BadParcelableException("Not an array: " + val); 2214 } 2215 if (Array.getLength(val) != length) { 2216 throw new BadParcelableException("bad length: expected " + length + ", but got " 2217 + Array.getLength(val)); 2218 } 2219 2220 // Delegates to other writers if this is a one-dimensional array. 2221 // Otherwise, write component arrays with recursive calls. 2222 2223 final Class<?> componentType = val.getClass().getComponentType(); 2224 if (!componentType.isArray() && index + 1 != dimensions.length) { 2225 throw new BadParcelableException("Array has fewer dimensions than expected: " 2226 + dimensions.length); 2227 } 2228 if (componentType == boolean.class) { 2229 writeBooleanArray((boolean[]) val); 2230 } else if (componentType == byte.class) { 2231 writeByteArray((byte[]) val); 2232 } else if (componentType == char.class) { 2233 writeCharArray((char[]) val); 2234 } else if (componentType == int.class) { 2235 writeIntArray((int[]) val); 2236 } else if (componentType == long.class) { 2237 writeLongArray((long[]) val); 2238 } else if (componentType == float.class) { 2239 writeFloatArray((float[]) val); 2240 } else if (componentType == double.class) { 2241 writeDoubleArray((double[]) val); 2242 } else if (componentType == IBinder.class) { 2243 writeBinderArray((IBinder[]) val); 2244 } else if (IInterface.class.isAssignableFrom(componentType)) { 2245 writeInterfaceArray((IInterface[]) val); 2246 } else if (Parcelable.class.isAssignableFrom(componentType)) { 2247 writeTypedArray((Parcelable[]) val, parcelableFlags); 2248 } else if (componentType.isArray()) { 2249 writeInt(length); 2250 for (int i = 0; i < length; i++) { 2251 writeFixedArrayInternal(Array.get(val, i), parcelableFlags, index + 1, 2252 dimensions); 2253 } 2254 } else { 2255 throw new BadParcelableException("unknown type for fixed-size array: " + componentType); 2256 } 2257 } 2258 2259 /** 2260 * Flatten a generic object in to a parcel. The given Object value may 2261 * currently be one of the following types: 2262 * 2263 * <ul> 2264 * <li> null 2265 * <li> String 2266 * <li> Byte 2267 * <li> Short 2268 * <li> Integer 2269 * <li> Long 2270 * <li> Float 2271 * <li> Double 2272 * <li> Boolean 2273 * <li> String[] 2274 * <li> boolean[] 2275 * <li> byte[] 2276 * <li> int[] 2277 * <li> long[] 2278 * <li> Object[] (supporting objects of the same type defined here). 2279 * <li> {@link Bundle} 2280 * <li> Map (as supported by {@link #writeMap}). 2281 * <li> Any object that implements the {@link Parcelable} protocol. 2282 * <li> Parcelable[] 2283 * <li> CharSequence (as supported by {@link TextUtils#writeToParcel}). 2284 * <li> List (as supported by {@link #writeList}). 2285 * <li> {@link SparseArray} (as supported by {@link #writeSparseArray(SparseArray)}). 2286 * <li> {@link IBinder} 2287 * <li> Any object that implements Serializable (but see 2288 * {@link #writeSerializable} for caveats). Note that all of the 2289 * previous types have relatively efficient implementations for 2290 * writing to a Parcel; having to rely on the generic serialization 2291 * approach is much less efficient and should be avoided whenever 2292 * possible. 2293 * </ul> 2294 * 2295 * <p class="caution">{@link Parcelable} objects are written with 2296 * {@link Parcelable#writeToParcel} using contextual flags of 0. When 2297 * serializing objects containing {@link ParcelFileDescriptor}s, 2298 * this may result in file descriptor leaks when they are returned from 2299 * Binder calls (where {@link Parcelable#PARCELABLE_WRITE_RETURN_VALUE} 2300 * should be used).</p> 2301 */ writeValue(@ullable Object v)2302 public final void writeValue(@Nullable Object v) { 2303 if (v instanceof LazyValue) { 2304 LazyValue value = (LazyValue) v; 2305 value.writeToParcel(this); 2306 return; 2307 } 2308 int type = getValueType(v); 2309 writeInt(type); 2310 if (isLengthPrefixed(type)) { 2311 // Length 2312 int length = dataPosition(); 2313 writeInt(-1); // Placeholder 2314 // Object 2315 int start = dataPosition(); 2316 writeValue(type, v); 2317 int end = dataPosition(); 2318 // Backpatch length 2319 setDataPosition(length); 2320 writeInt(end - start); 2321 setDataPosition(end); 2322 } else { 2323 writeValue(type, v); 2324 } 2325 } 2326 2327 /** @hide */ getValueType(@ullable Object v)2328 public static int getValueType(@Nullable Object v) { 2329 if (v == null) { 2330 return VAL_NULL; 2331 } else if (v instanceof String) { 2332 return VAL_STRING; 2333 } else if (v instanceof Integer) { 2334 return VAL_INTEGER; 2335 } else if (v instanceof Map) { 2336 return VAL_MAP; 2337 } else if (v instanceof Bundle) { 2338 // Must be before Parcelable 2339 return VAL_BUNDLE; 2340 } else if (v instanceof PersistableBundle) { 2341 // Must be before Parcelable 2342 return VAL_PERSISTABLEBUNDLE; 2343 } else if (v instanceof SizeF) { 2344 // Must be before Parcelable 2345 return VAL_SIZEF; 2346 } else if (v instanceof Parcelable) { 2347 // IMPOTANT: cases for classes that implement Parcelable must 2348 // come before the Parcelable case, so that their speci fic VAL_* 2349 // types will be written. 2350 return VAL_PARCELABLE; 2351 } else if (v instanceof Short) { 2352 return VAL_SHORT; 2353 } else if (v instanceof Long) { 2354 return VAL_LONG; 2355 } else if (v instanceof Float) { 2356 return VAL_FLOAT; 2357 } else if (v instanceof Double) { 2358 return VAL_DOUBLE; 2359 } else if (v instanceof Boolean) { 2360 return VAL_BOOLEAN; 2361 } else if (v instanceof CharSequence) { 2362 // Must be after String 2363 return VAL_CHARSEQUENCE; 2364 } else if (v instanceof List) { 2365 return VAL_LIST; 2366 } else if (v instanceof SparseArray) { 2367 return VAL_SPARSEARRAY; 2368 } else if (v instanceof boolean[]) { 2369 return VAL_BOOLEANARRAY; 2370 } else if (v instanceof byte[]) { 2371 return VAL_BYTEARRAY; 2372 } else if (v instanceof String[]) { 2373 return VAL_STRINGARRAY; 2374 } else if (v instanceof CharSequence[]) { 2375 // Must be after String[] and before Object[] 2376 return VAL_CHARSEQUENCEARRAY; 2377 } else if (v instanceof IBinder) { 2378 return VAL_IBINDER; 2379 } else if (v instanceof Parcelable[]) { 2380 return VAL_PARCELABLEARRAY; 2381 } else if (v instanceof int[]) { 2382 return VAL_INTARRAY; 2383 } else if (v instanceof long[]) { 2384 return VAL_LONGARRAY; 2385 } else if (v instanceof Byte) { 2386 return VAL_BYTE; 2387 } else if (v instanceof Size) { 2388 return VAL_SIZE; 2389 } else if (v instanceof double[]) { 2390 return VAL_DOUBLEARRAY; 2391 } else if (v instanceof Character) { 2392 return VAL_CHAR; 2393 } else if (v instanceof short[]) { 2394 return VAL_SHORTARRAY; 2395 } else if (v instanceof char[]) { 2396 return VAL_CHARARRAY; 2397 } else if (v instanceof float[]) { 2398 return VAL_FLOATARRAY; 2399 } else { 2400 Class<?> clazz = v.getClass(); 2401 if (clazz.isArray() && clazz.getComponentType() == Object.class) { 2402 // Only pure Object[] are written here, Other arrays of non-primitive types are 2403 // handled by serialization as this does not record the component type. 2404 return VAL_OBJECTARRAY; 2405 } else if (v instanceof Serializable) { 2406 // Must be last 2407 return VAL_SERIALIZABLE; 2408 } else { 2409 throw new IllegalArgumentException("Parcel: unknown type for value " + v); 2410 } 2411 } 2412 } 2413 /** 2414 * Writes value {@code v} in the parcel. This does NOT write the int representing the type 2415 * first. 2416 * 2417 * @hide 2418 */ writeValue(int type, @Nullable Object v)2419 public void writeValue(int type, @Nullable Object v) { 2420 switch (type) { 2421 case VAL_NULL: 2422 break; 2423 case VAL_STRING: 2424 writeString((String) v); 2425 break; 2426 case VAL_INTEGER: 2427 writeInt((Integer) v); 2428 break; 2429 case VAL_MAP: 2430 writeMap((Map) v); 2431 break; 2432 case VAL_BUNDLE: 2433 writeBundle((Bundle) v); 2434 break; 2435 case VAL_PERSISTABLEBUNDLE: 2436 writePersistableBundle((PersistableBundle) v); 2437 break; 2438 case VAL_PARCELABLE: 2439 writeParcelable((Parcelable) v, 0); 2440 break; 2441 case VAL_SHORT: 2442 writeInt(((Short) v).intValue()); 2443 break; 2444 case VAL_LONG: 2445 writeLong((Long) v); 2446 break; 2447 case VAL_FLOAT: 2448 writeFloat((Float) v); 2449 break; 2450 case VAL_DOUBLE: 2451 writeDouble((Double) v); 2452 break; 2453 case VAL_BOOLEAN: 2454 writeInt((Boolean) v ? 1 : 0); 2455 break; 2456 case VAL_CHARSEQUENCE: 2457 writeCharSequence((CharSequence) v); 2458 break; 2459 case VAL_LIST: 2460 writeList((List) v); 2461 break; 2462 case VAL_SPARSEARRAY: 2463 writeSparseArray((SparseArray) v); 2464 break; 2465 case VAL_BOOLEANARRAY: 2466 writeBooleanArray((boolean[]) v); 2467 break; 2468 case VAL_BYTEARRAY: 2469 writeByteArray((byte[]) v); 2470 break; 2471 case VAL_STRINGARRAY: 2472 writeStringArray((String[]) v); 2473 break; 2474 case VAL_CHARSEQUENCEARRAY: 2475 writeCharSequenceArray((CharSequence[]) v); 2476 break; 2477 case VAL_IBINDER: 2478 writeStrongBinder((IBinder) v); 2479 break; 2480 case VAL_PARCELABLEARRAY: 2481 writeParcelableArray((Parcelable[]) v, 0); 2482 break; 2483 case VAL_INTARRAY: 2484 writeIntArray((int[]) v); 2485 break; 2486 case VAL_LONGARRAY: 2487 writeLongArray((long[]) v); 2488 break; 2489 case VAL_BYTE: 2490 writeInt((Byte) v); 2491 break; 2492 case VAL_SIZE: 2493 writeSize((Size) v); 2494 break; 2495 case VAL_SIZEF: 2496 writeSizeF((SizeF) v); 2497 break; 2498 case VAL_DOUBLEARRAY: 2499 writeDoubleArray((double[]) v); 2500 break; 2501 case VAL_CHAR: 2502 writeInt((Character) v); 2503 break; 2504 case VAL_SHORTARRAY: 2505 writeShortArray((short[]) v); 2506 break; 2507 case VAL_CHARARRAY: 2508 writeCharArray((char[]) v); 2509 break; 2510 case VAL_FLOATARRAY: 2511 writeFloatArray((float[]) v); 2512 break; 2513 case VAL_OBJECTARRAY: 2514 writeArray((Object[]) v); 2515 break; 2516 case VAL_SERIALIZABLE: 2517 writeSerializable((Serializable) v); 2518 break; 2519 default: 2520 throw new RuntimeException("Parcel: unable to marshal value " + v); 2521 } 2522 } 2523 2524 /** 2525 * Flatten the name of the class of the Parcelable and its contents 2526 * into the parcel. 2527 * 2528 * @param p The Parcelable object to be written. 2529 * @param parcelableFlags Contextual flags as per 2530 * {@link Parcelable#writeToParcel(Parcel, int) Parcelable.writeToParcel()}. 2531 */ writeParcelable(@ullable Parcelable p, int parcelableFlags)2532 public final void writeParcelable(@Nullable Parcelable p, int parcelableFlags) { 2533 if (p == null) { 2534 writeString(null); 2535 return; 2536 } 2537 writeParcelableCreator(p); 2538 p.writeToParcel(this, parcelableFlags); 2539 } 2540 2541 /** 2542 * Flatten the name of the class of the Parcelable into this Parcel. 2543 * 2544 * @param p The Parcelable object to be written. 2545 * @see #readParcelableCreator 2546 */ writeParcelableCreator(@onNull Parcelable p)2547 public final void writeParcelableCreator(@NonNull Parcelable p) { 2548 String name = p.getClass().getName(); 2549 writeString(name); 2550 } 2551 2552 /** 2553 * A map used by {@link #maybeWriteSquashed} to keep track of what parcelables have 2554 * been seen, and what positions they were written. The value is the absolute position of 2555 * each parcelable. 2556 */ 2557 private ArrayMap<Parcelable, Integer> mWrittenSquashableParcelables; 2558 ensureWrittenSquashableParcelables()2559 private void ensureWrittenSquashableParcelables() { 2560 if (mWrittenSquashableParcelables != null) { 2561 return; 2562 } 2563 mWrittenSquashableParcelables = new ArrayMap<>(); 2564 } 2565 2566 private boolean mAllowSquashing = false; 2567 2568 /** 2569 * Allow "squashing" writes in {@link #maybeWriteSquashed}. This allows subsequent calls to 2570 * {@link #maybeWriteSquashed(Parcelable)} to "squash" the same instances into one in a Parcel. 2571 * 2572 * Typically, this method is called at the beginning of {@link Parcelable#writeToParcel}. The 2573 * caller must retain the return value from this method and call {@link #restoreAllowSquashing} 2574 * with it. 2575 * 2576 * See {@link #maybeWriteSquashed(Parcelable)} for the details. 2577 * 2578 * @see #restoreAllowSquashing(boolean) 2579 * @see #maybeWriteSquashed(Parcelable) 2580 * @see #readSquashed(SquashReadHelper) 2581 * 2582 * @hide 2583 */ 2584 @TestApi allowSquashing()2585 public boolean allowSquashing() { 2586 boolean previous = mAllowSquashing; 2587 mAllowSquashing = true; 2588 return previous; 2589 } 2590 2591 /** 2592 * @see #allowSquashing() 2593 * @hide 2594 */ 2595 @TestApi restoreAllowSquashing(boolean previous)2596 public void restoreAllowSquashing(boolean previous) { 2597 mAllowSquashing = previous; 2598 if (!mAllowSquashing) { 2599 mWrittenSquashableParcelables = null; 2600 } 2601 } 2602 resetSqaushingState()2603 private void resetSqaushingState() { 2604 if (mAllowSquashing) { 2605 Slog.wtf(TAG, "allowSquashing wasn't restored."); 2606 } 2607 mWrittenSquashableParcelables = null; 2608 mReadSquashableParcelables = null; 2609 mAllowSquashing = false; 2610 } 2611 2612 /** 2613 * A map used by {@link #readSquashed} to cache parcelables. It's a map from 2614 * an absolute position in a Parcel to the parcelable stored at the position. 2615 */ 2616 private SparseArray<Parcelable> mReadSquashableParcelables; 2617 ensureReadSquashableParcelables()2618 private void ensureReadSquashableParcelables() { 2619 if (mReadSquashableParcelables != null) { 2620 return; 2621 } 2622 mReadSquashableParcelables = new SparseArray<>(); 2623 } 2624 2625 /** 2626 * Write a parcelable with "squash" -- that is, when the same instance is written to the 2627 * same Parcelable multiple times, instead of writing the entire instance multiple times, 2628 * only write it once, and in subsequent writes we'll only write the offset to the original 2629 * object. 2630 * 2631 * This approach does not work of the resulting Parcel is copied with {@link #appendFrom} with 2632 * a non-zero offset, so we do not enable this behavior by default. Instead, we only enable 2633 * it between {@link #allowSquashing} and {@link #restoreAllowSquashing}, in order to make sure 2634 * we only do so within each "top level" Parcelable. 2635 * 2636 * Usage: Use this method in {@link Parcelable#writeToParcel}. 2637 * If this method returns TRUE, it's a subsequent call, and the offset is already written, 2638 * so the caller doesn't have to do anything. If this method returns FALSE, it's the first 2639 * time for the instance to be written to this parcel. The caller has to proceed with its 2640 * {@link Parcelable#writeToParcel}. 2641 * 2642 * (See {@code ApplicationInfo} for the example.) 2643 * 2644 * @param p the target Parcelable to write. 2645 * 2646 * @see #allowSquashing() 2647 * @see #restoreAllowSquashing(boolean) 2648 * @see #readSquashed(SquashReadHelper) 2649 * 2650 * @hide 2651 */ maybeWriteSquashed(@onNull Parcelable p)2652 public boolean maybeWriteSquashed(@NonNull Parcelable p) { 2653 if (!mAllowSquashing) { 2654 // Don't squash, and don't put it in the map either. 2655 writeInt(0); 2656 return false; 2657 } 2658 ensureWrittenSquashableParcelables(); 2659 final Integer firstPos = mWrittenSquashableParcelables.get(p); 2660 if (firstPos != null) { 2661 // Already written. 2662 // Write the relative offset from the current position to the first position. 2663 final int pos = dataPosition(); 2664 2665 // We want the offset from the next byte of this integer, so we need to +4. 2666 writeInt(pos - firstPos + 4); 2667 return true; 2668 } 2669 // First time seen, write a marker. 2670 writeInt(0); 2671 2672 // Remember the position. 2673 final int pos = dataPosition(); 2674 mWrittenSquashableParcelables.put(p, pos); 2675 2676 // Return false and let the caller actually write the content. 2677 return false; 2678 } 2679 2680 /** 2681 * Helper function that's used by {@link #readSquashed(SquashReadHelper)} 2682 * @hide 2683 */ 2684 public interface SquashReadHelper<T> { 2685 /** Read and instantiate {@code T} from a Parcel. */ 2686 @NonNull readRawParceled(@onNull Parcel p)2687 T readRawParceled(@NonNull Parcel p); 2688 } 2689 2690 /** 2691 * Read a {@link Parcelable} that's written with {@link #maybeWriteSquashed}. 2692 * 2693 * @param reader a callback function that instantiates an instance from a parcel. 2694 * Typicallly, a lambda to the instructor that takes a {@link Parcel} is passed. 2695 * 2696 * @see #maybeWriteSquashed(Parcelable) 2697 * 2698 * @hide 2699 */ 2700 @SuppressWarnings("unchecked") 2701 @Nullable readSquashed(SquashReadHelper<T> reader)2702 public <T extends Parcelable> T readSquashed(SquashReadHelper<T> reader) { 2703 final int offset = readInt(); 2704 final int pos = dataPosition(); 2705 2706 if (offset == 0) { 2707 // First time read. Unparcel, and remember it. 2708 final T p = reader.readRawParceled(this); 2709 ensureReadSquashableParcelables(); 2710 mReadSquashableParcelables.put(pos, p); 2711 return p; 2712 } 2713 // Subsequent read. 2714 final int firstAbsolutePos = pos - offset; 2715 2716 final Parcelable p = mReadSquashableParcelables.get(firstAbsolutePos); 2717 if (p == null) { 2718 final StringBuilder sb = new StringBuilder(); 2719 for (int i = 0; i < mReadSquashableParcelables.size(); i++) { 2720 sb.append(mReadSquashableParcelables.keyAt(i)).append(' '); 2721 } 2722 Slog.wtfStack(TAG, "Map doesn't contain offset " 2723 + firstAbsolutePos 2724 + " : contains=" + sb.toString()); 2725 } 2726 return (T) p; 2727 } 2728 2729 /** 2730 * Write a generic serializable object in to a Parcel. It is strongly 2731 * recommended that this method be avoided, since the serialization 2732 * overhead is extremely large, and this approach will be much slower than 2733 * using the other approaches to writing data in to a Parcel. 2734 */ writeSerializable(@ullable Serializable s)2735 public final void writeSerializable(@Nullable Serializable s) { 2736 if (s == null) { 2737 writeString(null); 2738 return; 2739 } 2740 String name = s.getClass().getName(); 2741 writeString(name); 2742 2743 ByteArrayOutputStream baos = new ByteArrayOutputStream(); 2744 try { 2745 ObjectOutputStream oos = new ObjectOutputStream(baos); 2746 oos.writeObject(s); 2747 oos.close(); 2748 2749 writeByteArray(baos.toByteArray()); 2750 } catch (IOException ioe) { 2751 throw new BadParcelableException("Parcelable encountered " 2752 + "IOException writing serializable object (name = " 2753 + name + ")", ioe); 2754 } 2755 } 2756 2757 /** @hide For debugging purposes */ setStackTraceParceling(boolean enabled)2758 public static void setStackTraceParceling(boolean enabled) { 2759 sParcelExceptionStackTrace = enabled; 2760 } 2761 2762 /** 2763 * Special function for writing an exception result at the header of 2764 * a parcel, to be used when returning an exception from a transaction. 2765 * Note that this currently only supports a few exception types; any other 2766 * exception will be re-thrown by this function as a RuntimeException 2767 * (to be caught by the system's last-resort exception handling when 2768 * dispatching a transaction). 2769 * 2770 * <p>The supported exception types are: 2771 * <ul> 2772 * <li>{@link BadParcelableException} 2773 * <li>{@link IllegalArgumentException} 2774 * <li>{@link IllegalStateException} 2775 * <li>{@link NullPointerException} 2776 * <li>{@link SecurityException} 2777 * <li>{@link UnsupportedOperationException} 2778 * <li>{@link NetworkOnMainThreadException} 2779 * </ul> 2780 * 2781 * @param e The Exception to be written. 2782 * 2783 * @see #writeNoException 2784 * @see #readException 2785 */ writeException(@onNull Exception e)2786 public final void writeException(@NonNull Exception e) { 2787 AppOpsManager.prefixParcelWithAppOpsIfNeeded(this); 2788 2789 int code = getExceptionCode(e); 2790 writeInt(code); 2791 StrictMode.clearGatheredViolations(); 2792 if (code == 0) { 2793 if (e instanceof RuntimeException) { 2794 throw (RuntimeException) e; 2795 } 2796 throw new RuntimeException(e); 2797 } 2798 writeString(e.getMessage()); 2799 final long timeNow = sParcelExceptionStackTrace ? SystemClock.elapsedRealtime() : 0; 2800 if (sParcelExceptionStackTrace && (timeNow - sLastWriteExceptionStackTrace 2801 > WRITE_EXCEPTION_STACK_TRACE_THRESHOLD_MS)) { 2802 sLastWriteExceptionStackTrace = timeNow; 2803 writeStackTrace(e); 2804 } else { 2805 writeInt(0); 2806 } 2807 switch (code) { 2808 case EX_SERVICE_SPECIFIC: 2809 writeInt(((ServiceSpecificException) e).errorCode); 2810 break; 2811 case EX_PARCELABLE: 2812 // Write parceled exception prefixed by length 2813 final int sizePosition = dataPosition(); 2814 writeInt(0); 2815 writeParcelable((Parcelable) e, Parcelable.PARCELABLE_WRITE_RETURN_VALUE); 2816 final int payloadPosition = dataPosition(); 2817 setDataPosition(sizePosition); 2818 writeInt(payloadPosition - sizePosition); 2819 setDataPosition(payloadPosition); 2820 break; 2821 } 2822 } 2823 2824 /** @hide */ getExceptionCode(@onNull Throwable e)2825 public static int getExceptionCode(@NonNull Throwable e) { 2826 int code = 0; 2827 if (e instanceof Parcelable 2828 && (e.getClass().getClassLoader() == Parcelable.class.getClassLoader())) { 2829 // We only send Parcelable exceptions that are in the 2830 // BootClassLoader to ensure that the receiver can unpack them 2831 code = EX_PARCELABLE; 2832 } else if (e instanceof SecurityException) { 2833 code = EX_SECURITY; 2834 } else if (e instanceof BadParcelableException) { 2835 code = EX_BAD_PARCELABLE; 2836 } else if (e instanceof IllegalArgumentException) { 2837 code = EX_ILLEGAL_ARGUMENT; 2838 } else if (e instanceof NullPointerException) { 2839 code = EX_NULL_POINTER; 2840 } else if (e instanceof IllegalStateException) { 2841 code = EX_ILLEGAL_STATE; 2842 } else if (e instanceof NetworkOnMainThreadException) { 2843 code = EX_NETWORK_MAIN_THREAD; 2844 } else if (e instanceof UnsupportedOperationException) { 2845 code = EX_UNSUPPORTED_OPERATION; 2846 } else if (e instanceof ServiceSpecificException) { 2847 code = EX_SERVICE_SPECIFIC; 2848 } 2849 return code; 2850 } 2851 2852 /** @hide */ writeStackTrace(@onNull Throwable e)2853 public void writeStackTrace(@NonNull Throwable e) { 2854 final int sizePosition = dataPosition(); 2855 writeInt(0); // Header size will be filled in later 2856 StackTraceElement[] stackTrace = e.getStackTrace(); 2857 final int truncatedSize = Math.min(stackTrace.length, 5); 2858 StringBuilder sb = new StringBuilder(); 2859 for (int i = 0; i < truncatedSize; i++) { 2860 sb.append("\tat ").append(stackTrace[i]).append('\n'); 2861 } 2862 writeString(sb.toString()); 2863 final int payloadPosition = dataPosition(); 2864 setDataPosition(sizePosition); 2865 // Write stack trace header size. Used in native side to skip the header 2866 writeInt(payloadPosition - sizePosition); 2867 setDataPosition(payloadPosition); 2868 } 2869 2870 /** 2871 * Special function for writing information at the front of the Parcel 2872 * indicating that no exception occurred. 2873 * 2874 * @see #writeException 2875 * @see #readException 2876 */ writeNoException()2877 public final void writeNoException() { 2878 AppOpsManager.prefixParcelWithAppOpsIfNeeded(this); 2879 2880 // Despite the name of this function ("write no exception"), 2881 // it should instead be thought of as "write the RPC response 2882 // header", but because this function name is written out by 2883 // the AIDL compiler, we're not going to rename it. 2884 // 2885 // The response header, in the non-exception case (see also 2886 // writeException above, also called by the AIDL compiler), is 2887 // either a 0 (the default case), or EX_HAS_STRICTMODE_REPLY_HEADER if 2888 // StrictMode has gathered up violations that have occurred 2889 // during a Binder call, in which case we write out the number 2890 // of violations and their details, serialized, before the 2891 // actual RPC respons data. The receiving end of this is 2892 // readException(), below. 2893 if (StrictMode.hasGatheredViolations()) { 2894 writeInt(EX_HAS_STRICTMODE_REPLY_HEADER); 2895 final int sizePosition = dataPosition(); 2896 writeInt(0); // total size of fat header, to be filled in later 2897 StrictMode.writeGatheredViolationsToParcel(this); 2898 final int payloadPosition = dataPosition(); 2899 setDataPosition(sizePosition); 2900 writeInt(payloadPosition - sizePosition); // header size 2901 setDataPosition(payloadPosition); 2902 } else { 2903 writeInt(0); 2904 } 2905 } 2906 2907 /** 2908 * Special function for reading an exception result from the header of 2909 * a parcel, to be used after receiving the result of a transaction. This 2910 * will throw the exception for you if it had been written to the Parcel, 2911 * otherwise return and let you read the normal result data from the Parcel. 2912 * 2913 * @see #writeException 2914 * @see #writeNoException 2915 */ readException()2916 public final void readException() { 2917 int code = readExceptionCode(); 2918 if (code != 0) { 2919 String msg = readString(); 2920 readException(code, msg); 2921 } 2922 } 2923 2924 /** 2925 * Parses the header of a Binder call's response Parcel and 2926 * returns the exception code. Deals with lite or fat headers. 2927 * In the common successful case, this header is generally zero. 2928 * In less common cases, it's a small negative number and will be 2929 * followed by an error string. 2930 * 2931 * This exists purely for android.database.DatabaseUtils and 2932 * insulating it from having to handle fat headers as returned by 2933 * e.g. StrictMode-induced RPC responses. 2934 * 2935 * @hide 2936 */ 2937 @UnsupportedAppUsage 2938 @TestApi readExceptionCode()2939 public final int readExceptionCode() { 2940 int code = readInt(); 2941 if (code == EX_HAS_NOTED_APPOPS_REPLY_HEADER) { 2942 AppOpsManager.readAndLogNotedAppops(this); 2943 // Read next header or real exception if there is no more header 2944 code = readInt(); 2945 } 2946 2947 if (code == EX_HAS_STRICTMODE_REPLY_HEADER) { 2948 int headerSize = readInt(); 2949 if (headerSize == 0) { 2950 Log.e(TAG, "Unexpected zero-sized Parcel reply header."); 2951 } else { 2952 // Currently the only thing in the header is StrictMode stacks, 2953 // but discussions around event/RPC tracing suggest we might 2954 // put that here too. If so, switch on sub-header tags here. 2955 // But for now, just parse out the StrictMode stuff. 2956 StrictMode.readAndHandleBinderCallViolations(this); 2957 } 2958 // And fat response headers are currently only used when 2959 // there are no exceptions, so return no error: 2960 return 0; 2961 } 2962 return code; 2963 } 2964 2965 /** 2966 * Throw an exception with the given message. Not intended for use 2967 * outside the Parcel class. 2968 * 2969 * @param code Used to determine which exception class to throw. 2970 * @param msg The exception message. 2971 */ readException(int code, String msg)2972 public final void readException(int code, String msg) { 2973 String remoteStackTrace = null; 2974 final int remoteStackPayloadSize = readInt(); 2975 if (remoteStackPayloadSize > 0) { 2976 remoteStackTrace = readString(); 2977 } 2978 Exception e = createException(code, msg); 2979 // Attach remote stack trace if availalble 2980 if (remoteStackTrace != null) { 2981 RemoteException cause = new RemoteException( 2982 "Remote stack trace:\n" + remoteStackTrace, null, false, false); 2983 ExceptionUtils.appendCause(e, cause); 2984 } 2985 SneakyThrow.sneakyThrow(e); 2986 } 2987 2988 /** 2989 * Creates an exception with the given message. 2990 * 2991 * @param code Used to determine which exception class to throw. 2992 * @param msg The exception message. 2993 */ createException(int code, String msg)2994 private Exception createException(int code, String msg) { 2995 Exception exception = createExceptionOrNull(code, msg); 2996 return exception != null 2997 ? exception 2998 : new RuntimeException("Unknown exception code: " + code + " msg " + msg); 2999 } 3000 3001 /** @hide */ createExceptionOrNull(int code, String msg)3002 public Exception createExceptionOrNull(int code, String msg) { 3003 switch (code) { 3004 case EX_PARCELABLE: 3005 if (readInt() > 0) { 3006 return (Exception) readParcelable(Parcelable.class.getClassLoader()); 3007 } else { 3008 return new RuntimeException(msg + " [missing Parcelable]"); 3009 } 3010 case EX_SECURITY: 3011 return new SecurityException(msg); 3012 case EX_BAD_PARCELABLE: 3013 return new BadParcelableException(msg); 3014 case EX_ILLEGAL_ARGUMENT: 3015 return new IllegalArgumentException(msg); 3016 case EX_NULL_POINTER: 3017 return new NullPointerException(msg); 3018 case EX_ILLEGAL_STATE: 3019 return new IllegalStateException(msg); 3020 case EX_NETWORK_MAIN_THREAD: 3021 return new NetworkOnMainThreadException(); 3022 case EX_UNSUPPORTED_OPERATION: 3023 return new UnsupportedOperationException(msg); 3024 case EX_SERVICE_SPECIFIC: 3025 return new ServiceSpecificException(readInt(), msg); 3026 default: 3027 return null; 3028 } 3029 } 3030 3031 /** 3032 * Read an integer value from the parcel at the current dataPosition(). 3033 */ readInt()3034 public final int readInt() { 3035 return nativeReadInt(mNativePtr); 3036 } 3037 3038 /** 3039 * Read a long integer value from the parcel at the current dataPosition(). 3040 */ readLong()3041 public final long readLong() { 3042 return nativeReadLong(mNativePtr); 3043 } 3044 3045 /** 3046 * Read a floating point value from the parcel at the current 3047 * dataPosition(). 3048 */ readFloat()3049 public final float readFloat() { 3050 return nativeReadFloat(mNativePtr); 3051 } 3052 3053 /** 3054 * Read a double precision floating point value from the parcel at the 3055 * current dataPosition(). 3056 */ readDouble()3057 public final double readDouble() { 3058 return nativeReadDouble(mNativePtr); 3059 } 3060 3061 /** 3062 * Read a string value from the parcel at the current dataPosition(). 3063 */ 3064 @Nullable readString()3065 public final String readString() { 3066 return readString16(); 3067 } 3068 3069 /** {@hide} */ readString8()3070 public final @Nullable String readString8() { 3071 return mReadWriteHelper.readString8(this); 3072 } 3073 3074 /** {@hide} */ readString16()3075 public final @Nullable String readString16() { 3076 return mReadWriteHelper.readString16(this); 3077 } 3078 3079 /** 3080 * Read a string without going though a {@link ReadWriteHelper}. Subclasses of 3081 * {@link ReadWriteHelper} must use this method instead of {@link #readString} to avoid 3082 * infinity recursive calls. 3083 * 3084 * @hide 3085 */ readStringNoHelper()3086 public @Nullable String readStringNoHelper() { 3087 return readString16NoHelper(); 3088 } 3089 3090 /** {@hide} */ readString8NoHelper()3091 public @Nullable String readString8NoHelper() { 3092 return nativeReadString8(mNativePtr); 3093 } 3094 3095 /** {@hide} */ readString16NoHelper()3096 public @Nullable String readString16NoHelper() { 3097 return nativeReadString16(mNativePtr); 3098 } 3099 3100 /** 3101 * Read a boolean value from the parcel at the current dataPosition(). 3102 */ readBoolean()3103 public final boolean readBoolean() { 3104 return readInt() != 0; 3105 } 3106 3107 /** 3108 * Read a CharSequence value from the parcel at the current dataPosition(). 3109 * @hide 3110 */ 3111 @UnsupportedAppUsage 3112 @Nullable readCharSequence()3113 public final CharSequence readCharSequence() { 3114 return TextUtils.CHAR_SEQUENCE_CREATOR.createFromParcel(this); 3115 } 3116 3117 /** 3118 * Read an object from the parcel at the current dataPosition(). 3119 */ readStrongBinder()3120 public final IBinder readStrongBinder() { 3121 final IBinder result = nativeReadStrongBinder(mNativePtr); 3122 3123 // If it's a reply from a method with @PropagateAllowBlocking, then inherit allow-blocking 3124 // from the object that returned it. 3125 if (result != null && hasFlags( 3126 FLAG_IS_REPLY_FROM_BLOCKING_ALLOWED_OBJECT | FLAG_PROPAGATE_ALLOW_BLOCKING)) { 3127 Binder.allowBlocking(result); 3128 } 3129 return result; 3130 } 3131 3132 /** 3133 * Read a FileDescriptor from the parcel at the current dataPosition(). 3134 */ readFileDescriptor()3135 public final ParcelFileDescriptor readFileDescriptor() { 3136 FileDescriptor fd = nativeReadFileDescriptor(mNativePtr); 3137 return fd != null ? new ParcelFileDescriptor(fd) : null; 3138 } 3139 3140 /** {@hide} */ 3141 @UnsupportedAppUsage readRawFileDescriptor()3142 public final FileDescriptor readRawFileDescriptor() { 3143 return nativeReadFileDescriptor(mNativePtr); 3144 } 3145 3146 /** 3147 * {@hide} 3148 * Read and return a new array of FileDescriptors from the parcel. 3149 * @return the FileDescriptor array, or null if the array is null. 3150 **/ 3151 @Nullable createRawFileDescriptorArray()3152 public final FileDescriptor[] createRawFileDescriptorArray() { 3153 int N = readInt(); 3154 if (N < 0) { 3155 return null; 3156 } 3157 FileDescriptor[] f = new FileDescriptor[N]; 3158 for (int i = 0; i < N; i++) { 3159 f[i] = readRawFileDescriptor(); 3160 } 3161 return f; 3162 } 3163 3164 /** 3165 * {@hide} 3166 * Read an array of FileDescriptors from a parcel. 3167 * The passed array must be exactly the length of the array in the parcel. 3168 * @return the FileDescriptor array, or null if the array is null. 3169 **/ readRawFileDescriptorArray(FileDescriptor[] val)3170 public final void readRawFileDescriptorArray(FileDescriptor[] val) { 3171 int N = readInt(); 3172 if (N == val.length) { 3173 for (int i=0; i<N; i++) { 3174 val[i] = readRawFileDescriptor(); 3175 } 3176 } else { 3177 throw new RuntimeException("bad array lengths"); 3178 } 3179 } 3180 3181 /** 3182 * Read a byte value from the parcel at the current dataPosition(). 3183 */ readByte()3184 public final byte readByte() { 3185 return (byte)(readInt() & 0xff); 3186 } 3187 3188 /** 3189 * Please use {@link #readBundle(ClassLoader)} instead (whose data must have 3190 * been written with {@link #writeBundle}. Read into an existing Map object 3191 * from the parcel at the current dataPosition(). 3192 * 3193 * @deprecated Consider using {@link #readBundle(ClassLoader)} as stated above, in case this 3194 * method is still preferred use the type-safer version {@link #readMap(Map, ClassLoader, 3195 * Class, Class)} starting from Android {@link Build.VERSION_CODES#TIRAMISU}. 3196 */ 3197 @Deprecated readMap(@onNull Map outVal, @Nullable ClassLoader loader)3198 public final void readMap(@NonNull Map outVal, @Nullable ClassLoader loader) { 3199 readMapInternal(outVal, loader, /* clazzKey */ null, /* clazzValue */ null); 3200 } 3201 3202 /** 3203 * Same as {@link #readMap(Map, ClassLoader)} but accepts {@code clazzKey} and 3204 * {@code clazzValue} parameter as the types required for each key and value pair. 3205 * 3206 * @throws BadParcelableException If the item to be deserialized is not an instance of that 3207 * class or any of its children class 3208 */ readMap(@onNull Map<? super K, ? super V> outVal, @Nullable ClassLoader loader, @NonNull Class<K> clazzKey, @NonNull Class<V> clazzValue)3209 public <K, V> void readMap(@NonNull Map<? super K, ? super V> outVal, 3210 @Nullable ClassLoader loader, @NonNull Class<K> clazzKey, 3211 @NonNull Class<V> clazzValue) { 3212 Objects.requireNonNull(clazzKey); 3213 Objects.requireNonNull(clazzValue); 3214 readMapInternal(outVal, loader, clazzKey, clazzValue); 3215 } 3216 3217 /** 3218 * Read into an existing List object from the parcel at the current 3219 * dataPosition(), using the given class loader to load any enclosed 3220 * Parcelables. If it is null, the default class loader is used. 3221 * 3222 * @deprecated Use the type-safer version {@link #readList(List, ClassLoader, Class)} starting 3223 * from Android {@link Build.VERSION_CODES#TIRAMISU}. Also consider changing the format to 3224 * use {@link #readTypedList(List, Parcelable.Creator)} if possible (eg. if the items' 3225 * class is final) since this is also more performant. Note that changing to the latter 3226 * also requires changing the writes. 3227 */ 3228 @Deprecated readList(@onNull List outVal, @Nullable ClassLoader loader)3229 public final void readList(@NonNull List outVal, @Nullable ClassLoader loader) { 3230 int N = readInt(); 3231 readListInternal(outVal, N, loader, /* clazz */ null); 3232 } 3233 3234 /** 3235 * Same as {@link #readList(List, ClassLoader)} but accepts {@code clazz} parameter as 3236 * the type required for each item. 3237 * 3238 * <p><b>Warning: </b> if the list contains items implementing the {@link Parcelable} interface, 3239 * the class that implements {@link Parcelable} has to be the immediately 3240 * enclosing class of the runtime type of its CREATOR field (that is, 3241 * {@link Class#getEnclosingClass()} has to return the parcelable implementing class), 3242 * otherwise this method might throw an exception. If the Parcelable class does not enclose the 3243 * CREATOR, use the deprecated {@link #readList(List, ClassLoader)} instead. 3244 * 3245 * @throws BadParcelableException Throws BadParcelableException if the item to be deserialized 3246 * is not an instance of that class or any of its children classes or there was an error 3247 * trying to instantiate an element. 3248 */ readList(@onNull List<? super T> outVal, @Nullable ClassLoader loader, @NonNull Class<T> clazz)3249 public <T> void readList(@NonNull List<? super T> outVal, 3250 @Nullable ClassLoader loader, @NonNull Class<T> clazz) { 3251 Objects.requireNonNull(clazz); 3252 int n = readInt(); 3253 readListInternal(outVal, n, loader, clazz); 3254 } 3255 3256 /** 3257 * Please use {@link #readBundle(ClassLoader)} instead (whose data must have 3258 * been written with {@link #writeBundle}. Read and return a new HashMap 3259 * object from the parcel at the current dataPosition(), using the given 3260 * class loader to load any enclosed Parcelables. Returns null if 3261 * the previously written map object was null. 3262 * 3263 * @deprecated Consider using {@link #readBundle(ClassLoader)} as stated above, in case this 3264 * method is still preferred use the type-safer version {@link #readHashMap(ClassLoader, 3265 * Class, Class)} starting from Android {@link Build.VERSION_CODES#TIRAMISU}. 3266 */ 3267 @Deprecated 3268 @Nullable readHashMap(@ullable ClassLoader loader)3269 public HashMap readHashMap(@Nullable ClassLoader loader) { 3270 return readHashMapInternal(loader, /* clazzKey */ null, /* clazzValue */ null); 3271 } 3272 3273 /** 3274 * Same as {@link #readHashMap(ClassLoader)} but accepts {@code clazzKey} and 3275 * {@code clazzValue} parameter as the types required for each key and value pair. 3276 * 3277 * @throws BadParcelableException if the item to be deserialized is not an instance of that 3278 * class or any of its children class 3279 */ 3280 @SuppressLint({"ConcreteCollection", "NullableCollection"}) 3281 @Nullable readHashMap(@ullable ClassLoader loader, @NonNull Class<? extends K> clazzKey, @NonNull Class<? extends V> clazzValue)3282 public <K, V> HashMap<K, V> readHashMap(@Nullable ClassLoader loader, 3283 @NonNull Class<? extends K> clazzKey, @NonNull Class<? extends V> clazzValue) { 3284 Objects.requireNonNull(clazzKey); 3285 Objects.requireNonNull(clazzValue); 3286 return readHashMapInternal(loader, clazzKey, clazzValue); 3287 } 3288 3289 /** 3290 * Read and return a new Bundle object from the parcel at the current 3291 * dataPosition(). Returns null if the previously written Bundle object was 3292 * null. 3293 */ 3294 @Nullable readBundle()3295 public final Bundle readBundle() { 3296 return readBundle(null); 3297 } 3298 3299 /** 3300 * Read and return a new Bundle object from the parcel at the current 3301 * dataPosition(), using the given class loader to initialize the class 3302 * loader of the Bundle for later retrieval of Parcelable objects. 3303 * Returns null if the previously written Bundle object was null. 3304 */ 3305 @Nullable readBundle(@ullable ClassLoader loader)3306 public final Bundle readBundle(@Nullable ClassLoader loader) { 3307 int length = readInt(); 3308 if (length < 0) { 3309 if (Bundle.DEBUG) Log.d(TAG, "null bundle: length=" + length); 3310 return null; 3311 } 3312 3313 final Bundle bundle = new Bundle(this, length); 3314 if (loader != null) { 3315 bundle.setClassLoader(loader); 3316 } 3317 return bundle; 3318 } 3319 3320 /** 3321 * Read and return a new Bundle object from the parcel at the current 3322 * dataPosition(). Returns null if the previously written Bundle object was 3323 * null. 3324 */ 3325 @Nullable readPersistableBundle()3326 public final PersistableBundle readPersistableBundle() { 3327 return readPersistableBundle(null); 3328 } 3329 3330 /** 3331 * Read and return a new Bundle object from the parcel at the current 3332 * dataPosition(), using the given class loader to initialize the class 3333 * loader of the Bundle for later retrieval of Parcelable objects. 3334 * Returns null if the previously written Bundle object was null. 3335 */ 3336 @Nullable readPersistableBundle(@ullable ClassLoader loader)3337 public final PersistableBundle readPersistableBundle(@Nullable ClassLoader loader) { 3338 int length = readInt(); 3339 if (length < 0) { 3340 if (Bundle.DEBUG) Log.d(TAG, "null bundle: length=" + length); 3341 return null; 3342 } 3343 3344 final PersistableBundle bundle = new PersistableBundle(this, length); 3345 if (loader != null) { 3346 bundle.setClassLoader(loader); 3347 } 3348 return bundle; 3349 } 3350 3351 /** 3352 * Read a Size from the parcel at the current dataPosition(). 3353 */ 3354 @NonNull readSize()3355 public final Size readSize() { 3356 final int width = readInt(); 3357 final int height = readInt(); 3358 return new Size(width, height); 3359 } 3360 3361 /** 3362 * Read a SizeF from the parcel at the current dataPosition(). 3363 */ 3364 @NonNull readSizeF()3365 public final SizeF readSizeF() { 3366 final float width = readFloat(); 3367 final float height = readFloat(); 3368 return new SizeF(width, height); 3369 } 3370 3371 /** 3372 * Read and return a byte[] object from the parcel. 3373 */ 3374 @Nullable createByteArray()3375 public final byte[] createByteArray() { 3376 return nativeCreateByteArray(mNativePtr); 3377 } 3378 3379 /** 3380 * Read a byte[] object from the parcel and copy it into the 3381 * given byte array. 3382 */ readByteArray(@onNull byte[] val)3383 public final void readByteArray(@NonNull byte[] val) { 3384 boolean valid = nativeReadByteArray(mNativePtr, val, (val != null) ? val.length : 0); 3385 if (!valid) { 3386 throw new RuntimeException("bad array lengths"); 3387 } 3388 } 3389 3390 /** 3391 * Read a blob of data from the parcel and return it as a byte array. 3392 * @see #writeBlob(byte[], int, int) 3393 */ 3394 @Nullable readBlob()3395 public final byte[] readBlob() { 3396 return nativeReadBlob(mNativePtr); 3397 } 3398 3399 /** 3400 * Read and return a String[] object from the parcel. 3401 * {@hide} 3402 */ 3403 @UnsupportedAppUsage 3404 @Nullable readStringArray()3405 public final String[] readStringArray() { 3406 return createString16Array(); 3407 } 3408 3409 /** 3410 * Read and return a CharSequence[] object from the parcel. 3411 * {@hide} 3412 */ 3413 @Nullable readCharSequenceArray()3414 public final CharSequence[] readCharSequenceArray() { 3415 CharSequence[] array = null; 3416 3417 int length = readInt(); 3418 if (length >= 0) 3419 { 3420 array = new CharSequence[length]; 3421 3422 for (int i = 0 ; i < length ; i++) 3423 { 3424 array[i] = readCharSequence(); 3425 } 3426 } 3427 3428 return array; 3429 } 3430 3431 /** 3432 * Read and return an ArrayList<CharSequence> object from the parcel. 3433 * {@hide} 3434 */ 3435 @Nullable readCharSequenceList()3436 public final ArrayList<CharSequence> readCharSequenceList() { 3437 ArrayList<CharSequence> array = null; 3438 3439 int length = readInt(); 3440 if (length >= 0) { 3441 array = new ArrayList<CharSequence>(length); 3442 3443 for (int i = 0 ; i < length ; i++) { 3444 array.add(readCharSequence()); 3445 } 3446 } 3447 3448 return array; 3449 } 3450 3451 /** 3452 * Read and return a new ArrayList object from the parcel at the current 3453 * dataPosition(). Returns null if the previously written list object was 3454 * null. The given class loader will be used to load any enclosed 3455 * Parcelables. 3456 * 3457 * @deprecated Use the type-safer version {@link #readArrayList(ClassLoader, Class)} starting 3458 * from Android {@link Build.VERSION_CODES#TIRAMISU}. Also consider changing the format to 3459 * use {@link #createTypedArrayList(Parcelable.Creator)} if possible (eg. if the items' 3460 * class is final) since this is also more performant. Note that changing to the latter 3461 * also requires changing the writes. 3462 */ 3463 @Deprecated 3464 @Nullable readArrayList(@ullable ClassLoader loader)3465 public ArrayList readArrayList(@Nullable ClassLoader loader) { 3466 return readArrayListInternal(loader, /* clazz */ null); 3467 } 3468 3469 /** 3470 * Same as {@link #readArrayList(ClassLoader)} but accepts {@code clazz} parameter as 3471 * the type required for each item. 3472 * 3473 * <p><b>Warning: </b> if the list contains items implementing the {@link Parcelable} interface, 3474 * the class that implements {@link Parcelable} has to be the immediately 3475 * enclosing class of the runtime type of its CREATOR field (that is, 3476 * {@link Class#getEnclosingClass()} has to return the parcelable implementing class), 3477 * otherwise this method might throw an exception. If the Parcelable class does not enclose the 3478 * CREATOR, use the deprecated {@link #readArrayList(ClassLoader)} instead. 3479 * 3480 * @throws BadParcelableException Throws BadParcelableException if the item to be deserialized 3481 * is not an instance of that class or any of its children classes or there was an error 3482 * trying to instantiate an element. 3483 */ 3484 @SuppressLint({"ConcreteCollection", "NullableCollection"}) 3485 @Nullable readArrayList(@ullable ClassLoader loader, @NonNull Class<? extends T> clazz)3486 public <T> ArrayList<T> readArrayList(@Nullable ClassLoader loader, 3487 @NonNull Class<? extends T> clazz) { 3488 Objects.requireNonNull(clazz); 3489 return readArrayListInternal(loader, clazz); 3490 } 3491 3492 /** 3493 * Read and return a new Object array from the parcel at the current 3494 * dataPosition(). Returns null if the previously written array was 3495 * null. The given class loader will be used to load any enclosed 3496 * Parcelables. 3497 * 3498 * @deprecated Use the type-safer version {@link #readArray(ClassLoader, Class)} starting from 3499 * Android {@link Build.VERSION_CODES#TIRAMISU}. Also consider changing the format to use 3500 * {@link #createTypedArray(Parcelable.Creator)} if possible (eg. if the items' class is 3501 * final) since this is also more performant. Note that changing to the latter also 3502 * requires changing the writes. 3503 */ 3504 @Deprecated 3505 @Nullable readArray(@ullable ClassLoader loader)3506 public Object[] readArray(@Nullable ClassLoader loader) { 3507 return readArrayInternal(loader, /* clazz */ null); 3508 } 3509 3510 /** 3511 * Same as {@link #readArray(ClassLoader)} but accepts {@code clazz} parameter as 3512 * the type required for each item. 3513 * 3514 * <p><b>Warning: </b> if the list contains items implementing the {@link Parcelable} interface, 3515 * the class that implements {@link Parcelable} has to be the immediately 3516 * enclosing class of the runtime type of its CREATOR field (that is, 3517 * {@link Class#getEnclosingClass()} has to return the parcelable implementing class), 3518 * otherwise this method might throw an exception. If the Parcelable class does not enclose the 3519 * CREATOR, use the deprecated {@link #readArray(ClassLoader)} instead. 3520 * 3521 * @throws BadParcelableException Throws BadParcelableException if the item to be deserialized 3522 * is not an instance of that class or any of its children classes or there was an error 3523 * trying to instantiate an element. 3524 */ 3525 @SuppressLint({"ArrayReturn", "NullableCollection"}) 3526 @Nullable readArray(@ullable ClassLoader loader, @NonNull Class<T> clazz)3527 public <T> T[] readArray(@Nullable ClassLoader loader, @NonNull Class<T> clazz) { 3528 Objects.requireNonNull(clazz); 3529 return readArrayInternal(loader, clazz); 3530 } 3531 3532 /** 3533 * Read and return a new SparseArray object from the parcel at the current 3534 * dataPosition(). Returns null if the previously written list object was 3535 * null. The given class loader will be used to load any enclosed 3536 * Parcelables. 3537 * 3538 * @deprecated Use the type-safer version {@link #readSparseArray(ClassLoader, Class)} starting 3539 * from Android {@link Build.VERSION_CODES#TIRAMISU}. Also consider changing the format to 3540 * use {@link #createTypedSparseArray(Parcelable.Creator)} if possible (eg. if the items' 3541 * class is final) since this is also more performant. Note that changing to the latter 3542 * also requires changing the writes. 3543 */ 3544 @Deprecated 3545 @Nullable readSparseArray(@ullable ClassLoader loader)3546 public <T> SparseArray<T> readSparseArray(@Nullable ClassLoader loader) { 3547 return readSparseArrayInternal(loader, /* clazz */ null); 3548 } 3549 3550 /** 3551 * Same as {@link #readSparseArray(ClassLoader)} but accepts {@code clazz} parameter as 3552 * the type required for each item. 3553 * 3554 * <p><b>Warning: </b> if the list contains items implementing the {@link Parcelable} interface, 3555 * the class that implements {@link Parcelable} has to be the immediately 3556 * enclosing class of the runtime type of its CREATOR field (that is, 3557 * {@link Class#getEnclosingClass()} has to return the parcelable implementing class), 3558 * otherwise this method might throw an exception. If the Parcelable class does not enclose the 3559 * CREATOR, use the deprecated {@link #readSparseArray(ClassLoader)} instead. 3560 * 3561 * @throws BadParcelableException Throws BadParcelableException if the item to be deserialized 3562 * is not an instance of that class or any of its children classes or there was an error 3563 * trying to instantiate an element. 3564 */ 3565 @Nullable readSparseArray(@ullable ClassLoader loader, @NonNull Class<? extends T> clazz)3566 public <T> SparseArray<T> readSparseArray(@Nullable ClassLoader loader, 3567 @NonNull Class<? extends T> clazz) { 3568 Objects.requireNonNull(clazz); 3569 return readSparseArrayInternal(loader, clazz); 3570 } 3571 3572 /** 3573 * Read and return a new SparseBooleanArray object from the parcel at the current 3574 * dataPosition(). Returns null if the previously written list object was 3575 * null. 3576 */ 3577 @Nullable readSparseBooleanArray()3578 public final SparseBooleanArray readSparseBooleanArray() { 3579 int N = readInt(); 3580 if (N < 0) { 3581 return null; 3582 } 3583 SparseBooleanArray sa = new SparseBooleanArray(N); 3584 readSparseBooleanArrayInternal(sa, N); 3585 return sa; 3586 } 3587 3588 /** 3589 * Read and return a new SparseIntArray object from the parcel at the current 3590 * dataPosition(). Returns null if the previously written array object was null. 3591 * @hide 3592 */ 3593 @Nullable readSparseIntArray()3594 public final SparseIntArray readSparseIntArray() { 3595 int N = readInt(); 3596 if (N < 0) { 3597 return null; 3598 } 3599 SparseIntArray sa = new SparseIntArray(N); 3600 readSparseIntArrayInternal(sa, N); 3601 return sa; 3602 } 3603 3604 /** 3605 * Read and return a new ArrayList containing a particular object type from 3606 * the parcel that was written with {@link #writeTypedList} at the 3607 * current dataPosition(). Returns null if the 3608 * previously written list object was null. The list <em>must</em> have 3609 * previously been written via {@link #writeTypedList} with the same object 3610 * type. 3611 * 3612 * @return A newly created ArrayList containing objects with the same data 3613 * as those that were previously written. 3614 * 3615 * @see #writeTypedList 3616 */ 3617 @Nullable createTypedArrayList(@onNull Parcelable.Creator<T> c)3618 public final <T> ArrayList<T> createTypedArrayList(@NonNull Parcelable.Creator<T> c) { 3619 int N = readInt(); 3620 if (N < 0) { 3621 return null; 3622 } 3623 ArrayList<T> l = new ArrayList<T>(N); 3624 while (N > 0) { 3625 l.add(readTypedObject(c)); 3626 N--; 3627 } 3628 return l; 3629 } 3630 3631 /** 3632 * Read into the given List items containing a particular object type 3633 * that were written with {@link #writeTypedList} at the 3634 * current dataPosition(). The list <em>must</em> have 3635 * previously been written via {@link #writeTypedList} with the same object 3636 * type. 3637 * 3638 * @return A newly created ArrayList containing objects with the same data 3639 * as those that were previously written. 3640 * 3641 * @see #writeTypedList 3642 */ readTypedList(@onNull List<T> list, @NonNull Parcelable.Creator<T> c)3643 public final <T> void readTypedList(@NonNull List<T> list, @NonNull Parcelable.Creator<T> c) { 3644 int M = list.size(); 3645 int N = readInt(); 3646 int i = 0; 3647 for (; i < M && i < N; i++) { 3648 list.set(i, readTypedObject(c)); 3649 } 3650 for (; i<N; i++) { 3651 list.add(readTypedObject(c)); 3652 } 3653 for (; i<M; i++) { 3654 list.remove(N); 3655 } 3656 } 3657 3658 /** 3659 * Read into a new {@link SparseArray} items containing a particular object type 3660 * that were written with {@link #writeTypedSparseArray(SparseArray, int)} at the 3661 * current dataPosition(). The list <em>must</em> have previously been written 3662 * via {@link #writeTypedSparseArray(SparseArray, int)} with the same object type. 3663 * 3664 * @param creator The creator to use when for instantiation. 3665 * 3666 * @return A newly created {@link SparseArray} containing objects with the same data 3667 * as those that were previously written. 3668 * 3669 * @see #writeTypedSparseArray(SparseArray, int) 3670 */ createTypedSparseArray( @onNull Parcelable.Creator<T> creator)3671 public final @Nullable <T extends Parcelable> SparseArray<T> createTypedSparseArray( 3672 @NonNull Parcelable.Creator<T> creator) { 3673 final int count = readInt(); 3674 if (count < 0) { 3675 return null; 3676 } 3677 final SparseArray<T> array = new SparseArray<>(count); 3678 for (int i = 0; i < count; i++) { 3679 final int index = readInt(); 3680 final T value = readTypedObject(creator); 3681 array.append(index, value); 3682 } 3683 return array; 3684 } 3685 3686 /** 3687 * Read into a new {@link ArrayMap} with string keys items containing a particular 3688 * object type that were written with {@link #writeTypedArrayMap(ArrayMap, int)} at the 3689 * current dataPosition(). The list <em>must</em> have previously been written 3690 * via {@link #writeTypedArrayMap(ArrayMap, int)} with the same object type. 3691 * 3692 * @param creator The creator to use when for instantiation. 3693 * 3694 * @return A newly created {@link ArrayMap} containing objects with the same data 3695 * as those that were previously written. 3696 * 3697 * @see #writeTypedArrayMap(ArrayMap, int) 3698 */ createTypedArrayMap( @onNull Parcelable.Creator<T> creator)3699 public final @Nullable <T extends Parcelable> ArrayMap<String, T> createTypedArrayMap( 3700 @NonNull Parcelable.Creator<T> creator) { 3701 final int count = readInt(); 3702 if (count < 0) { 3703 return null; 3704 } 3705 final ArrayMap<String, T> map = new ArrayMap<>(count); 3706 for (int i = 0; i < count; i++) { 3707 final String key = readString(); 3708 final T value = readTypedObject(creator); 3709 map.append(key, value); 3710 } 3711 return map; 3712 } 3713 3714 /** 3715 * Read and return a new ArrayList containing String objects from 3716 * the parcel that was written with {@link #writeStringList} at the 3717 * current dataPosition(). Returns null if the 3718 * previously written list object was null. 3719 * 3720 * @return A newly created ArrayList containing strings with the same data 3721 * as those that were previously written. 3722 * 3723 * @see #writeStringList 3724 */ 3725 @Nullable createStringArrayList()3726 public final ArrayList<String> createStringArrayList() { 3727 int N = readInt(); 3728 if (N < 0) { 3729 return null; 3730 } 3731 ArrayList<String> l = new ArrayList<String>(N); 3732 while (N > 0) { 3733 l.add(readString()); 3734 N--; 3735 } 3736 return l; 3737 } 3738 3739 /** 3740 * Read and return a new ArrayList containing IBinder objects from 3741 * the parcel that was written with {@link #writeBinderList} at the 3742 * current dataPosition(). Returns null if the 3743 * previously written list object was null. 3744 * 3745 * @return A newly created ArrayList containing strings with the same data 3746 * as those that were previously written. 3747 * 3748 * @see #writeBinderList 3749 */ 3750 @Nullable createBinderArrayList()3751 public final ArrayList<IBinder> createBinderArrayList() { 3752 int N = readInt(); 3753 if (N < 0) { 3754 return null; 3755 } 3756 ArrayList<IBinder> l = new ArrayList<IBinder>(N); 3757 while (N > 0) { 3758 l.add(readStrongBinder()); 3759 N--; 3760 } 3761 return l; 3762 } 3763 3764 /** 3765 * Read and return a new ArrayList containing T (IInterface) objects from 3766 * the parcel that was written with {@link #writeInterfaceList} at the 3767 * current dataPosition(). Returns null if the 3768 * previously written list object was null. 3769 * 3770 * @return A newly created ArrayList containing T (IInterface) 3771 * 3772 * @see #writeInterfaceList 3773 */ 3774 @SuppressLint({"ConcreteCollection", "NullableCollection"}) 3775 @Nullable createInterfaceArrayList( @onNull Function<IBinder, T> asInterface)3776 public final <T extends IInterface> ArrayList<T> createInterfaceArrayList( 3777 @NonNull Function<IBinder, T> asInterface) { 3778 int N = readInt(); 3779 if (N < 0) { 3780 return null; 3781 } 3782 ArrayList<T> l = new ArrayList<T>(N); 3783 while (N > 0) { 3784 l.add(asInterface.apply(readStrongBinder())); 3785 N--; 3786 } 3787 return l; 3788 } 3789 3790 /** 3791 * Read into the given List items String objects that were written with 3792 * {@link #writeStringList} at the current dataPosition(). 3793 * 3794 * @see #writeStringList 3795 */ readStringList(@onNull List<String> list)3796 public final void readStringList(@NonNull List<String> list) { 3797 int M = list.size(); 3798 int N = readInt(); 3799 int i = 0; 3800 for (; i < M && i < N; i++) { 3801 list.set(i, readString()); 3802 } 3803 for (; i<N; i++) { 3804 list.add(readString()); 3805 } 3806 for (; i<M; i++) { 3807 list.remove(N); 3808 } 3809 } 3810 3811 /** 3812 * Read into the given List items IBinder objects that were written with 3813 * {@link #writeBinderList} at the current dataPosition(). 3814 * 3815 * @see #writeBinderList 3816 */ readBinderList(@onNull List<IBinder> list)3817 public final void readBinderList(@NonNull List<IBinder> list) { 3818 int M = list.size(); 3819 int N = readInt(); 3820 int i = 0; 3821 for (; i < M && i < N; i++) { 3822 list.set(i, readStrongBinder()); 3823 } 3824 for (; i<N; i++) { 3825 list.add(readStrongBinder()); 3826 } 3827 for (; i<M; i++) { 3828 list.remove(N); 3829 } 3830 } 3831 3832 /** 3833 * Read into the given List items IInterface objects that were written with 3834 * {@link #writeInterfaceList} at the current dataPosition(). 3835 * 3836 * @see #writeInterfaceList 3837 */ readInterfaceList(@onNull List<T> list, @NonNull Function<IBinder, T> asInterface)3838 public final <T extends IInterface> void readInterfaceList(@NonNull List<T> list, 3839 @NonNull Function<IBinder, T> asInterface) { 3840 int M = list.size(); 3841 int N = readInt(); 3842 int i = 0; 3843 for (; i < M && i < N; i++) { 3844 list.set(i, asInterface.apply(readStrongBinder())); 3845 } 3846 for (; i<N; i++) { 3847 list.add(asInterface.apply(readStrongBinder())); 3848 } 3849 for (; i<M; i++) { 3850 list.remove(N); 3851 } 3852 } 3853 3854 /** 3855 * Read the list of {@code Parcelable} objects at the current data position into the 3856 * given {@code list}. The contents of the {@code list} are replaced. If the serialized 3857 * list was {@code null}, {@code list} is cleared. 3858 * 3859 * @see #writeParcelableList(List, int) 3860 * 3861 * @deprecated Use the type-safer version {@link #readParcelableList(List, ClassLoader, Class)} 3862 * starting from Android {@link Build.VERSION_CODES#TIRAMISU}. Also consider changing the 3863 * format to use {@link #readTypedList(List, Parcelable.Creator)} if possible (eg. if the 3864 * items' class is final) since this is also more performant. Note that changing to the 3865 * latter also requires changing the writes. 3866 */ 3867 @Deprecated 3868 @NonNull readParcelableList(@onNull List<T> list, @Nullable ClassLoader cl)3869 public final <T extends Parcelable> List<T> readParcelableList(@NonNull List<T> list, 3870 @Nullable ClassLoader cl) { 3871 return readParcelableListInternal(list, cl, /*clazz*/ null); 3872 } 3873 3874 /** 3875 * Same as {@link #readParcelableList(List, ClassLoader)} but accepts {@code clazz} parameter as 3876 * the type required for each item. 3877 * 3878 * <p><b>Warning: </b> if the list contains items implementing the {@link Parcelable} interface, 3879 * the class that implements {@link Parcelable} has to be the immediately 3880 * enclosing class of the runtime type of its CREATOR field (that is, 3881 * {@link Class#getEnclosingClass()} has to return the parcelable implementing class), 3882 * otherwise this method might throw an exception. If the Parcelable class does not enclose the 3883 * CREATOR, use the deprecated {@link #readParcelableList(List, ClassLoader)} instead. 3884 * 3885 * @throws BadParcelableException Throws BadParcelableException if the item to be deserialized 3886 * is not an instance of that class or any of its children classes or there was an error 3887 * trying to instantiate an element. 3888 */ 3889 @NonNull readParcelableList(@onNull List<T> list, @Nullable ClassLoader cl, @NonNull Class<? extends T> clazz)3890 public <T> List<T> readParcelableList(@NonNull List<T> list, 3891 @Nullable ClassLoader cl, @NonNull Class<? extends T> clazz) { 3892 Objects.requireNonNull(list); 3893 Objects.requireNonNull(clazz); 3894 return readParcelableListInternal(list, cl, clazz); 3895 } 3896 3897 /** 3898 * @param clazz The type of the object expected or {@code null} for performing no checks. 3899 */ 3900 @NonNull readParcelableListInternal(@onNull List<T> list, @Nullable ClassLoader cl, @Nullable Class<? extends T> clazz)3901 private <T> List<T> readParcelableListInternal(@NonNull List<T> list, 3902 @Nullable ClassLoader cl, @Nullable Class<? extends T> clazz) { 3903 final int n = readInt(); 3904 if (n == -1) { 3905 list.clear(); 3906 return list; 3907 } 3908 3909 final int m = list.size(); 3910 int i = 0; 3911 for (; i < m && i < n; i++) { 3912 list.set(i, (T) readParcelableInternal(cl, clazz)); 3913 } 3914 for (; i < n; i++) { 3915 list.add((T) readParcelableInternal(cl, clazz)); 3916 } 3917 for (; i < m; i++) { 3918 list.remove(n); 3919 } 3920 return list; 3921 } 3922 3923 /** 3924 * Read and return a new array containing a particular object type from 3925 * the parcel at the current dataPosition(). Returns null if the 3926 * previously written array was null. The array <em>must</em> have 3927 * previously been written via {@link #writeTypedArray} with the same 3928 * object type. 3929 * 3930 * @return A newly created array containing objects with the same data 3931 * as those that were previously written. 3932 * 3933 * @see #writeTypedArray 3934 */ 3935 @Nullable createTypedArray(@onNull Parcelable.Creator<T> c)3936 public final <T> T[] createTypedArray(@NonNull Parcelable.Creator<T> c) { 3937 int N = readInt(); 3938 if (N < 0) { 3939 return null; 3940 } 3941 T[] l = c.newArray(N); 3942 for (int i=0; i<N; i++) { 3943 l[i] = readTypedObject(c); 3944 } 3945 return l; 3946 } 3947 readTypedArray(@onNull T[] val, @NonNull Parcelable.Creator<T> c)3948 public final <T> void readTypedArray(@NonNull T[] val, @NonNull Parcelable.Creator<T> c) { 3949 int N = readInt(); 3950 if (N == val.length) { 3951 for (int i=0; i<N; i++) { 3952 val[i] = readTypedObject(c); 3953 } 3954 } else { 3955 throw new RuntimeException("bad array lengths"); 3956 } 3957 } 3958 3959 /** 3960 * @deprecated 3961 * @hide 3962 */ 3963 @Deprecated readTypedArray(Parcelable.Creator<T> c)3964 public final <T> T[] readTypedArray(Parcelable.Creator<T> c) { 3965 return createTypedArray(c); 3966 } 3967 3968 /** 3969 * Read and return a typed Parcelable object from a parcel. 3970 * Returns null if the previous written object was null. 3971 * The object <em>must</em> have previous been written via 3972 * {@link #writeTypedObject} with the same object type. 3973 * 3974 * @return A newly created object of the type that was previously 3975 * written. 3976 * 3977 * @see #writeTypedObject 3978 */ 3979 @Nullable readTypedObject(@onNull Parcelable.Creator<T> c)3980 public final <T> T readTypedObject(@NonNull Parcelable.Creator<T> c) { 3981 if (readInt() != 0) { 3982 return c.createFromParcel(this); 3983 } else { 3984 return null; 3985 } 3986 } 3987 3988 /** 3989 * Read a new multi-dimensional array from a parcel. If you want to read Parcelable or 3990 * IInterface values, use {@link #readFixedArray(Object, Parcelable.Creator)} or 3991 * {@link #readFixedArray(Object, Function)}. 3992 * @param val the destination array to hold the read values. 3993 * 3994 * @see #writeTypedArray 3995 * @see #readBooleanArray 3996 * @see #readByteArray 3997 * @see #readCharArray 3998 * @see #readIntArray 3999 * @see #readLongArray 4000 * @see #readFloatArray 4001 * @see #readDoubleArray 4002 * @see #readBinderArray 4003 * @see #readInterfaceArray 4004 * @see #readTypedArray 4005 */ readFixedArray(@onNull T val)4006 public <T> void readFixedArray(@NonNull T val) { 4007 Class<?> componentType = val.getClass().getComponentType(); 4008 if (componentType == boolean.class) { 4009 readBooleanArray((boolean[]) val); 4010 } else if (componentType == byte.class) { 4011 readByteArray((byte[]) val); 4012 } else if (componentType == char.class) { 4013 readCharArray((char[]) val); 4014 } else if (componentType == int.class) { 4015 readIntArray((int[]) val); 4016 } else if (componentType == long.class) { 4017 readLongArray((long[]) val); 4018 } else if (componentType == float.class) { 4019 readFloatArray((float[]) val); 4020 } else if (componentType == double.class) { 4021 readDoubleArray((double[]) val); 4022 } else if (componentType == IBinder.class) { 4023 readBinderArray((IBinder[]) val); 4024 } else if (componentType.isArray()) { 4025 int length = readInt(); 4026 if (length != Array.getLength(val)) { 4027 throw new BadParcelableException("Bad length: expected " + Array.getLength(val) 4028 + ", but got " + length); 4029 } 4030 for (int i = 0; i < length; i++) { 4031 readFixedArray(Array.get(val, i)); 4032 } 4033 } else { 4034 throw new BadParcelableException("Unknown type for fixed-size array: " + componentType); 4035 } 4036 } 4037 4038 /** 4039 * Read a new multi-dimensional array of typed interfaces from a parcel. 4040 * If you want to read Parcelable values, use 4041 * {@link #readFixedArray(Object, Parcelable.Creator)}. For values of other types, use 4042 * {@link #readFixedArray(Object)}. 4043 * @param val the destination array to hold the read values. 4044 */ readFixedArray(@onNull T val, @NonNull Function<IBinder, S> asInterface)4045 public <T, S extends IInterface> void readFixedArray(@NonNull T val, 4046 @NonNull Function<IBinder, S> asInterface) { 4047 Class<?> componentType = val.getClass().getComponentType(); 4048 if (IInterface.class.isAssignableFrom(componentType)) { 4049 readInterfaceArray((S[]) val, asInterface); 4050 } else if (componentType.isArray()) { 4051 int length = readInt(); 4052 if (length != Array.getLength(val)) { 4053 throw new BadParcelableException("Bad length: expected " + Array.getLength(val) 4054 + ", but got " + length); 4055 } 4056 for (int i = 0; i < length; i++) { 4057 readFixedArray(Array.get(val, i), asInterface); 4058 } 4059 } else { 4060 throw new BadParcelableException("Unknown type for fixed-size array: " + componentType); 4061 } 4062 } 4063 4064 /** 4065 * Read a new multi-dimensional array of typed parcelables from a parcel. 4066 * If you want to read IInterface values, use 4067 * {@link #readFixedArray(Object, Function)}. For values of other types, use 4068 * {@link #readFixedArray(Object)}. 4069 * @param val the destination array to hold the read values. 4070 */ readFixedArray(@onNull T val, @NonNull Parcelable.Creator<S> c)4071 public <T, S extends Parcelable> void readFixedArray(@NonNull T val, 4072 @NonNull Parcelable.Creator<S> c) { 4073 Class<?> componentType = val.getClass().getComponentType(); 4074 if (Parcelable.class.isAssignableFrom(componentType)) { 4075 readTypedArray((S[]) val, c); 4076 } else if (componentType.isArray()) { 4077 int length = readInt(); 4078 if (length != Array.getLength(val)) { 4079 throw new BadParcelableException("Bad length: expected " + Array.getLength(val) 4080 + ", but got " + length); 4081 } 4082 for (int i = 0; i < length; i++) { 4083 readFixedArray(Array.get(val, i), c); 4084 } 4085 } else { 4086 throw new BadParcelableException("Unknown type for fixed-size array: " + componentType); 4087 } 4088 } 4089 ensureClassHasExpectedDimensions(@onNull Class<?> cls, int numDimension)4090 private void ensureClassHasExpectedDimensions(@NonNull Class<?> cls, int numDimension) { 4091 if (numDimension <= 0) { 4092 throw new BadParcelableException("Fixed-size array should have dimensions."); 4093 } 4094 4095 for (int i = 0; i < numDimension; i++) { 4096 if (!cls.isArray()) { 4097 throw new BadParcelableException("Array has fewer dimensions than expected: " 4098 + numDimension); 4099 } 4100 cls = cls.getComponentType(); 4101 } 4102 if (cls.isArray()) { 4103 throw new BadParcelableException("Array has more dimensions than expected: " 4104 + numDimension); 4105 } 4106 } 4107 4108 /** 4109 * Read and return a new multi-dimensional array from a parcel. Returns null if the 4110 * previously written array object is null. If you want to read Parcelable or 4111 * IInterface values, use {@link #createFixedArray(Class, Parcelable.Creator, int[])} or 4112 * {@link #createFixedArray(Class, Function, int[])}. 4113 * @param cls the Class object for the target array type. (e.g. int[][].class) 4114 * @param dimensions an array of int representing length of each dimension. 4115 * 4116 * @see #writeTypedArray 4117 * @see #createBooleanArray 4118 * @see #createByteArray 4119 * @see #createCharArray 4120 * @see #createIntArray 4121 * @see #createLongArray 4122 * @see #createFloatArray 4123 * @see #createDoubleArray 4124 * @see #createBinderArray 4125 * @see #createInterfaceArray 4126 * @see #createTypedArray 4127 */ 4128 @Nullable createFixedArray(@onNull Class<T> cls, @NonNull int... dimensions)4129 public <T> T createFixedArray(@NonNull Class<T> cls, @NonNull int... dimensions) { 4130 // Check if type matches with dimensions 4131 // If type is one-dimensional array, delegate to other creators 4132 // Otherwise, create an multi-dimensional array at once and then fill it with readFixedArray 4133 4134 ensureClassHasExpectedDimensions(cls, dimensions.length); 4135 4136 T val = null; 4137 final Class<?> componentType = cls.getComponentType(); 4138 if (componentType == boolean.class) { 4139 val = (T) createBooleanArray(); 4140 } else if (componentType == byte.class) { 4141 val = (T) createByteArray(); 4142 } else if (componentType == char.class) { 4143 val = (T) createCharArray(); 4144 } else if (componentType == int.class) { 4145 val = (T) createIntArray(); 4146 } else if (componentType == long.class) { 4147 val = (T) createLongArray(); 4148 } else if (componentType == float.class) { 4149 val = (T) createFloatArray(); 4150 } else if (componentType == double.class) { 4151 val = (T) createDoubleArray(); 4152 } else if (componentType == IBinder.class) { 4153 val = (T) createBinderArray(); 4154 } else if (componentType.isArray()) { 4155 int length = readInt(); 4156 if (length < 0) { 4157 return null; 4158 } 4159 if (length != dimensions[0]) { 4160 throw new BadParcelableException("Bad length: expected " + dimensions[0] 4161 + ", but got " + length); 4162 } 4163 4164 // Create a multi-dimensional array with an innermost component type and dimensions 4165 Class<?> innermost = componentType.getComponentType(); 4166 while (innermost.isArray()) { 4167 innermost = innermost.getComponentType(); 4168 } 4169 val = (T) Array.newInstance(innermost, dimensions); 4170 for (int i = 0; i < length; i++) { 4171 readFixedArray(Array.get(val, i)); 4172 } 4173 return val; 4174 } else { 4175 throw new BadParcelableException("Unknown type for fixed-size array: " + componentType); 4176 } 4177 4178 // Check if val is null (which is OK) or has the expected size. 4179 // This check doesn't have to be multi-dimensional because multi-dimensional arrays 4180 // are created with expected dimensions. 4181 if (val != null && Array.getLength(val) != dimensions[0]) { 4182 throw new BadParcelableException("Bad length: expected " + dimensions[0] + ", but got " 4183 + Array.getLength(val)); 4184 } 4185 return val; 4186 } 4187 4188 /** 4189 * Read and return a new multi-dimensional array of typed interfaces from a parcel. 4190 * Returns null if the previously written array object is null. If you want to read 4191 * Parcelable values, use {@link #createFixedArray(Class, Parcelable.Creator, int[])}. 4192 * For values of other types use {@link #createFixedArray(Class, int[])}. 4193 * @param cls the Class object for the target array type. (e.g. IFoo[][].class) 4194 * @param dimensions an array of int representing length of each dimension. 4195 */ 4196 @Nullable createFixedArray(@onNull Class<T> cls, @NonNull Function<IBinder, S> asInterface, @NonNull int... dimensions)4197 public <T, S extends IInterface> T createFixedArray(@NonNull Class<T> cls, 4198 @NonNull Function<IBinder, S> asInterface, @NonNull int... dimensions) { 4199 // Check if type matches with dimensions 4200 // If type is one-dimensional array, delegate to other creators 4201 // Otherwise, create an multi-dimensional array at once and then fill it with readFixedArray 4202 4203 ensureClassHasExpectedDimensions(cls, dimensions.length); 4204 4205 T val = null; 4206 final Class<?> componentType = cls.getComponentType(); 4207 if (IInterface.class.isAssignableFrom(componentType)) { 4208 val = (T) createInterfaceArray(n -> (S[]) Array.newInstance(componentType, n), 4209 asInterface); 4210 } else if (componentType.isArray()) { 4211 int length = readInt(); 4212 if (length < 0) { 4213 return null; 4214 } 4215 if (length != dimensions[0]) { 4216 throw new BadParcelableException("Bad length: expected " + dimensions[0] 4217 + ", but got " + length); 4218 } 4219 4220 // Create a multi-dimensional array with an innermost component type and dimensions 4221 Class<?> innermost = componentType.getComponentType(); 4222 while (innermost.isArray()) { 4223 innermost = innermost.getComponentType(); 4224 } 4225 val = (T) Array.newInstance(innermost, dimensions); 4226 for (int i = 0; i < length; i++) { 4227 readFixedArray(Array.get(val, i), asInterface); 4228 } 4229 return val; 4230 } else { 4231 throw new BadParcelableException("Unknown type for fixed-size array: " + componentType); 4232 } 4233 4234 // Check if val is null (which is OK) or has the expected size. 4235 // This check doesn't have to be multi-dimensional because multi-dimensional arrays 4236 // are created with expected dimensions. 4237 if (val != null && Array.getLength(val) != dimensions[0]) { 4238 throw new BadParcelableException("Bad length: expected " + dimensions[0] + ", but got " 4239 + Array.getLength(val)); 4240 } 4241 return val; 4242 } 4243 4244 /** 4245 * Read and return a new multi-dimensional array of typed parcelables from a parcel. 4246 * Returns null if the previously written array object is null. If you want to read 4247 * IInterface values, use {@link #createFixedArray(Class, Function, int[])}. 4248 * For values of other types use {@link #createFixedArray(Class, int[])}. 4249 * @param cls the Class object for the target array type. (e.g. Foo[][].class) 4250 * @param dimensions an array of int representing length of each dimension. 4251 */ 4252 @Nullable createFixedArray(@onNull Class<T> cls, @NonNull Parcelable.Creator<S> c, @NonNull int... dimensions)4253 public <T, S extends Parcelable> T createFixedArray(@NonNull Class<T> cls, 4254 @NonNull Parcelable.Creator<S> c, @NonNull int... dimensions) { 4255 // Check if type matches with dimensions 4256 // If type is one-dimensional array, delegate to other creators 4257 // Otherwise, create an multi-dimensional array at once and then fill it with readFixedArray 4258 4259 ensureClassHasExpectedDimensions(cls, dimensions.length); 4260 4261 T val = null; 4262 final Class<?> componentType = cls.getComponentType(); 4263 if (Parcelable.class.isAssignableFrom(componentType)) { 4264 val = (T) createTypedArray(c); 4265 } else if (componentType.isArray()) { 4266 int length = readInt(); 4267 if (length < 0) { 4268 return null; 4269 } 4270 if (length != dimensions[0]) { 4271 throw new BadParcelableException("Bad length: expected " + dimensions[0] 4272 + ", but got " + length); 4273 } 4274 4275 // Create a multi-dimensional array with an innermost component type and dimensions 4276 Class<?> innermost = componentType.getComponentType(); 4277 while (innermost.isArray()) { 4278 innermost = innermost.getComponentType(); 4279 } 4280 val = (T) Array.newInstance(innermost, dimensions); 4281 for (int i = 0; i < length; i++) { 4282 readFixedArray(Array.get(val, i), c); 4283 } 4284 return val; 4285 } else { 4286 throw new BadParcelableException("Unknown type for fixed-size array: " + componentType); 4287 } 4288 4289 // Check if val is null (which is OK) or has the expected size. 4290 // This check doesn't have to be multi-dimensional because multi-dimensional arrays 4291 // are created with expected dimensions. 4292 if (val != null && Array.getLength(val) != dimensions[0]) { 4293 throw new BadParcelableException("Bad length: expected " + dimensions[0] + ", but got " 4294 + Array.getLength(val)); 4295 } 4296 return val; 4297 } 4298 4299 /** 4300 * Write a heterogeneous array of Parcelable objects into the Parcel. 4301 * Each object in the array is written along with its class name, so 4302 * that the correct class can later be instantiated. As a result, this 4303 * has significantly more overhead than {@link #writeTypedArray}, but will 4304 * correctly handle an array containing more than one type of object. 4305 * 4306 * @param value The array of objects to be written. 4307 * @param parcelableFlags Contextual flags as per 4308 * {@link Parcelable#writeToParcel(Parcel, int) Parcelable.writeToParcel()}. 4309 * 4310 * @see #writeTypedArray 4311 */ writeParcelableArray(@ullable T[] value, int parcelableFlags)4312 public final <T extends Parcelable> void writeParcelableArray(@Nullable T[] value, 4313 int parcelableFlags) { 4314 if (value != null) { 4315 int N = value.length; 4316 writeInt(N); 4317 for (int i=0; i<N; i++) { 4318 writeParcelable(value[i], parcelableFlags); 4319 } 4320 } else { 4321 writeInt(-1); 4322 } 4323 } 4324 4325 /** 4326 * Read a typed object from a parcel. The given class loader will be 4327 * used to load any enclosed Parcelables. If it is null, the default class 4328 * loader will be used. 4329 */ 4330 @Nullable readValue(@ullable ClassLoader loader)4331 public final Object readValue(@Nullable ClassLoader loader) { 4332 return readValue(loader, /* clazz */ null); 4333 } 4334 4335 4336 /** 4337 * @see #readValue(int, ClassLoader, Class, Class[]) 4338 */ 4339 @Nullable readValue(@ullable ClassLoader loader, @Nullable Class<T> clazz, @Nullable Class<?>... itemTypes)4340 private <T> T readValue(@Nullable ClassLoader loader, @Nullable Class<T> clazz, 4341 @Nullable Class<?>... itemTypes) { 4342 int type = readInt(); 4343 final T object; 4344 if (isLengthPrefixed(type)) { 4345 int length = readInt(); 4346 int start = dataPosition(); 4347 object = readValue(type, loader, clazz, itemTypes); 4348 int actual = dataPosition() - start; 4349 if (actual != length) { 4350 Slog.wtfStack(TAG, 4351 "Unparcelling of " + object + " of type " + Parcel.valueTypeToString(type) 4352 + " consumed " + actual + " bytes, but " + length + " expected."); 4353 } 4354 } else { 4355 object = readValue(type, loader, clazz, itemTypes); 4356 } 4357 return object; 4358 } 4359 4360 /** 4361 * This will return a {@link BiFunction} for length-prefixed types that deserializes the object 4362 * when {@link BiFunction#apply} is called (the arguments correspond to the ones of {@link 4363 * #readValue(int, ClassLoader, Class, Class[])} after the class loader), for other types it 4364 * will return the object itself. 4365 * 4366 * <p>After calling {@link BiFunction#apply} the parcel cursor will not change. Note that you 4367 * shouldn't recycle the parcel, not at least until all objects have been retrieved. No 4368 * synchronization attempts are made. 4369 * 4370 * </p>The function returned implements {@link #equals(Object)} and {@link #hashCode()}. Two 4371 * function objects are equal if either of the following is true: 4372 * <ul> 4373 * <li>{@link BiFunction#apply} has been called on both and both objects returned are equal. 4374 * <li>{@link BiFunction#apply} hasn't been called on either one and everything below is true: 4375 * <ul> 4376 * <li>The {@code loader} parameters used to retrieve each are equal. 4377 * <li>They both have the same type. 4378 * <li>They have the same payload length. 4379 * <li>Their binary content is the same. 4380 * </ul> 4381 * </ul> 4382 * 4383 * @hide 4384 */ 4385 @Nullable readLazyValue(@ullable ClassLoader loader)4386 public Object readLazyValue(@Nullable ClassLoader loader) { 4387 int start = dataPosition(); 4388 int type = readInt(); 4389 if (isLengthPrefixed(type)) { 4390 int objectLength = readInt(); 4391 if (objectLength < 0) { 4392 return null; 4393 } 4394 int end = MathUtils.addOrThrow(dataPosition(), objectLength); 4395 int valueLength = end - start; 4396 setDataPosition(end); 4397 return new LazyValue(this, start, valueLength, type, loader); 4398 } else { 4399 return readValue(type, loader, /* clazz */ null); 4400 } 4401 } 4402 4403 4404 private static final class LazyValue implements BiFunction<Class<?>, Class<?>[], Object> { 4405 /** 4406 * | 4B | 4B | 4407 * mSource = Parcel{... | type | length | object | ...} 4408 * a b c d 4409 * length = d - c 4410 * mPosition = a 4411 * mLength = d - a 4412 */ 4413 private final int mPosition; 4414 private final int mLength; 4415 private final int mType; 4416 @Nullable private final ClassLoader mLoader; 4417 @Nullable private Object mObject; 4418 4419 /** 4420 * This goes from non-null to null once. Always check the nullability of this object before 4421 * performing any operations, either involving itself or mObject since the happens-before 4422 * established by this volatile will guarantee visibility of either. We can assume this 4423 * parcel won't change anymore. 4424 */ 4425 @Nullable private volatile Parcel mSource; 4426 LazyValue(Parcel source, int position, int length, int type, @Nullable ClassLoader loader)4427 LazyValue(Parcel source, int position, int length, int type, @Nullable ClassLoader loader) { 4428 mSource = requireNonNull(source); 4429 mPosition = position; 4430 mLength = length; 4431 mType = type; 4432 mLoader = loader; 4433 } 4434 4435 @Override apply(@ullable Class<?> clazz, @Nullable Class<?>[] itemTypes)4436 public Object apply(@Nullable Class<?> clazz, @Nullable Class<?>[] itemTypes) { 4437 Parcel source = mSource; 4438 if (source != null) { 4439 synchronized (source) { 4440 // Check mSource != null guarantees callers won't ever see different objects. 4441 if (mSource != null) { 4442 int restore = source.dataPosition(); 4443 try { 4444 source.setDataPosition(mPosition); 4445 mObject = source.readValue(mLoader, clazz, itemTypes); 4446 } finally { 4447 source.setDataPosition(restore); 4448 } 4449 mSource = null; 4450 } 4451 } 4452 } 4453 return mObject; 4454 } 4455 writeToParcel(Parcel out)4456 public void writeToParcel(Parcel out) { 4457 Parcel source = mSource; 4458 if (source != null) { 4459 out.appendFrom(source, mPosition, mLength); 4460 } else { 4461 out.writeValue(mObject); 4462 } 4463 } 4464 hasFileDescriptors()4465 public boolean hasFileDescriptors() { 4466 Parcel source = mSource; 4467 return (source != null) 4468 ? source.hasFileDescriptors(mPosition, mLength) 4469 : Parcel.hasFileDescriptors(mObject); 4470 } 4471 4472 @Override toString()4473 public String toString() { 4474 return (mSource != null) 4475 ? "Supplier{" + valueTypeToString(mType) + "@" + mPosition + "+" + mLength + '}' 4476 : "Supplier{" + mObject + "}"; 4477 } 4478 4479 /** 4480 * We're checking if the *lazy value* is equal to another one, not if the *object* 4481 * represented by the lazy value is equal to the other one. So, if there are two lazy values 4482 * and one of them has been deserialized but the other hasn't this will always return false. 4483 */ 4484 @Override equals(Object other)4485 public boolean equals(Object other) { 4486 if (this == other) { 4487 return true; 4488 } 4489 if (!(other instanceof LazyValue)) { 4490 return false; 4491 } 4492 LazyValue value = (LazyValue) other; 4493 // Check if they are either both serialized or both deserialized. 4494 Parcel source = mSource; 4495 Parcel otherSource = value.mSource; 4496 if ((source == null) != (otherSource == null)) { 4497 return false; 4498 } 4499 // If both are deserialized, compare the live objects. 4500 if (source == null) { 4501 // Note that here it's guaranteed that both mObject references contain valid values 4502 // (possibly null) since mSource will have provided the memory barrier for those and 4503 // once deserialized we never go back to serialized state. 4504 return Objects.equals(mObject, value.mObject); 4505 } 4506 // Better safely fail here since this could mean we get different objects. 4507 if (!Objects.equals(mLoader, value.mLoader)) { 4508 return false; 4509 } 4510 // Otherwise compare metadata prior to comparing payload. 4511 if (mType != value.mType || mLength != value.mLength) { 4512 return false; 4513 } 4514 // Finally we compare the payload. 4515 return Parcel.compareData(source, mPosition, otherSource, value.mPosition, mLength); 4516 } 4517 4518 @Override hashCode()4519 public int hashCode() { 4520 // Accessing mSource first to provide memory barrier for mObject 4521 return Objects.hash(mSource == null, mObject, mLoader, mType, mLength); 4522 } 4523 } 4524 4525 /** Same as {@link #readValue(ClassLoader, Class, Class[])} without any item types. */ readValue(int type, @Nullable ClassLoader loader, @Nullable Class<T> clazz)4526 private <T> T readValue(int type, @Nullable ClassLoader loader, @Nullable Class<T> clazz) { 4527 // Avoids allocating Class[0] array 4528 return readValue(type, loader, clazz, (Class<?>[]) null); 4529 } 4530 4531 /** 4532 * Reads a value from the parcel of type {@code type}. Does NOT read the int representing the 4533 * type first. 4534 * 4535 * @param clazz The type of the object expected or {@code null} for performing no checks. 4536 * @param itemTypes If the value is a container, these represent the item types (eg. for a list 4537 * it's the item type, for a map, it's the key type, followed by the value 4538 * type). 4539 */ 4540 @SuppressWarnings("unchecked") 4541 @Nullable readValue(int type, @Nullable ClassLoader loader, @Nullable Class<T> clazz, @Nullable Class<?>... itemTypes)4542 private <T> T readValue(int type, @Nullable ClassLoader loader, @Nullable Class<T> clazz, 4543 @Nullable Class<?>... itemTypes) { 4544 final Object object; 4545 switch (type) { 4546 case VAL_NULL: 4547 object = null; 4548 break; 4549 4550 case VAL_STRING: 4551 object = readString(); 4552 break; 4553 4554 case VAL_INTEGER: 4555 object = readInt(); 4556 break; 4557 4558 case VAL_MAP: 4559 checkTypeToUnparcel(clazz, HashMap.class); 4560 Class<?> keyType = ArrayUtils.getOrNull(itemTypes, 0); 4561 Class<?> valueType = ArrayUtils.getOrNull(itemTypes, 1); 4562 checkArgument((keyType == null) == (valueType == null)); 4563 object = readHashMapInternal(loader, keyType, valueType); 4564 break; 4565 4566 case VAL_PARCELABLE: 4567 object = readParcelableInternal(loader, clazz); 4568 break; 4569 4570 case VAL_SHORT: 4571 object = (short) readInt(); 4572 break; 4573 4574 case VAL_LONG: 4575 object = readLong(); 4576 break; 4577 4578 case VAL_FLOAT: 4579 object = readFloat(); 4580 break; 4581 4582 case VAL_DOUBLE: 4583 object = readDouble(); 4584 break; 4585 4586 case VAL_BOOLEAN: 4587 object = readInt() == 1; 4588 break; 4589 4590 case VAL_CHARSEQUENCE: 4591 object = readCharSequence(); 4592 break; 4593 4594 case VAL_LIST: { 4595 checkTypeToUnparcel(clazz, ArrayList.class); 4596 Class<?> itemType = ArrayUtils.getOrNull(itemTypes, 0); 4597 object = readArrayListInternal(loader, itemType); 4598 break; 4599 } 4600 case VAL_BOOLEANARRAY: 4601 object = createBooleanArray(); 4602 break; 4603 4604 case VAL_BYTEARRAY: 4605 object = createByteArray(); 4606 break; 4607 4608 case VAL_STRINGARRAY: 4609 object = readStringArray(); 4610 break; 4611 4612 case VAL_CHARSEQUENCEARRAY: 4613 object = readCharSequenceArray(); 4614 break; 4615 4616 case VAL_IBINDER: 4617 object = readStrongBinder(); 4618 break; 4619 4620 case VAL_OBJECTARRAY: { 4621 Class<?> itemType = ArrayUtils.getOrNull(itemTypes, 0); 4622 checkArrayTypeToUnparcel(clazz, (itemType != null) ? itemType : Object.class); 4623 object = readArrayInternal(loader, itemType); 4624 break; 4625 } 4626 case VAL_INTARRAY: 4627 object = createIntArray(); 4628 break; 4629 4630 case VAL_LONGARRAY: 4631 object = createLongArray(); 4632 break; 4633 4634 case VAL_BYTE: 4635 object = readByte(); 4636 break; 4637 4638 case VAL_SERIALIZABLE: 4639 object = readSerializableInternal(loader, clazz); 4640 break; 4641 4642 case VAL_PARCELABLEARRAY: { 4643 Class<?> itemType = ArrayUtils.getOrNull(itemTypes, 0); 4644 checkArrayTypeToUnparcel(clazz, (itemType != null) ? itemType : Parcelable.class); 4645 object = readParcelableArrayInternal(loader, itemType); 4646 break; 4647 } 4648 case VAL_SPARSEARRAY: { 4649 checkTypeToUnparcel(clazz, SparseArray.class); 4650 Class<?> itemType = ArrayUtils.getOrNull(itemTypes, 0); 4651 object = readSparseArrayInternal(loader, itemType); 4652 break; 4653 } 4654 case VAL_SPARSEBOOLEANARRAY: 4655 object = readSparseBooleanArray(); 4656 break; 4657 4658 case VAL_BUNDLE: 4659 object = readBundle(loader); // loading will be deferred 4660 break; 4661 4662 case VAL_PERSISTABLEBUNDLE: 4663 object = readPersistableBundle(loader); 4664 break; 4665 4666 case VAL_SIZE: 4667 object = readSize(); 4668 break; 4669 4670 case VAL_SIZEF: 4671 object = readSizeF(); 4672 break; 4673 4674 case VAL_DOUBLEARRAY: 4675 object = createDoubleArray(); 4676 break; 4677 4678 case VAL_CHAR: 4679 object = (char) readInt(); 4680 break; 4681 4682 case VAL_SHORTARRAY: 4683 object = createShortArray(); 4684 break; 4685 4686 case VAL_CHARARRAY: 4687 object = createCharArray(); 4688 break; 4689 4690 case VAL_FLOATARRAY: 4691 object = createFloatArray(); 4692 break; 4693 4694 default: 4695 int off = dataPosition() - 4; 4696 throw new BadParcelableException( 4697 "Parcel " + this + ": Unmarshalling unknown type code " + type 4698 + " at offset " + off); 4699 } 4700 if (object != null && clazz != null && !clazz.isInstance(object)) { 4701 throw new BadTypeParcelableException("Unparcelled object " + object 4702 + " is not an instance of required class " + clazz.getName() 4703 + " provided in the parameter"); 4704 } 4705 return (T) object; 4706 } 4707 isLengthPrefixed(int type)4708 private boolean isLengthPrefixed(int type) { 4709 // In general, we want custom types and containers of custom types to be length-prefixed, 4710 // this allows clients (eg. Bundle) to skip their content during deserialization. The 4711 // exception to this is Bundle, since Bundle is already length-prefixed and already copies 4712 // the correspondent section of the parcel internally. 4713 switch (type) { 4714 case VAL_MAP: 4715 case VAL_PARCELABLE: 4716 case VAL_LIST: 4717 case VAL_SPARSEARRAY: 4718 case VAL_PARCELABLEARRAY: 4719 case VAL_OBJECTARRAY: 4720 case VAL_SERIALIZABLE: 4721 return true; 4722 default: 4723 return false; 4724 } 4725 } 4726 4727 /** 4728 * Checks that an array of type T[], where T is {@code componentTypeToUnparcel}, is a subtype of 4729 * {@code requiredArrayType}. 4730 */ checkArrayTypeToUnparcel(@ullable Class<?> requiredArrayType, Class<?> componentTypeToUnparcel)4731 private void checkArrayTypeToUnparcel(@Nullable Class<?> requiredArrayType, 4732 Class<?> componentTypeToUnparcel) { 4733 if (requiredArrayType != null) { 4734 // In Java 12, we could use componentTypeToUnparcel.arrayType() for the check 4735 Class<?> requiredComponentType = requiredArrayType.getComponentType(); 4736 if (requiredComponentType == null) { 4737 throw new BadTypeParcelableException( 4738 "About to unparcel an array but type " 4739 + requiredArrayType.getCanonicalName() 4740 + " required by caller is not an array."); 4741 } 4742 checkTypeToUnparcel(requiredComponentType, componentTypeToUnparcel); 4743 } 4744 } 4745 4746 /** 4747 * Checks that {@code typeToUnparcel} is a subtype of {@code requiredType}, if {@code 4748 * requiredType} is not {@code null}. 4749 */ checkTypeToUnparcel(@ullable Class<?> requiredType, Class<?> typeToUnparcel)4750 private void checkTypeToUnparcel(@Nullable Class<?> requiredType, Class<?> typeToUnparcel) { 4751 if (requiredType != null && !requiredType.isAssignableFrom(typeToUnparcel)) { 4752 throw new BadTypeParcelableException( 4753 "About to unparcel a " + typeToUnparcel.getCanonicalName() 4754 + ", which is not a subtype of type " + requiredType.getCanonicalName() 4755 + " required by caller."); 4756 } 4757 } 4758 4759 /** 4760 * Read and return a new Parcelable from the parcel. The given class loader 4761 * will be used to load any enclosed Parcelables. If it is null, the default 4762 * class loader will be used. 4763 * @param loader A ClassLoader from which to instantiate the Parcelable 4764 * object, or null for the default class loader. 4765 * @return Returns the newly created Parcelable, or null if a null 4766 * object has been written. 4767 * @throws BadParcelableException Throws BadParcelableException if there 4768 * was an error trying to instantiate the Parcelable. 4769 * 4770 * @deprecated Use the type-safer version {@link #readParcelable(ClassLoader, Class)} starting 4771 * from Android {@link Build.VERSION_CODES#TIRAMISU}. Also consider changing the format to 4772 * use {@link Parcelable.Creator#createFromParcel(Parcel)} if possible since this is also 4773 * more performant. Note that changing to the latter also requires changing the writes. 4774 */ 4775 @Deprecated 4776 @Nullable readParcelable(@ullable ClassLoader loader)4777 public final <T extends Parcelable> T readParcelable(@Nullable ClassLoader loader) { 4778 return readParcelableInternal(loader, /* clazz */ null); 4779 } 4780 4781 /** 4782 * Same as {@link #readParcelable(ClassLoader)} but accepts {@code clazz} parameter as the type 4783 * required for each item. 4784 * 4785 * <p><b>Warning: </b> the class that implements {@link Parcelable} has to be the immediately 4786 * enclosing class of the runtime type of its CREATOR field (that is, 4787 * {@link Class#getEnclosingClass()} has to return the parcelable implementing class), 4788 * otherwise this method might throw an exception. If the Parcelable class does not enclose the 4789 * CREATOR, use the deprecated {@link #readParcelable(ClassLoader)} instead. 4790 * 4791 * @throws BadParcelableException Throws BadParcelableException if the item to be deserialized 4792 * is not an instance of that class or any of its children classes or there was an error 4793 * trying to instantiate an element. 4794 */ 4795 @Nullable readParcelable(@ullable ClassLoader loader, @NonNull Class<T> clazz)4796 public <T> T readParcelable(@Nullable ClassLoader loader, @NonNull Class<T> clazz) { 4797 Objects.requireNonNull(clazz); 4798 return readParcelableInternal(loader, clazz); 4799 } 4800 4801 /** 4802 * @param clazz The type of the parcelable expected or {@code null} for performing no checks. 4803 */ 4804 @SuppressWarnings("unchecked") 4805 @Nullable readParcelableInternal(@ullable ClassLoader loader, @Nullable Class<T> clazz)4806 private <T> T readParcelableInternal(@Nullable ClassLoader loader, @Nullable Class<T> clazz) { 4807 Parcelable.Creator<?> creator = readParcelableCreatorInternal(loader, clazz); 4808 if (creator == null) { 4809 return null; 4810 } 4811 if (creator instanceof Parcelable.ClassLoaderCreator<?>) { 4812 Parcelable.ClassLoaderCreator<?> classLoaderCreator = 4813 (Parcelable.ClassLoaderCreator<?>) creator; 4814 return (T) classLoaderCreator.createFromParcel(this, loader); 4815 } 4816 return (T) creator.createFromParcel(this); 4817 } 4818 4819 /** @hide */ 4820 @UnsupportedAppUsage 4821 @SuppressWarnings("unchecked") 4822 @Nullable readCreator(@onNull Parcelable.Creator<?> creator, @Nullable ClassLoader loader)4823 public final <T extends Parcelable> T readCreator(@NonNull Parcelable.Creator<?> creator, 4824 @Nullable ClassLoader loader) { 4825 if (creator instanceof Parcelable.ClassLoaderCreator<?>) { 4826 Parcelable.ClassLoaderCreator<?> classLoaderCreator = 4827 (Parcelable.ClassLoaderCreator<?>) creator; 4828 return (T) classLoaderCreator.createFromParcel(this, loader); 4829 } 4830 return (T) creator.createFromParcel(this); 4831 } 4832 4833 /** 4834 * Read and return a Parcelable.Creator from the parcel. The given class loader will be used to 4835 * load the {@link Parcelable.Creator}. If it is null, the default class loader will be used. 4836 * 4837 * @param loader A ClassLoader from which to instantiate the {@link Parcelable.Creator} 4838 * object, or null for the default class loader. 4839 * @return the previously written {@link Parcelable.Creator}, or null if a null Creator was 4840 * written. 4841 * @throws BadParcelableException Throws BadParcelableException if there was an error trying to 4842 * read the {@link Parcelable.Creator}. 4843 * 4844 * @see #writeParcelableCreator 4845 * 4846 * @deprecated Use the type-safer version {@link #readParcelableCreator(ClassLoader, Class)} 4847 * starting from Android {@link Build.VERSION_CODES#TIRAMISU}. 4848 */ 4849 @Deprecated 4850 @Nullable readParcelableCreator(@ullable ClassLoader loader)4851 public final Parcelable.Creator<?> readParcelableCreator(@Nullable ClassLoader loader) { 4852 return readParcelableCreatorInternal(loader, /* clazz */ null); 4853 } 4854 4855 /** 4856 * Same as {@link #readParcelableCreator(ClassLoader)} but accepts {@code clazz} parameter 4857 * as the required type. 4858 * 4859 * <p><b>Warning: </b> the class that implements {@link Parcelable} has to be the immediately 4860 * enclosing class of the runtime type of its CREATOR field (that is, 4861 * {@link Class#getEnclosingClass()} has to return the parcelable implementing class), 4862 * otherwise this method might throw an exception. If the Parcelable class does not enclose the 4863 * CREATOR, use the deprecated {@link #readParcelableCreator(ClassLoader) instead. 4864 * 4865 * @throws BadParcelableException Throws BadParcelableException if the item to be deserialized 4866 * is not an instance of that class or any of its children classes or there there was an error 4867 * trying to read the {@link Parcelable.Creator}. 4868 */ 4869 @Nullable readParcelableCreator( @ullable ClassLoader loader, @NonNull Class<T> clazz)4870 public <T> Parcelable.Creator<T> readParcelableCreator( 4871 @Nullable ClassLoader loader, @NonNull Class<T> clazz) { 4872 Objects.requireNonNull(clazz); 4873 return readParcelableCreatorInternal(loader, clazz); 4874 } 4875 4876 /** 4877 * @param clazz The type of the parcelable expected or {@code null} for performing no checks. 4878 */ 4879 @SuppressWarnings("unchecked") 4880 @Nullable readParcelableCreatorInternal( @ullable ClassLoader loader, @Nullable Class<T> clazz)4881 private <T> Parcelable.Creator<T> readParcelableCreatorInternal( 4882 @Nullable ClassLoader loader, @Nullable Class<T> clazz) { 4883 String name = readString(); 4884 if (name == null) { 4885 return null; 4886 } 4887 Parcelable.Creator<?> creator; 4888 HashMap<String, Parcelable.Creator<?>> map; 4889 synchronized (mCreators) { 4890 map = mCreators.get(loader); 4891 if (map == null) { 4892 map = new HashMap<>(); 4893 mCreators.put(loader, map); 4894 } 4895 creator = map.get(name); 4896 } 4897 if (creator != null) { 4898 if (clazz != null) { 4899 Class<?> parcelableClass = creator.getClass().getEnclosingClass(); 4900 if (!clazz.isAssignableFrom(parcelableClass)) { 4901 throw new BadTypeParcelableException("Parcelable creator " + name + " is not " 4902 + "a subclass of required class " + clazz.getName() 4903 + " provided in the parameter"); 4904 } 4905 } 4906 return (Parcelable.Creator<T>) creator; 4907 } 4908 4909 try { 4910 // If loader == null, explicitly emulate Class.forName(String) "caller 4911 // classloader" behavior. 4912 ClassLoader parcelableClassLoader = 4913 (loader == null ? getClass().getClassLoader() : loader); 4914 // Avoid initializing the Parcelable class until we know it implements 4915 // Parcelable and has the necessary CREATOR field. http://b/1171613. 4916 Class<?> parcelableClass = Class.forName(name, false /* initialize */, 4917 parcelableClassLoader); 4918 if (!Parcelable.class.isAssignableFrom(parcelableClass)) { 4919 throw new BadParcelableException("Parcelable protocol requires subclassing " 4920 + "from Parcelable on class " + name); 4921 } 4922 if (clazz != null) { 4923 if (!clazz.isAssignableFrom(parcelableClass)) { 4924 throw new BadTypeParcelableException("Parcelable creator " + name + " is not " 4925 + "a subclass of required class " + clazz.getName() 4926 + " provided in the parameter"); 4927 } 4928 } 4929 4930 Field f = parcelableClass.getField("CREATOR"); 4931 if ((f.getModifiers() & Modifier.STATIC) == 0) { 4932 throw new BadParcelableException("Parcelable protocol requires " 4933 + "the CREATOR object to be static on class " + name); 4934 } 4935 Class<?> creatorType = f.getType(); 4936 if (!Parcelable.Creator.class.isAssignableFrom(creatorType)) { 4937 // Fail before calling Field.get(), not after, to avoid initializing 4938 // parcelableClass unnecessarily. 4939 throw new BadParcelableException("Parcelable protocol requires a " 4940 + "Parcelable.Creator object called " 4941 + "CREATOR on class " + name); 4942 } 4943 creator = (Parcelable.Creator<?>) f.get(null); 4944 } catch (IllegalAccessException e) { 4945 Log.e(TAG, "Illegal access when unmarshalling: " + name, e); 4946 throw new BadParcelableException( 4947 "IllegalAccessException when unmarshalling: " + name, e); 4948 } catch (ClassNotFoundException e) { 4949 Log.e(TAG, "Class not found when unmarshalling: " + name, e); 4950 throw new BadParcelableException( 4951 "ClassNotFoundException when unmarshalling: " + name, e); 4952 } catch (NoSuchFieldException e) { 4953 throw new BadParcelableException("Parcelable protocol requires a " 4954 + "Parcelable.Creator object called " 4955 + "CREATOR on class " + name, e); 4956 } 4957 if (creator == null) { 4958 throw new BadParcelableException("Parcelable protocol requires a " 4959 + "non-null Parcelable.Creator object called " 4960 + "CREATOR on class " + name); 4961 } 4962 4963 synchronized (mCreators) { 4964 map.put(name, creator); 4965 } 4966 4967 return (Parcelable.Creator<T>) creator; 4968 } 4969 4970 /** 4971 * Read and return a new Parcelable array from the parcel. 4972 * The given class loader will be used to load any enclosed 4973 * Parcelables. 4974 * @return the Parcelable array, or null if the array is null 4975 * 4976 * @deprecated Use the type-safer version {@link #readParcelableArray(ClassLoader, Class)} 4977 * starting from Android {@link Build.VERSION_CODES#TIRAMISU}. Also consider changing the 4978 * format to use {@link #createTypedArray(Parcelable.Creator)} if possible (eg. if the 4979 * items' class is final) since this is also more performant. Note that changing to the 4980 * latter also requires changing the writes. 4981 */ 4982 @Deprecated 4983 @Nullable readParcelableArray(@ullable ClassLoader loader)4984 public Parcelable[] readParcelableArray(@Nullable ClassLoader loader) { 4985 return readParcelableArrayInternal(loader, /* clazz */ null); 4986 } 4987 4988 /** 4989 * Same as {@link #readParcelableArray(ClassLoader)} but accepts {@code clazz} parameter as 4990 * the type required for each item. 4991 * 4992 * <p><b>Warning: </b> the class that implements {@link Parcelable} has to be the immediately 4993 * enclosing class of the runtime type of its CREATOR field (that is, 4994 * {@link Class#getEnclosingClass()} has to return the parcelable implementing class), 4995 * otherwise this method might throw an exception. If the Parcelable class does not enclose the 4996 * CREATOR, use the deprecated {@link #readParcelableArray(ClassLoader)} instead. 4997 * 4998 * @throws BadParcelableException Throws BadParcelableException if the item to be deserialized 4999 * is not an instance of that class or any of its children classes or there was an error 5000 * trying to instantiate an element. 5001 */ 5002 @SuppressLint({"ArrayReturn", "NullableCollection"}) 5003 @Nullable readParcelableArray(@ullable ClassLoader loader, @NonNull Class<T> clazz)5004 public <T> T[] readParcelableArray(@Nullable ClassLoader loader, @NonNull Class<T> clazz) { 5005 return readParcelableArrayInternal(loader, requireNonNull(clazz)); 5006 } 5007 5008 @SuppressWarnings("unchecked") 5009 @Nullable readParcelableArrayInternal(@ullable ClassLoader loader, @Nullable Class<T> clazz)5010 private <T> T[] readParcelableArrayInternal(@Nullable ClassLoader loader, 5011 @Nullable Class<T> clazz) { 5012 int n = readInt(); 5013 if (n < 0) { 5014 return null; 5015 } 5016 T[] p = (T[]) ((clazz == null) ? new Parcelable[n] : Array.newInstance(clazz, n)); 5017 for (int i = 0; i < n; i++) { 5018 p[i] = readParcelableInternal(loader, clazz); 5019 } 5020 return p; 5021 } 5022 5023 /** 5024 * Read and return a new Serializable object from the parcel. 5025 * @return the Serializable object, or null if the Serializable name 5026 * wasn't found in the parcel. 5027 * 5028 * Unlike {@link #readSerializable(ClassLoader, Class)}, it uses the nearest valid class loader 5029 * up the execution stack to instantiate the Serializable object. 5030 * 5031 * @deprecated Use the type-safer version {@link #readSerializable(ClassLoader, Class)} starting 5032 * from Android {@link Build.VERSION_CODES#TIRAMISU}. 5033 */ 5034 @Deprecated 5035 @Nullable readSerializable()5036 public Serializable readSerializable() { 5037 return readSerializableInternal(/* loader */ null, /* clazz */ null); 5038 } 5039 5040 /** 5041 * Same as {@link #readSerializable()} but accepts {@code loader} and {@code clazz} parameters. 5042 * 5043 * @param loader A ClassLoader from which to instantiate the Serializable object, 5044 * or null for the default class loader. 5045 * @param clazz The type of the object expected. 5046 * 5047 * @throws BadParcelableException Throws BadParcelableException if the item to be deserialized 5048 * is not an instance of that class or any of its children class or there there was an error 5049 * deserializing the object. 5050 */ 5051 @Nullable readSerializable(@ullable ClassLoader loader, @NonNull Class<T> clazz)5052 public <T> T readSerializable(@Nullable ClassLoader loader, @NonNull Class<T> clazz) { 5053 Objects.requireNonNull(clazz); 5054 return readSerializableInternal( 5055 loader == null ? getClass().getClassLoader() : loader, clazz); 5056 } 5057 5058 /** 5059 * @param clazz The type of the serializable expected or {@code null} for performing no checks 5060 */ 5061 @Nullable readSerializableInternal(@ullable final ClassLoader loader, @Nullable Class<T> clazz)5062 private <T> T readSerializableInternal(@Nullable final ClassLoader loader, 5063 @Nullable Class<T> clazz) { 5064 String name = readString(); 5065 if (name == null) { 5066 // For some reason we were unable to read the name of the Serializable (either there 5067 // is nothing left in the Parcel to read, or the next value wasn't a String), so 5068 // return null, which indicates that the name wasn't found in the parcel. 5069 return null; 5070 } 5071 5072 try { 5073 if (clazz != null && loader != null) { 5074 // If custom classloader is provided, resolve the type of serializable using the 5075 // name, then check the type before deserialization. As in this case we can resolve 5076 // the class the same way as ObjectInputStream, using the provided classloader. 5077 Class<?> cl = Class.forName(name, false, loader); 5078 if (!clazz.isAssignableFrom(cl)) { 5079 throw new BadTypeParcelableException("Serializable object " 5080 + cl.getName() + " is not a subclass of required class " 5081 + clazz.getName() + " provided in the parameter"); 5082 } 5083 } 5084 byte[] serializedData = createByteArray(); 5085 ByteArrayInputStream bais = new ByteArrayInputStream(serializedData); 5086 ObjectInputStream ois = new ObjectInputStream(bais) { 5087 @Override 5088 protected Class<?> resolveClass(ObjectStreamClass osClass) 5089 throws IOException, ClassNotFoundException { 5090 // try the custom classloader if provided 5091 if (loader != null) { 5092 Class<?> c = Class.forName(osClass.getName(), false, loader); 5093 return Objects.requireNonNull(c); 5094 } 5095 return super.resolveClass(osClass); 5096 } 5097 }; 5098 T object = (T) ois.readObject(); 5099 if (clazz != null && loader == null) { 5100 // If custom classloader is not provided, check the type of the serializable using 5101 // the deserialized object, as we cannot resolve the class the same way as 5102 // ObjectInputStream. 5103 if (!clazz.isAssignableFrom(object.getClass())) { 5104 throw new BadTypeParcelableException("Serializable object " 5105 + object.getClass().getName() + " is not a subclass of required class " 5106 + clazz.getName() + " provided in the parameter"); 5107 } 5108 } 5109 return object; 5110 } catch (IOException ioe) { 5111 throw new BadParcelableException("Parcelable encountered " 5112 + "IOException reading a Serializable object (name = " 5113 + name + ")", ioe); 5114 } catch (ClassNotFoundException cnfe) { 5115 throw new BadParcelableException("Parcelable encountered " 5116 + "ClassNotFoundException reading a Serializable object (name = " 5117 + name + ")", cnfe); 5118 } 5119 } 5120 5121 // Cache of previously looked up CREATOR.createFromParcel() methods for 5122 // particular classes. Keys are the names of the classes, values are 5123 // Method objects. 5124 @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.P) 5125 private static final HashMap<ClassLoader,HashMap<String,Parcelable.Creator<?>>> 5126 mCreators = new HashMap<>(); 5127 5128 /** @hide for internal use only. */ obtain(int obj)5129 static protected final Parcel obtain(int obj) { 5130 throw new UnsupportedOperationException(); 5131 } 5132 5133 /** @hide */ obtain(long obj)5134 static protected final Parcel obtain(long obj) { 5135 Parcel res = null; 5136 synchronized (sPoolSync) { 5137 if (sHolderPool != null) { 5138 res = sHolderPool; 5139 sHolderPool = res.mPoolNext; 5140 res.mPoolNext = null; 5141 sHolderPoolSize--; 5142 } 5143 } 5144 5145 // When no cache found above, create from scratch; otherwise prepare the 5146 // cached object to be used 5147 if (res == null) { 5148 res = new Parcel(obj); 5149 } else { 5150 if (DEBUG_RECYCLE) { 5151 res.mStack = new RuntimeException(); 5152 } 5153 res.init(obj); 5154 } 5155 return res; 5156 } 5157 Parcel(long nativePtr)5158 private Parcel(long nativePtr) { 5159 if (DEBUG_RECYCLE) { 5160 mStack = new RuntimeException(); 5161 } 5162 //Log.i(TAG, "Initializing obj=0x" + Integer.toHexString(obj), mStack); 5163 init(nativePtr); 5164 } 5165 init(long nativePtr)5166 private void init(long nativePtr) { 5167 if (nativePtr != 0) { 5168 mNativePtr = nativePtr; 5169 mOwnsNativeParcelObject = false; 5170 } else { 5171 mNativePtr = nativeCreate(); 5172 mOwnsNativeParcelObject = true; 5173 } 5174 } 5175 freeBuffer()5176 private void freeBuffer() { 5177 mFlags = 0; 5178 resetSqaushingState(); 5179 if (mOwnsNativeParcelObject) { 5180 nativeFreeBuffer(mNativePtr); 5181 } 5182 mReadWriteHelper = ReadWriteHelper.DEFAULT; 5183 } 5184 destroy()5185 private void destroy() { 5186 resetSqaushingState(); 5187 if (mNativePtr != 0) { 5188 if (mOwnsNativeParcelObject) { 5189 nativeDestroy(mNativePtr); 5190 } 5191 mNativePtr = 0; 5192 } 5193 } 5194 5195 @Override finalize()5196 protected void finalize() throws Throwable { 5197 if (DEBUG_RECYCLE) { 5198 if (mStack != null) { 5199 Log.w(TAG, "Client did not call Parcel.recycle()", mStack); 5200 } 5201 } 5202 destroy(); 5203 } 5204 5205 /** 5206 * To be replaced by {@link #readMapInternal(Map, int, ClassLoader, Class, Class)}, but keep 5207 * the old API for compatibility usages. 5208 */ readMapInternal(@onNull Map outVal, int n, @Nullable ClassLoader loader)5209 /* package */ void readMapInternal(@NonNull Map outVal, int n, 5210 @Nullable ClassLoader loader) { 5211 readMapInternal(outVal, n, loader, /* clazzKey */null, /* clazzValue */null); 5212 } 5213 5214 @Nullable readHashMapInternal(@ullable ClassLoader loader, @NonNull Class<? extends K> clazzKey, @NonNull Class<? extends V> clazzValue)5215 private <K, V> HashMap<K, V> readHashMapInternal(@Nullable ClassLoader loader, 5216 @NonNull Class<? extends K> clazzKey, @NonNull Class<? extends V> clazzValue) { 5217 int n = readInt(); 5218 if (n < 0) { 5219 return null; 5220 } 5221 HashMap<K, V> map = new HashMap<>(n); 5222 readMapInternal(map, n, loader, clazzKey, clazzValue); 5223 return map; 5224 } 5225 readMapInternal(@onNull Map<? super K, ? super V> outVal, @Nullable ClassLoader loader, @Nullable Class<K> clazzKey, @Nullable Class<V> clazzValue)5226 private <K, V> void readMapInternal(@NonNull Map<? super K, ? super V> outVal, 5227 @Nullable ClassLoader loader, @Nullable Class<K> clazzKey, 5228 @Nullable Class<V> clazzValue) { 5229 int n = readInt(); 5230 readMapInternal(outVal, n, loader, clazzKey, clazzValue); 5231 } 5232 readMapInternal(@onNull Map<? super K, ? super V> outVal, int n, @Nullable ClassLoader loader, @Nullable Class<K> clazzKey, @Nullable Class<V> clazzValue)5233 private <K, V> void readMapInternal(@NonNull Map<? super K, ? super V> outVal, int n, 5234 @Nullable ClassLoader loader, @Nullable Class<K> clazzKey, 5235 @Nullable Class<V> clazzValue) { 5236 while (n > 0) { 5237 K key = readValue(loader, clazzKey); 5238 V value = readValue(loader, clazzValue); 5239 outVal.put(key, value); 5240 n--; 5241 } 5242 } 5243 readArrayMapInternal(@onNull ArrayMap<? super String, Object> outVal, int size, @Nullable ClassLoader loader)5244 private void readArrayMapInternal(@NonNull ArrayMap<? super String, Object> outVal, 5245 int size, @Nullable ClassLoader loader) { 5246 readArrayMap(outVal, size, /* sorted */ true, /* lazy */ false, loader); 5247 } 5248 5249 /** 5250 * Reads a map into {@code map}. 5251 * 5252 * @param sorted Whether the keys are sorted by their hashes, if so we use an optimized path. 5253 * @param lazy Whether to populate the map with lazy {@link Supplier} objects for 5254 * length-prefixed values. See {@link Parcel#readLazyValue(ClassLoader)} for more 5255 * details. 5256 * @return whether the parcel can be recycled or not. 5257 * @hide 5258 */ readArrayMap(ArrayMap<? super String, Object> map, int size, boolean sorted, boolean lazy, @Nullable ClassLoader loader)5259 boolean readArrayMap(ArrayMap<? super String, Object> map, int size, boolean sorted, 5260 boolean lazy, @Nullable ClassLoader loader) { 5261 boolean recycle = true; 5262 while (size > 0) { 5263 String key = readString(); 5264 Object value = (lazy) ? readLazyValue(loader) : readValue(loader); 5265 if (value instanceof LazyValue) { 5266 recycle = false; 5267 } 5268 if (sorted) { 5269 map.append(key, value); 5270 } else { 5271 map.put(key, value); 5272 } 5273 size--; 5274 } 5275 if (sorted) { 5276 map.validate(); 5277 } 5278 return recycle; 5279 } 5280 5281 /** 5282 * @hide For testing only. 5283 */ 5284 @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.R, trackingBug = 170729553) readArrayMap(@onNull ArrayMap<? super String, Object> outVal, @Nullable ClassLoader loader)5285 public void readArrayMap(@NonNull ArrayMap<? super String, Object> outVal, 5286 @Nullable ClassLoader loader) { 5287 final int N = readInt(); 5288 if (N < 0) { 5289 return; 5290 } 5291 readArrayMapInternal(outVal, N, loader); 5292 } 5293 5294 /** 5295 * Reads an array set. 5296 * 5297 * @param loader The class loader to use. 5298 * 5299 * @hide 5300 */ 5301 @UnsupportedAppUsage readArraySet(@ullable ClassLoader loader)5302 public @Nullable ArraySet<? extends Object> readArraySet(@Nullable ClassLoader loader) { 5303 final int size = readInt(); 5304 if (size < 0) { 5305 return null; 5306 } 5307 ArraySet<Object> result = new ArraySet<>(size); 5308 for (int i = 0; i < size; i++) { 5309 Object value = readValue(loader); 5310 result.append(value); 5311 } 5312 return result; 5313 } 5314 5315 /** 5316 * The method is replaced by {@link #readListInternal(List, int, ClassLoader, Class)}, however 5317 * we are keeping this unused method here to allow unsupported app usages. 5318 */ readListInternal(@onNull List outVal, int n, @Nullable ClassLoader loader)5319 private void readListInternal(@NonNull List outVal, int n, @Nullable ClassLoader loader) { 5320 readListInternal(outVal, n, loader, /* clazz */ null); 5321 } 5322 5323 /** 5324 * @param clazz The type of the object expected or {@code null} for performing no checks. 5325 */ readListInternal(@onNull List<? super T> outVal, int n, @Nullable ClassLoader loader, @Nullable Class<T> clazz)5326 private <T> void readListInternal(@NonNull List<? super T> outVal, int n, 5327 @Nullable ClassLoader loader, @Nullable Class<T> clazz) { 5328 while (n > 0) { 5329 T value = readValue(loader, clazz); 5330 //Log.d(TAG, "Unmarshalling value=" + value); 5331 outVal.add(value); 5332 n--; 5333 } 5334 } 5335 5336 /** 5337 * @param clazz The type of the object expected or {@code null} for performing no checks. 5338 */ 5339 @SuppressLint({"ConcreteCollection", "NullableCollection"}) 5340 @Nullable readArrayListInternal(@ullable ClassLoader loader, @Nullable Class<? extends T> clazz)5341 private <T> ArrayList<T> readArrayListInternal(@Nullable ClassLoader loader, 5342 @Nullable Class<? extends T> clazz) { 5343 int n = readInt(); 5344 if (n < 0) { 5345 return null; 5346 } 5347 ArrayList<T> l = new ArrayList<>(n); 5348 readListInternal(l, n, loader, clazz); 5349 return l; 5350 } 5351 5352 /** 5353 * The method is replaced by {@link #readArrayInternal(ClassLoader, Class)}, however 5354 * we are keeping this unused method here to allow unsupported app usages. 5355 */ readArrayInternal(@onNull Object[] outVal, int N, @Nullable ClassLoader loader)5356 private void readArrayInternal(@NonNull Object[] outVal, int N, 5357 @Nullable ClassLoader loader) { 5358 for (int i = 0; i < N; i++) { 5359 Object value = readValue(loader, /* clazz */ null); 5360 outVal[i] = value; 5361 } 5362 } 5363 5364 /** 5365 * @param clazz The type of the object expected or {@code null} for performing no checks. 5366 */ 5367 @SuppressWarnings("unchecked") 5368 @Nullable readArrayInternal(@ullable ClassLoader loader, @Nullable Class<T> clazz)5369 private <T> T[] readArrayInternal(@Nullable ClassLoader loader, @Nullable Class<T> clazz) { 5370 int n = readInt(); 5371 if (n < 0) { 5372 return null; 5373 } 5374 T[] outVal = (T[]) ((clazz == null) ? new Object[n] : Array.newInstance(clazz, n)); 5375 5376 for (int i = 0; i < n; i++) { 5377 T value = readValue(loader, clazz); 5378 outVal[i] = value; 5379 } 5380 return outVal; 5381 } 5382 5383 /** 5384 * The method is replaced by {@link #readSparseArray(ClassLoader, Class)}, however 5385 * we are keeping this unused method here to allow unsupported app usages. 5386 */ readSparseArrayInternal(@onNull SparseArray outVal, int N, @Nullable ClassLoader loader)5387 private void readSparseArrayInternal(@NonNull SparseArray outVal, int N, 5388 @Nullable ClassLoader loader) { 5389 while (N > 0) { 5390 int key = readInt(); 5391 Object value = readValue(loader); 5392 outVal.append(key, value); 5393 N--; 5394 } 5395 } 5396 5397 /** 5398 * @param clazz The type of the object expected or {@code null} for performing no checks. 5399 */ 5400 @Nullable readSparseArrayInternal(@ullable ClassLoader loader, @Nullable Class<? extends T> clazz)5401 private <T> SparseArray<T> readSparseArrayInternal(@Nullable ClassLoader loader, 5402 @Nullable Class<? extends T> clazz) { 5403 int n = readInt(); 5404 if (n < 0) { 5405 return null; 5406 } 5407 SparseArray<T> outVal = new SparseArray<>(n); 5408 5409 while (n > 0) { 5410 int key = readInt(); 5411 T value = readValue(loader, clazz); 5412 outVal.append(key, value); 5413 n--; 5414 } 5415 return outVal; 5416 } 5417 5418 readSparseBooleanArrayInternal(@onNull SparseBooleanArray outVal, int N)5419 private void readSparseBooleanArrayInternal(@NonNull SparseBooleanArray outVal, int N) { 5420 while (N > 0) { 5421 int key = readInt(); 5422 boolean value = this.readByte() == 1; 5423 //Log.i(TAG, "Unmarshalling key=" + key + " value=" + value); 5424 outVal.append(key, value); 5425 N--; 5426 } 5427 } 5428 readSparseIntArrayInternal(@onNull SparseIntArray outVal, int N)5429 private void readSparseIntArrayInternal(@NonNull SparseIntArray outVal, int N) { 5430 while (N > 0) { 5431 int key = readInt(); 5432 int value = readInt(); 5433 outVal.append(key, value); 5434 N--; 5435 } 5436 } 5437 5438 /** 5439 * @hide For testing 5440 */ getOpenAshmemSize()5441 public long getOpenAshmemSize() { 5442 return nativeGetOpenAshmemSize(mNativePtr); 5443 } 5444 valueTypeToString(int type)5445 private static String valueTypeToString(int type) { 5446 switch (type) { 5447 case VAL_NULL: return "VAL_NULL"; 5448 case VAL_INTEGER: return "VAL_INTEGER"; 5449 case VAL_MAP: return "VAL_MAP"; 5450 case VAL_BUNDLE: return "VAL_BUNDLE"; 5451 case VAL_PERSISTABLEBUNDLE: return "VAL_PERSISTABLEBUNDLE"; 5452 case VAL_PARCELABLE: return "VAL_PARCELABLE"; 5453 case VAL_SHORT: return "VAL_SHORT"; 5454 case VAL_LONG: return "VAL_LONG"; 5455 case VAL_FLOAT: return "VAL_FLOAT"; 5456 case VAL_DOUBLE: return "VAL_DOUBLE"; 5457 case VAL_BOOLEAN: return "VAL_BOOLEAN"; 5458 case VAL_CHARSEQUENCE: return "VAL_CHARSEQUENCE"; 5459 case VAL_LIST: return "VAL_LIST"; 5460 case VAL_SPARSEARRAY: return "VAL_SPARSEARRAY"; 5461 case VAL_BOOLEANARRAY: return "VAL_BOOLEANARRAY"; 5462 case VAL_BYTEARRAY: return "VAL_BYTEARRAY"; 5463 case VAL_STRINGARRAY: return "VAL_STRINGARRAY"; 5464 case VAL_CHARSEQUENCEARRAY: return "VAL_CHARSEQUENCEARRAY"; 5465 case VAL_IBINDER: return "VAL_IBINDER"; 5466 case VAL_PARCELABLEARRAY: return "VAL_PARCELABLEARRAY"; 5467 case VAL_INTARRAY: return "VAL_INTARRAY"; 5468 case VAL_LONGARRAY: return "VAL_LONGARRAY"; 5469 case VAL_BYTE: return "VAL_BYTE"; 5470 case VAL_SIZE: return "VAL_SIZE"; 5471 case VAL_SIZEF: return "VAL_SIZEF"; 5472 case VAL_DOUBLEARRAY: return "VAL_DOUBLEARRAY"; 5473 case VAL_CHAR: return "VAL_CHAR"; 5474 case VAL_SHORTARRAY: return "VAL_SHORTARRAY"; 5475 case VAL_CHARARRAY: return "VAL_CHARARRAY"; 5476 case VAL_FLOATARRAY: return "VAL_FLOATARRAY"; 5477 case VAL_OBJECTARRAY: return "VAL_OBJECTARRAY"; 5478 case VAL_SERIALIZABLE: return "VAL_SERIALIZABLE"; 5479 default: return "UNKNOWN(" + type + ")"; 5480 } 5481 } 5482 } 5483