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