• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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&lt;T&gt;, Parcelable.Creator&lt;S&gt;, 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&lt;CharSequence&gt; 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