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