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