Home | History | Annotate | Download | only in os
      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 android.annotation.Nullable;
     20 import android.text.TextUtils;
     21 import android.util.ArrayMap;
     22 import android.util.ArraySet;
     23 import android.util.Log;
     24 import android.util.Size;
     25 import android.util.SizeF;
     26 import android.util.SparseArray;
     27 import android.util.SparseBooleanArray;
     28 import android.util.SparseIntArray;
     29 
     30 import dalvik.annotation.optimization.CriticalNative;
     31 import dalvik.annotation.optimization.FastNative;
     32 import dalvik.system.VMRuntime;
     33 
     34 import libcore.util.SneakyThrow;
     35 
     36 import java.io.ByteArrayInputStream;
     37 import java.io.ByteArrayOutputStream;
     38 import java.io.FileDescriptor;
     39 import java.io.FileNotFoundException;
     40 import java.io.IOException;
     41 import java.io.ObjectInputStream;
     42 import java.io.ObjectOutputStream;
     43 import java.io.ObjectStreamClass;
     44 import java.io.Serializable;
     45 import java.lang.reflect.Array;
     46 import java.lang.reflect.Field;
     47 import java.lang.reflect.Modifier;
     48 import java.util.ArrayList;
     49 import java.util.Arrays;
     50 import java.util.HashMap;
     51 import java.util.List;
     52 import java.util.Map;
     53 import java.util.Set;
     54 
     55 /**
     56  * Container for a message (data and object references) that can
     57  * be sent through an IBinder.  A Parcel can contain both flattened data
     58  * that will be unflattened on the other side of the IPC (using the various
     59  * methods here for writing specific types, or the general
     60  * {@link Parcelable} interface), and references to live {@link IBinder}
     61  * objects that will result in the other side receiving a proxy IBinder
     62  * connected with the original IBinder in the Parcel.
     63  *
     64  * <p class="note">Parcel is <strong>not</strong> a general-purpose
     65  * serialization mechanism.  This class (and the corresponding
     66  * {@link Parcelable} API for placing arbitrary objects into a Parcel) is
     67  * designed as a high-performance IPC transport.  As such, it is not
     68  * appropriate to place any Parcel data in to persistent storage: changes
     69  * in the underlying implementation of any of the data in the Parcel can
     70  * render older data unreadable.</p>
     71  *
     72  * <p>The bulk of the Parcel API revolves around reading and writing data
     73  * of various types.  There are six major classes of such functions available.</p>
     74  *
     75  * <h3>Primitives</h3>
     76  *
     77  * <p>The most basic data functions are for writing and reading primitive
     78  * data types: {@link #writeByte}, {@link #readByte}, {@link #writeDouble},
     79  * {@link #readDouble}, {@link #writeFloat}, {@link #readFloat}, {@link #writeInt},
     80  * {@link #readInt}, {@link #writeLong}, {@link #readLong},
     81  * {@link #writeString}, {@link #readString}.  Most other
     82  * data operations are built on top of these.  The given data is written and
     83  * read using the endianess of the host CPU.</p>
     84  *
     85  * <h3>Primitive Arrays</h3>
     86  *
     87  * <p>There are a variety of methods for reading and writing raw arrays
     88  * of primitive objects, which generally result in writing a 4-byte length
     89  * followed by the primitive data items.  The methods for reading can either
     90  * read the data into an existing array, or create and return a new array.
     91  * These available types are:</p>
     92  *
     93  * <ul>
     94  * <li> {@link #writeBooleanArray(boolean[])},
     95  * {@link #readBooleanArray(boolean[])}, {@link #createBooleanArray()}
     96  * <li> {@link #writeByteArray(byte[])},
     97  * {@link #writeByteArray(byte[], int, int)}, {@link #readByteArray(byte[])},
     98  * {@link #createByteArray()}
     99  * <li> {@link #writeCharArray(char[])}, {@link #readCharArray(char[])},
    100  * {@link #createCharArray()}
    101  * <li> {@link #writeDoubleArray(double[])}, {@link #readDoubleArray(double[])},
    102  * {@link #createDoubleArray()}
    103  * <li> {@link #writeFloatArray(float[])}, {@link #readFloatArray(float[])},
    104  * {@link #createFloatArray()}
    105  * <li> {@link #writeIntArray(int[])}, {@link #readIntArray(int[])},
    106  * {@link #createIntArray()}
    107  * <li> {@link #writeLongArray(long[])}, {@link #readLongArray(long[])},
    108  * {@link #createLongArray()}
    109  * <li> {@link #writeStringArray(String[])}, {@link #readStringArray(String[])},
    110  * {@link #createStringArray()}.
    111  * <li> {@link #writeSparseBooleanArray(SparseBooleanArray)},
    112  * {@link #readSparseBooleanArray()}.
    113  * </ul>
    114  *
    115  * <h3>Parcelables</h3>
    116  *
    117  * <p>The {@link Parcelable} protocol provides an extremely efficient (but
    118  * low-level) protocol for objects to write and read themselves from Parcels.
    119  * You can use the direct methods {@link #writeParcelable(Parcelable, int)}
    120  * and {@link #readParcelable(ClassLoader)} or
    121  * {@link #writeParcelableArray} and
    122  * {@link #readParcelableArray(ClassLoader)} to write or read.  These
    123  * methods write both the class type and its data to the Parcel, allowing
    124  * that class to be reconstructed from the appropriate class loader when
    125  * later reading.</p>
    126  *
    127  * <p>There are also some methods that provide a more efficient way to work
    128  * with Parcelables: {@link #writeTypedObject}, {@link #writeTypedArray},
    129  * {@link #writeTypedList}, {@link #readTypedObject},
    130  * {@link #createTypedArray} and {@link #createTypedArrayList}.  These methods
    131  * do not write the class information of the original object: instead, the
    132  * caller of the read function must know what type to expect and pass in the
    133  * appropriate {@link Parcelable.Creator Parcelable.Creator} instead to
    134  * properly construct the new object and read its data.  (To more efficient
    135  * write and read a single Parcelable object that is not null, you can directly
    136  * call {@link Parcelable#writeToParcel Parcelable.writeToParcel} and
    137  * {@link Parcelable.Creator#createFromParcel Parcelable.Creator.createFromParcel}
    138  * yourself.)</p>
    139  *
    140  * <h3>Bundles</h3>
    141  *
    142  * <p>A special type-safe container, called {@link Bundle}, is available
    143  * for key/value maps of heterogeneous values.  This has many optimizations
    144  * for improved performance when reading and writing data, and its type-safe
    145  * API avoids difficult to debug type errors when finally marshalling the
    146  * data contents into a Parcel.  The methods to use are
    147  * {@link #writeBundle(Bundle)}, {@link #readBundle()}, and
    148  * {@link #readBundle(ClassLoader)}.
    149  *
    150  * <h3>Active Objects</h3>
    151  *
    152  * <p>An unusual feature of Parcel is the ability to read and write active
    153  * objects.  For these objects the actual contents of the object is not
    154  * written, rather a special token referencing the object is written.  When
    155  * reading the object back from the Parcel, you do not get a new instance of
    156  * the object, but rather a handle that operates on the exact same object that
    157  * was originally written.  There are two forms of active objects available.</p>
    158  *
    159  * <p>{@link Binder} objects are a core facility of Android's general cross-process
    160  * communication system.  The {@link IBinder} interface describes an abstract
    161  * protocol with a Binder object.  Any such interface can be written in to
    162  * a Parcel, and upon reading you will receive either the original object
    163  * implementing that interface or a special proxy implementation
    164  * that communicates calls back to the original object.  The methods to use are
    165  * {@link #writeStrongBinder(IBinder)},
    166  * {@link #writeStrongInterface(IInterface)}, {@link #readStrongBinder()},
    167  * {@link #writeBinderArray(IBinder[])}, {@link #readBinderArray(IBinder[])},
    168  * {@link #createBinderArray()},
    169  * {@link #writeBinderList(List)}, {@link #readBinderList(List)},
    170  * {@link #createBinderArrayList()}.</p>
    171  *
    172  * <p>FileDescriptor objects, representing raw Linux file descriptor identifiers,
    173  * can be written and {@link ParcelFileDescriptor} objects returned to operate
    174  * on the original file descriptor.  The returned file descriptor is a dup
    175  * of the original file descriptor: the object and fd is different, but
    176  * operating on the same underlying file stream, with the same position, etc.
    177  * The methods to use are {@link #writeFileDescriptor(FileDescriptor)},
    178  * {@link #readFileDescriptor()}.
    179  *
    180  * <h3>Untyped Containers</h3>
    181  *
    182  * <p>A final class of methods are for writing and reading standard Java
    183  * containers of arbitrary types.  These all revolve around the
    184  * {@link #writeValue(Object)} and {@link #readValue(ClassLoader)} methods
    185  * which define the types of objects allowed.  The container methods are
    186  * {@link #writeArray(Object[])}, {@link #readArray(ClassLoader)},
    187  * {@link #writeList(List)}, {@link #readList(List, ClassLoader)},
    188  * {@link #readArrayList(ClassLoader)},
    189  * {@link #writeMap(Map)}, {@link #readMap(Map, ClassLoader)},
    190  * {@link #writeSparseArray(SparseArray)},
    191  * {@link #readSparseArray(ClassLoader)}.
    192  */
    193 public final class Parcel {
    194     private static final boolean DEBUG_RECYCLE = false;
    195     private static final boolean DEBUG_ARRAY_MAP = false;
    196     private static final String TAG = "Parcel";
    197 
    198     @SuppressWarnings({"UnusedDeclaration"})
    199     private long mNativePtr; // used by native code
    200 
    201     /**
    202      * Flag indicating if {@link #mNativePtr} was allocated by this object,
    203      * indicating that we're responsible for its lifecycle.
    204      */
    205     private boolean mOwnsNativeParcelObject;
    206     private long mNativeSize;
    207 
    208     private ArrayMap<Class, Object> mClassCookies;
    209 
    210     private RuntimeException mStack;
    211 
    212     private static final int POOL_SIZE = 6;
    213     private static final Parcel[] sOwnedPool = new Parcel[POOL_SIZE];
    214     private static final Parcel[] sHolderPool = new Parcel[POOL_SIZE];
    215 
    216     // Keep in sync with frameworks/native/include/private/binder/ParcelValTypes.h.
    217     private static final int VAL_NULL = -1;
    218     private static final int VAL_STRING = 0;
    219     private static final int VAL_INTEGER = 1;
    220     private static final int VAL_MAP = 2;
    221     private static final int VAL_BUNDLE = 3;
    222     private static final int VAL_PARCELABLE = 4;
    223     private static final int VAL_SHORT = 5;
    224     private static final int VAL_LONG = 6;
    225     private static final int VAL_FLOAT = 7;
    226     private static final int VAL_DOUBLE = 8;
    227     private static final int VAL_BOOLEAN = 9;
    228     private static final int VAL_CHARSEQUENCE = 10;
    229     private static final int VAL_LIST  = 11;
    230     private static final int VAL_SPARSEARRAY = 12;
    231     private static final int VAL_BYTEARRAY = 13;
    232     private static final int VAL_STRINGARRAY = 14;
    233     private static final int VAL_IBINDER = 15;
    234     private static final int VAL_PARCELABLEARRAY = 16;
    235     private static final int VAL_OBJECTARRAY = 17;
    236     private static final int VAL_INTARRAY = 18;
    237     private static final int VAL_LONGARRAY = 19;
    238     private static final int VAL_BYTE = 20;
    239     private static final int VAL_SERIALIZABLE = 21;
    240     private static final int VAL_SPARSEBOOLEANARRAY = 22;
    241     private static final int VAL_BOOLEANARRAY = 23;
    242     private static final int VAL_CHARSEQUENCEARRAY = 24;
    243     private static final int VAL_PERSISTABLEBUNDLE = 25;
    244     private static final int VAL_SIZE = 26;
    245     private static final int VAL_SIZEF = 27;
    246     private static final int VAL_DOUBLEARRAY = 28;
    247 
    248     // The initial int32 in a Binder call's reply Parcel header:
    249     // Keep these in sync with libbinder's binder/Status.h.
    250     private static final int EX_SECURITY = -1;
    251     private static final int EX_BAD_PARCELABLE = -2;
    252     private static final int EX_ILLEGAL_ARGUMENT = -3;
    253     private static final int EX_NULL_POINTER = -4;
    254     private static final int EX_ILLEGAL_STATE = -5;
    255     private static final int EX_NETWORK_MAIN_THREAD = -6;
    256     private static final int EX_UNSUPPORTED_OPERATION = -7;
    257     private static final int EX_SERVICE_SPECIFIC = -8;
    258     private static final int EX_PARCELABLE = -9;
    259     private static final int EX_HAS_REPLY_HEADER = -128;  // special; see below
    260     // EX_TRANSACTION_FAILED is used exclusively in native code.
    261     // see libbinder's binder/Status.h
    262     private static final int EX_TRANSACTION_FAILED = -129;
    263 
    264     @CriticalNative
    265     private static native int nativeDataSize(long nativePtr);
    266     @CriticalNative
    267     private static native int nativeDataAvail(long nativePtr);
    268     @CriticalNative
    269     private static native int nativeDataPosition(long nativePtr);
    270     @CriticalNative
    271     private static native int nativeDataCapacity(long nativePtr);
    272     @FastNative
    273     private static native long nativeSetDataSize(long nativePtr, int size);
    274     @CriticalNative
    275     private static native void nativeSetDataPosition(long nativePtr, int pos);
    276     @FastNative
    277     private static native void nativeSetDataCapacity(long nativePtr, int size);
    278 
    279     @CriticalNative
    280     private static native boolean nativePushAllowFds(long nativePtr, boolean allowFds);
    281     @CriticalNative
    282     private static native void nativeRestoreAllowFds(long nativePtr, boolean lastValue);
    283 
    284     private static native void nativeWriteByteArray(long nativePtr, byte[] b, int offset, int len);
    285     private static native void nativeWriteBlob(long nativePtr, byte[] b, int offset, int len);
    286     @FastNative
    287     private static native void nativeWriteInt(long nativePtr, int val);
    288     @FastNative
    289     private static native void nativeWriteLong(long nativePtr, long val);
    290     @FastNative
    291     private static native void nativeWriteFloat(long nativePtr, float val);
    292     @FastNative
    293     private static native void nativeWriteDouble(long nativePtr, double val);
    294     static native void nativeWriteString(long nativePtr, String val);
    295     private static native void nativeWriteStrongBinder(long nativePtr, IBinder val);
    296     private static native long nativeWriteFileDescriptor(long nativePtr, FileDescriptor val);
    297 
    298     private static native byte[] nativeCreateByteArray(long nativePtr);
    299     private static native boolean nativeReadByteArray(long nativePtr, byte[] dest, int destLen);
    300     private static native byte[] nativeReadBlob(long nativePtr);
    301     @CriticalNative
    302     private static native int nativeReadInt(long nativePtr);
    303     @CriticalNative
    304     private static native long nativeReadLong(long nativePtr);
    305     @CriticalNative
    306     private static native float nativeReadFloat(long nativePtr);
    307     @CriticalNative
    308     private static native double nativeReadDouble(long nativePtr);
    309     static native String nativeReadString(long nativePtr);
    310     private static native IBinder nativeReadStrongBinder(long nativePtr);
    311     private static native FileDescriptor nativeReadFileDescriptor(long nativePtr);
    312 
    313     private static native long nativeCreate();
    314     private static native long nativeFreeBuffer(long nativePtr);
    315     private static native void nativeDestroy(long nativePtr);
    316 
    317     private static native byte[] nativeMarshall(long nativePtr);
    318     private static native long nativeUnmarshall(
    319             long nativePtr, byte[] data, int offset, int length);
    320     private static native int nativeCompareData(long thisNativePtr, long otherNativePtr);
    321     private static native long nativeAppendFrom(
    322             long thisNativePtr, long otherNativePtr, int offset, int length);
    323     @CriticalNative
    324     private static native boolean nativeHasFileDescriptors(long nativePtr);
    325     private static native void nativeWriteInterfaceToken(long nativePtr, String interfaceName);
    326     private static native void nativeEnforceInterface(long nativePtr, String interfaceName);
    327 
    328     @CriticalNative
    329     private static native long nativeGetBlobAshmemSize(long nativePtr);
    330 
    331     public final static Parcelable.Creator<String> STRING_CREATOR
    332              = new Parcelable.Creator<String>() {
    333         public String createFromParcel(Parcel source) {
    334             return source.readString();
    335         }
    336         public String[] newArray(int size) {
    337             return new String[size];
    338         }
    339     };
    340 
    341     /**
    342      * @hide
    343      */
    344     public static class ReadWriteHelper {
    345         public static final ReadWriteHelper DEFAULT = new ReadWriteHelper();
    346 
    347         /**
    348          * Called when writing a string to a parcel. Subclasses wanting to write a string
    349          * must use {@link #writeStringNoHelper(String)} to avoid
    350          * infinity recursive calls.
    351          */
    352         public void writeString(Parcel p, String s) {
    353             nativeWriteString(p.mNativePtr, s);
    354         }
    355 
    356         /**
    357          * Called when reading a string to a parcel. Subclasses wanting to read a string
    358          * must use {@link #readStringNoHelper()} to avoid
    359          * infinity recursive calls.
    360          */
    361         public String readString(Parcel p) {
    362             return nativeReadString(p.mNativePtr);
    363         }
    364     }
    365 
    366     private ReadWriteHelper mReadWriteHelper = ReadWriteHelper.DEFAULT;
    367 
    368     /**
    369      * Retrieve a new Parcel object from the pool.
    370      */
    371     public static Parcel obtain() {
    372         final Parcel[] pool = sOwnedPool;
    373         synchronized (pool) {
    374             Parcel p;
    375             for (int i=0; i<POOL_SIZE; i++) {
    376                 p = pool[i];
    377                 if (p != null) {
    378                     pool[i] = null;
    379                     if (DEBUG_RECYCLE) {
    380                         p.mStack = new RuntimeException();
    381                     }
    382                     p.mReadWriteHelper = ReadWriteHelper.DEFAULT;
    383                     return p;
    384                 }
    385             }
    386         }
    387         return new Parcel(0);
    388     }
    389 
    390     /**
    391      * Put a Parcel object back into the pool.  You must not touch
    392      * the object after this call.
    393      */
    394     public final void recycle() {
    395         if (DEBUG_RECYCLE) mStack = null;
    396         freeBuffer();
    397 
    398         final Parcel[] pool;
    399         if (mOwnsNativeParcelObject) {
    400             pool = sOwnedPool;
    401         } else {
    402             mNativePtr = 0;
    403             pool = sHolderPool;
    404         }
    405 
    406         synchronized (pool) {
    407             for (int i=0; i<POOL_SIZE; i++) {
    408                 if (pool[i] == null) {
    409                     pool[i] = this;
    410                     return;
    411                 }
    412             }
    413         }
    414     }
    415 
    416     /**
    417      * Set a {@link ReadWriteHelper}, which can be used to avoid having duplicate strings, for
    418      * example.
    419      *
    420      * @hide
    421      */
    422     public void setReadWriteHelper(ReadWriteHelper helper) {
    423         mReadWriteHelper = helper != null ? helper : ReadWriteHelper.DEFAULT;
    424     }
    425 
    426     /**
    427      * @return whether this parcel has a {@link ReadWriteHelper}.
    428      *
    429      * @hide
    430      */
    431     public boolean hasReadWriteHelper() {
    432         return (mReadWriteHelper != null) && (mReadWriteHelper != ReadWriteHelper.DEFAULT);
    433     }
    434 
    435     /** @hide */
    436     public static native long getGlobalAllocSize();
    437 
    438     /** @hide */
    439     public static native long getGlobalAllocCount();
    440 
    441     /**
    442      * Returns the total amount of data contained in the parcel.
    443      */
    444     public final int dataSize() {
    445         return nativeDataSize(mNativePtr);
    446     }
    447 
    448     /**
    449      * Returns the amount of data remaining to be read from the
    450      * parcel.  That is, {@link #dataSize}-{@link #dataPosition}.
    451      */
    452     public final int dataAvail() {
    453         return nativeDataAvail(mNativePtr);
    454     }
    455 
    456     /**
    457      * Returns the current position in the parcel data.  Never
    458      * more than {@link #dataSize}.
    459      */
    460     public final int dataPosition() {
    461         return nativeDataPosition(mNativePtr);
    462     }
    463 
    464     /**
    465      * Returns the total amount of space in the parcel.  This is always
    466      * >= {@link #dataSize}.  The difference between it and dataSize() is the
    467      * amount of room left until the parcel needs to re-allocate its
    468      * data buffer.
    469      */
    470     public final int dataCapacity() {
    471         return nativeDataCapacity(mNativePtr);
    472     }
    473 
    474     /**
    475      * Change the amount of data in the parcel.  Can be either smaller or
    476      * larger than the current size.  If larger than the current capacity,
    477      * more memory will be allocated.
    478      *
    479      * @param size The new number of bytes in the Parcel.
    480      */
    481     public final void setDataSize(int size) {
    482         updateNativeSize(nativeSetDataSize(mNativePtr, size));
    483     }
    484 
    485     /**
    486      * Move the current read/write position in the parcel.
    487      * @param pos New offset in the parcel; must be between 0 and
    488      * {@link #dataSize}.
    489      */
    490     public final void setDataPosition(int pos) {
    491         nativeSetDataPosition(mNativePtr, pos);
    492     }
    493 
    494     /**
    495      * Change the capacity (current available space) of the parcel.
    496      *
    497      * @param size The new capacity of the parcel, in bytes.  Can not be
    498      * less than {@link #dataSize} -- that is, you can not drop existing data
    499      * with this method.
    500      */
    501     public final void setDataCapacity(int size) {
    502         nativeSetDataCapacity(mNativePtr, size);
    503     }
    504 
    505     /** @hide */
    506     public final boolean pushAllowFds(boolean allowFds) {
    507         return nativePushAllowFds(mNativePtr, allowFds);
    508     }
    509 
    510     /** @hide */
    511     public final void restoreAllowFds(boolean lastValue) {
    512         nativeRestoreAllowFds(mNativePtr, lastValue);
    513     }
    514 
    515     /**
    516      * Returns the raw bytes of the parcel.
    517      *
    518      * <p class="note">The data you retrieve here <strong>must not</strong>
    519      * be placed in any kind of persistent storage (on local disk, across
    520      * a network, etc).  For that, you should use standard serialization
    521      * or another kind of general serialization mechanism.  The Parcel
    522      * marshalled representation is highly optimized for local IPC, and as
    523      * such does not attempt to maintain compatibility with data created
    524      * in different versions of the platform.
    525      */
    526     public final byte[] marshall() {
    527         return nativeMarshall(mNativePtr);
    528     }
    529 
    530     /**
    531      * Set the bytes in data to be the raw bytes of this Parcel.
    532      */
    533     public final void unmarshall(byte[] data, int offset, int length) {
    534         updateNativeSize(nativeUnmarshall(mNativePtr, data, offset, length));
    535     }
    536 
    537     public final void appendFrom(Parcel parcel, int offset, int length) {
    538         updateNativeSize(nativeAppendFrom(mNativePtr, parcel.mNativePtr, offset, length));
    539     }
    540 
    541     /** @hide */
    542     public final int compareData(Parcel other) {
    543         return nativeCompareData(mNativePtr, other.mNativePtr);
    544     }
    545 
    546     /** @hide */
    547     public final void setClassCookie(Class clz, Object cookie) {
    548         if (mClassCookies == null) {
    549             mClassCookies = new ArrayMap<>();
    550         }
    551         mClassCookies.put(clz, cookie);
    552     }
    553 
    554     /** @hide */
    555     public final Object getClassCookie(Class clz) {
    556         return mClassCookies != null ? mClassCookies.get(clz) : null;
    557     }
    558 
    559     /** @hide */
    560     public final void adoptClassCookies(Parcel from) {
    561         mClassCookies = from.mClassCookies;
    562     }
    563 
    564     /**
    565      * Report whether the parcel contains any marshalled file descriptors.
    566      */
    567     public final boolean hasFileDescriptors() {
    568         return nativeHasFileDescriptors(mNativePtr);
    569     }
    570 
    571     /**
    572      * Store or read an IBinder interface token in the parcel at the current
    573      * {@link #dataPosition}.  This is used to validate that the marshalled
    574      * transaction is intended for the target interface.
    575      */
    576     public final void writeInterfaceToken(String interfaceName) {
    577         nativeWriteInterfaceToken(mNativePtr, interfaceName);
    578     }
    579 
    580     public final void enforceInterface(String interfaceName) {
    581         nativeEnforceInterface(mNativePtr, interfaceName);
    582     }
    583 
    584     /**
    585      * Write a byte array into the parcel at the current {@link #dataPosition},
    586      * growing {@link #dataCapacity} if needed.
    587      * @param b Bytes to place into the parcel.
    588      */
    589     public final void writeByteArray(byte[] b) {
    590         writeByteArray(b, 0, (b != null) ? b.length : 0);
    591     }
    592 
    593     /**
    594      * Write a byte array into the parcel at the current {@link #dataPosition},
    595      * growing {@link #dataCapacity} if needed.
    596      * @param b Bytes to place into the parcel.
    597      * @param offset Index of first byte to be written.
    598      * @param len Number of bytes to write.
    599      */
    600     public final void writeByteArray(byte[] b, int offset, int len) {
    601         if (b == null) {
    602             writeInt(-1);
    603             return;
    604         }
    605         Arrays.checkOffsetAndCount(b.length, offset, len);
    606         nativeWriteByteArray(mNativePtr, b, offset, len);
    607     }
    608 
    609     /**
    610      * Write a blob of data into the parcel at the current {@link #dataPosition},
    611      * growing {@link #dataCapacity} if needed.
    612      * @param b Bytes to place into the parcel.
    613      * {@hide}
    614      * {@SystemApi}
    615      */
    616     public final void writeBlob(byte[] b) {
    617         writeBlob(b, 0, (b != null) ? b.length : 0);
    618     }
    619 
    620     /**
    621      * Write a blob of data into the parcel at the current {@link #dataPosition},
    622      * growing {@link #dataCapacity} if needed.
    623      * @param b Bytes to place into the parcel.
    624      * @param offset Index of first byte to be written.
    625      * @param len Number of bytes to write.
    626      * {@hide}
    627      * {@SystemApi}
    628      */
    629     public final void writeBlob(byte[] b, int offset, int len) {
    630         if (b == null) {
    631             writeInt(-1);
    632             return;
    633         }
    634         Arrays.checkOffsetAndCount(b.length, offset, len);
    635         nativeWriteBlob(mNativePtr, b, offset, len);
    636     }
    637 
    638     /**
    639      * Write an integer value into the parcel at the current dataPosition(),
    640      * growing dataCapacity() if needed.
    641      */
    642     public final void writeInt(int val) {
    643         nativeWriteInt(mNativePtr, val);
    644     }
    645 
    646     /**
    647      * Write a long integer value into the parcel at the current dataPosition(),
    648      * growing dataCapacity() if needed.
    649      */
    650     public final void writeLong(long val) {
    651         nativeWriteLong(mNativePtr, val);
    652     }
    653 
    654     /**
    655      * Write a floating point value into the parcel at the current
    656      * dataPosition(), growing dataCapacity() if needed.
    657      */
    658     public final void writeFloat(float val) {
    659         nativeWriteFloat(mNativePtr, val);
    660     }
    661 
    662     /**
    663      * Write a double precision floating point value into the parcel at the
    664      * current dataPosition(), growing dataCapacity() if needed.
    665      */
    666     public final void writeDouble(double val) {
    667         nativeWriteDouble(mNativePtr, val);
    668     }
    669 
    670     /**
    671      * Write a string value into the parcel at the current dataPosition(),
    672      * growing dataCapacity() if needed.
    673      */
    674     public final void writeString(String val) {
    675         mReadWriteHelper.writeString(this, val);
    676     }
    677 
    678     /**
    679      * Write a string without going though a {@link ReadWriteHelper}.  Subclasses of
    680      * {@link ReadWriteHelper} must use this method instead of {@link #writeString} to avoid
    681      * infinity recursive calls.
    682      *
    683      * @hide
    684      */
    685     public void writeStringNoHelper(String val) {
    686         nativeWriteString(mNativePtr, val);
    687     }
    688 
    689     /** @hide */
    690     public final void writeBoolean(boolean val) {
    691         writeInt(val ? 1 : 0);
    692     }
    693 
    694     /**
    695      * Write a CharSequence value into the parcel at the current dataPosition(),
    696      * growing dataCapacity() if needed.
    697      * @hide
    698      */
    699     public final void writeCharSequence(CharSequence val) {
    700         TextUtils.writeToParcel(val, this, 0);
    701     }
    702 
    703     /**
    704      * Write an object into the parcel at the current dataPosition(),
    705      * growing dataCapacity() if needed.
    706      */
    707     public final void writeStrongBinder(IBinder val) {
    708         nativeWriteStrongBinder(mNativePtr, val);
    709     }
    710 
    711     /**
    712      * Write an object into the parcel at the current dataPosition(),
    713      * growing dataCapacity() if needed.
    714      */
    715     public final void writeStrongInterface(IInterface val) {
    716         writeStrongBinder(val == null ? null : val.asBinder());
    717     }
    718 
    719     /**
    720      * Write a FileDescriptor into the parcel at the current dataPosition(),
    721      * growing dataCapacity() if needed.
    722      *
    723      * <p class="caution">The file descriptor will not be closed, which may
    724      * result in file descriptor leaks when objects are returned from Binder
    725      * calls.  Use {@link ParcelFileDescriptor#writeToParcel} instead, which
    726      * accepts contextual flags and will close the original file descriptor
    727      * if {@link Parcelable#PARCELABLE_WRITE_RETURN_VALUE} is set.</p>
    728      */
    729     public final void writeFileDescriptor(FileDescriptor val) {
    730         updateNativeSize(nativeWriteFileDescriptor(mNativePtr, val));
    731     }
    732 
    733     private void updateNativeSize(long newNativeSize) {
    734         if (mOwnsNativeParcelObject) {
    735             if (newNativeSize > Integer.MAX_VALUE) {
    736                 newNativeSize = Integer.MAX_VALUE;
    737             }
    738             if (newNativeSize != mNativeSize) {
    739                 int delta = (int) (newNativeSize - mNativeSize);
    740                 if (delta > 0) {
    741                     VMRuntime.getRuntime().registerNativeAllocation(delta);
    742                 } else {
    743                     VMRuntime.getRuntime().registerNativeFree(-delta);
    744                 }
    745                 mNativeSize = newNativeSize;
    746             }
    747         }
    748     }
    749 
    750     /**
    751      * {@hide}
    752      * This will be the new name for writeFileDescriptor, for consistency.
    753      **/
    754     public final void writeRawFileDescriptor(FileDescriptor val) {
    755         nativeWriteFileDescriptor(mNativePtr, val);
    756     }
    757 
    758     /**
    759      * {@hide}
    760      * Write an array of FileDescriptor objects into the Parcel.
    761      *
    762      * @param value The array of objects to be written.
    763      */
    764     public final void writeRawFileDescriptorArray(FileDescriptor[] value) {
    765         if (value != null) {
    766             int N = value.length;
    767             writeInt(N);
    768             for (int i=0; i<N; i++) {
    769                 writeRawFileDescriptor(value[i]);
    770             }
    771         } else {
    772             writeInt(-1);
    773         }
    774     }
    775 
    776     /**
    777      * Write a byte value into the parcel at the current dataPosition(),
    778      * growing dataCapacity() if needed.
    779      */
    780     public final void writeByte(byte val) {
    781         writeInt(val);
    782     }
    783 
    784     /**
    785      * Please use {@link #writeBundle} instead.  Flattens a Map into the parcel
    786      * at the current dataPosition(),
    787      * growing dataCapacity() if needed.  The Map keys must be String objects.
    788      * The Map values are written using {@link #writeValue} and must follow
    789      * the specification there.
    790      *
    791      * <p>It is strongly recommended to use {@link #writeBundle} instead of
    792      * this method, since the Bundle class provides a type-safe API that
    793      * allows you to avoid mysterious type errors at the point of marshalling.
    794      */
    795     public final void writeMap(Map val) {
    796         writeMapInternal((Map<String, Object>) val);
    797     }
    798 
    799     /**
    800      * Flatten a Map into the parcel at the current dataPosition(),
    801      * growing dataCapacity() if needed.  The Map keys must be String objects.
    802      */
    803     /* package */ void writeMapInternal(Map<String,Object> val) {
    804         if (val == null) {
    805             writeInt(-1);
    806             return;
    807         }
    808         Set<Map.Entry<String,Object>> entries = val.entrySet();
    809         writeInt(entries.size());
    810         for (Map.Entry<String,Object> e : entries) {
    811             writeValue(e.getKey());
    812             writeValue(e.getValue());
    813         }
    814     }
    815 
    816     /**
    817      * Flatten an ArrayMap into the parcel at the current dataPosition(),
    818      * growing dataCapacity() if needed.  The Map keys must be String objects.
    819      */
    820     /* package */ void writeArrayMapInternal(ArrayMap<String, Object> val) {
    821         if (val == null) {
    822             writeInt(-1);
    823             return;
    824         }
    825         // Keep the format of this Parcel in sync with writeToParcelInner() in
    826         // frameworks/native/libs/binder/PersistableBundle.cpp.
    827         final int N = val.size();
    828         writeInt(N);
    829         if (DEBUG_ARRAY_MAP) {
    830             RuntimeException here =  new RuntimeException("here");
    831             here.fillInStackTrace();
    832             Log.d(TAG, "Writing " + N + " ArrayMap entries", here);
    833         }
    834         int startPos;
    835         for (int i=0; i<N; i++) {
    836             if (DEBUG_ARRAY_MAP) startPos = dataPosition();
    837             writeString(val.keyAt(i));
    838             writeValue(val.valueAt(i));
    839             if (DEBUG_ARRAY_MAP) Log.d(TAG, "  Write #" + i + " "
    840                     + (dataPosition()-startPos) + " bytes: key=0x"
    841                     + Integer.toHexString(val.keyAt(i) != null ? val.keyAt(i).hashCode() : 0)
    842                     + " " + val.keyAt(i));
    843         }
    844     }
    845 
    846     /**
    847      * @hide For testing only.
    848      */
    849     public void writeArrayMap(ArrayMap<String, Object> val) {
    850         writeArrayMapInternal(val);
    851     }
    852 
    853     /**
    854      * Write an array set to the parcel.
    855      *
    856      * @param val The array set to write.
    857      *
    858      * @hide
    859      */
    860     public void writeArraySet(@Nullable ArraySet<? extends Object> val) {
    861         final int size = (val != null) ? val.size() : -1;
    862         writeInt(size);
    863         for (int i = 0; i < size; i++) {
    864             writeValue(val.valueAt(i));
    865         }
    866     }
    867 
    868     /**
    869      * Flatten a Bundle into the parcel at the current dataPosition(),
    870      * growing dataCapacity() if needed.
    871      */
    872     public final void writeBundle(Bundle val) {
    873         if (val == null) {
    874             writeInt(-1);
    875             return;
    876         }
    877 
    878         val.writeToParcel(this, 0);
    879     }
    880 
    881     /**
    882      * Flatten a PersistableBundle into the parcel at the current dataPosition(),
    883      * growing dataCapacity() if needed.
    884      */
    885     public final void writePersistableBundle(PersistableBundle val) {
    886         if (val == null) {
    887             writeInt(-1);
    888             return;
    889         }
    890 
    891         val.writeToParcel(this, 0);
    892     }
    893 
    894     /**
    895      * Flatten a Size into the parcel at the current dataPosition(),
    896      * growing dataCapacity() if needed.
    897      */
    898     public final void writeSize(Size val) {
    899         writeInt(val.getWidth());
    900         writeInt(val.getHeight());
    901     }
    902 
    903     /**
    904      * Flatten a SizeF into the parcel at the current dataPosition(),
    905      * growing dataCapacity() if needed.
    906      */
    907     public final void writeSizeF(SizeF val) {
    908         writeFloat(val.getWidth());
    909         writeFloat(val.getHeight());
    910     }
    911 
    912     /**
    913      * Flatten a List into the parcel at the current dataPosition(), growing
    914      * dataCapacity() if needed.  The List values are written using
    915      * {@link #writeValue} and must follow the specification there.
    916      */
    917     public final void writeList(List val) {
    918         if (val == null) {
    919             writeInt(-1);
    920             return;
    921         }
    922         int N = val.size();
    923         int i=0;
    924         writeInt(N);
    925         while (i < N) {
    926             writeValue(val.get(i));
    927             i++;
    928         }
    929     }
    930 
    931     /**
    932      * Flatten an Object array into the parcel at the current dataPosition(),
    933      * growing dataCapacity() if needed.  The array values are written using
    934      * {@link #writeValue} and must follow the specification there.
    935      */
    936     public final void writeArray(Object[] val) {
    937         if (val == null) {
    938             writeInt(-1);
    939             return;
    940         }
    941         int N = val.length;
    942         int i=0;
    943         writeInt(N);
    944         while (i < N) {
    945             writeValue(val[i]);
    946             i++;
    947         }
    948     }
    949 
    950     /**
    951      * Flatten a generic SparseArray into the parcel at the current
    952      * dataPosition(), growing dataCapacity() if needed.  The SparseArray
    953      * values are written using {@link #writeValue} and must follow the
    954      * specification there.
    955      */
    956     public final void writeSparseArray(SparseArray<Object> val) {
    957         if (val == null) {
    958             writeInt(-1);
    959             return;
    960         }
    961         int N = val.size();
    962         writeInt(N);
    963         int i=0;
    964         while (i < N) {
    965             writeInt(val.keyAt(i));
    966             writeValue(val.valueAt(i));
    967             i++;
    968         }
    969     }
    970 
    971     public final void writeSparseBooleanArray(SparseBooleanArray val) {
    972         if (val == null) {
    973             writeInt(-1);
    974             return;
    975         }
    976         int N = val.size();
    977         writeInt(N);
    978         int i=0;
    979         while (i < N) {
    980             writeInt(val.keyAt(i));
    981             writeByte((byte)(val.valueAt(i) ? 1 : 0));
    982             i++;
    983         }
    984     }
    985 
    986     /**
    987      * @hide
    988      */
    989     public final void writeSparseIntArray(SparseIntArray val) {
    990         if (val == null) {
    991             writeInt(-1);
    992             return;
    993         }
    994         int N = val.size();
    995         writeInt(N);
    996         int i=0;
    997         while (i < N) {
    998             writeInt(val.keyAt(i));
    999             writeInt(val.valueAt(i));
   1000             i++;
   1001         }
   1002     }
   1003 
   1004     public final void writeBooleanArray(boolean[] val) {
   1005         if (val != null) {
   1006             int N = val.length;
   1007             writeInt(N);
   1008             for (int i=0; i<N; i++) {
   1009                 writeInt(val[i] ? 1 : 0);
   1010             }
   1011         } else {
   1012             writeInt(-1);
   1013         }
   1014     }
   1015 
   1016     public final boolean[] createBooleanArray() {
   1017         int N = readInt();
   1018         // >>2 as a fast divide-by-4 works in the create*Array() functions
   1019         // because dataAvail() will never return a negative number.  4 is
   1020         // the size of a stored boolean in the stream.
   1021         if (N >= 0 && N <= (dataAvail() >> 2)) {
   1022             boolean[] val = new boolean[N];
   1023             for (int i=0; i<N; i++) {
   1024                 val[i] = readInt() != 0;
   1025             }
   1026             return val;
   1027         } else {
   1028             return null;
   1029         }
   1030     }
   1031 
   1032     public final void readBooleanArray(boolean[] val) {
   1033         int N = readInt();
   1034         if (N == val.length) {
   1035             for (int i=0; i<N; i++) {
   1036                 val[i] = readInt() != 0;
   1037             }
   1038         } else {
   1039             throw new RuntimeException("bad array lengths");
   1040         }
   1041     }
   1042 
   1043     public final void writeCharArray(char[] val) {
   1044         if (val != null) {
   1045             int N = val.length;
   1046             writeInt(N);
   1047             for (int i=0; i<N; i++) {
   1048                 writeInt((int)val[i]);
   1049             }
   1050         } else {
   1051             writeInt(-1);
   1052         }
   1053     }
   1054 
   1055     public final char[] createCharArray() {
   1056         int N = readInt();
   1057         if (N >= 0 && N <= (dataAvail() >> 2)) {
   1058             char[] val = new char[N];
   1059             for (int i=0; i<N; i++) {
   1060                 val[i] = (char)readInt();
   1061             }
   1062             return val;
   1063         } else {
   1064             return null;
   1065         }
   1066     }
   1067 
   1068     public final void readCharArray(char[] val) {
   1069         int N = readInt();
   1070         if (N == val.length) {
   1071             for (int i=0; i<N; i++) {
   1072                 val[i] = (char)readInt();
   1073             }
   1074         } else {
   1075             throw new RuntimeException("bad array lengths");
   1076         }
   1077     }
   1078 
   1079     public final void writeIntArray(int[] val) {
   1080         if (val != null) {
   1081             int N = val.length;
   1082             writeInt(N);
   1083             for (int i=0; i<N; i++) {
   1084                 writeInt(val[i]);
   1085             }
   1086         } else {
   1087             writeInt(-1);
   1088         }
   1089     }
   1090 
   1091     public final int[] createIntArray() {
   1092         int N = readInt();
   1093         if (N >= 0 && N <= (dataAvail() >> 2)) {
   1094             int[] val = new int[N];
   1095             for (int i=0; i<N; i++) {
   1096                 val[i] = readInt();
   1097             }
   1098             return val;
   1099         } else {
   1100             return null;
   1101         }
   1102     }
   1103 
   1104     public final void readIntArray(int[] val) {
   1105         int N = readInt();
   1106         if (N == val.length) {
   1107             for (int i=0; i<N; i++) {
   1108                 val[i] = readInt();
   1109             }
   1110         } else {
   1111             throw new RuntimeException("bad array lengths");
   1112         }
   1113     }
   1114 
   1115     public final void writeLongArray(long[] val) {
   1116         if (val != null) {
   1117             int N = val.length;
   1118             writeInt(N);
   1119             for (int i=0; i<N; i++) {
   1120                 writeLong(val[i]);
   1121             }
   1122         } else {
   1123             writeInt(-1);
   1124         }
   1125     }
   1126 
   1127     public final long[] createLongArray() {
   1128         int N = readInt();
   1129         // >>3 because stored longs are 64 bits
   1130         if (N >= 0 && N <= (dataAvail() >> 3)) {
   1131             long[] val = new long[N];
   1132             for (int i=0; i<N; i++) {
   1133                 val[i] = readLong();
   1134             }
   1135             return val;
   1136         } else {
   1137             return null;
   1138         }
   1139     }
   1140 
   1141     public final void readLongArray(long[] val) {
   1142         int N = readInt();
   1143         if (N == val.length) {
   1144             for (int i=0; i<N; i++) {
   1145                 val[i] = readLong();
   1146             }
   1147         } else {
   1148             throw new RuntimeException("bad array lengths");
   1149         }
   1150     }
   1151 
   1152     public final void writeFloatArray(float[] val) {
   1153         if (val != null) {
   1154             int N = val.length;
   1155             writeInt(N);
   1156             for (int i=0; i<N; i++) {
   1157                 writeFloat(val[i]);
   1158             }
   1159         } else {
   1160             writeInt(-1);
   1161         }
   1162     }
   1163 
   1164     public final float[] createFloatArray() {
   1165         int N = readInt();
   1166         // >>2 because stored floats are 4 bytes
   1167         if (N >= 0 && N <= (dataAvail() >> 2)) {
   1168             float[] val = new float[N];
   1169             for (int i=0; i<N; i++) {
   1170                 val[i] = readFloat();
   1171             }
   1172             return val;
   1173         } else {
   1174             return null;
   1175         }
   1176     }
   1177 
   1178     public final void readFloatArray(float[] val) {
   1179         int N = readInt();
   1180         if (N == val.length) {
   1181             for (int i=0; i<N; i++) {
   1182                 val[i] = readFloat();
   1183             }
   1184         } else {
   1185             throw new RuntimeException("bad array lengths");
   1186         }
   1187     }
   1188 
   1189     public final void writeDoubleArray(double[] val) {
   1190         if (val != null) {
   1191             int N = val.length;
   1192             writeInt(N);
   1193             for (int i=0; i<N; i++) {
   1194                 writeDouble(val[i]);
   1195             }
   1196         } else {
   1197             writeInt(-1);
   1198         }
   1199     }
   1200 
   1201     public final double[] createDoubleArray() {
   1202         int N = readInt();
   1203         // >>3 because stored doubles are 8 bytes
   1204         if (N >= 0 && N <= (dataAvail() >> 3)) {
   1205             double[] val = new double[N];
   1206             for (int i=0; i<N; i++) {
   1207                 val[i] = readDouble();
   1208             }
   1209             return val;
   1210         } else {
   1211             return null;
   1212         }
   1213     }
   1214 
   1215     public final void readDoubleArray(double[] val) {
   1216         int N = readInt();
   1217         if (N == val.length) {
   1218             for (int i=0; i<N; i++) {
   1219                 val[i] = readDouble();
   1220             }
   1221         } else {
   1222             throw new RuntimeException("bad array lengths");
   1223         }
   1224     }
   1225 
   1226     public final void writeStringArray(String[] val) {
   1227         if (val != null) {
   1228             int N = val.length;
   1229             writeInt(N);
   1230             for (int i=0; i<N; i++) {
   1231                 writeString(val[i]);
   1232             }
   1233         } else {
   1234             writeInt(-1);
   1235         }
   1236     }
   1237 
   1238     public final String[] createStringArray() {
   1239         int N = readInt();
   1240         if (N >= 0) {
   1241             String[] val = new String[N];
   1242             for (int i=0; i<N; i++) {
   1243                 val[i] = readString();
   1244             }
   1245             return val;
   1246         } else {
   1247             return null;
   1248         }
   1249     }
   1250 
   1251     public final void readStringArray(String[] val) {
   1252         int N = readInt();
   1253         if (N == val.length) {
   1254             for (int i=0; i<N; i++) {
   1255                 val[i] = readString();
   1256             }
   1257         } else {
   1258             throw new RuntimeException("bad array lengths");
   1259         }
   1260     }
   1261 
   1262     public final void writeBinderArray(IBinder[] val) {
   1263         if (val != null) {
   1264             int N = val.length;
   1265             writeInt(N);
   1266             for (int i=0; i<N; i++) {
   1267                 writeStrongBinder(val[i]);
   1268             }
   1269         } else {
   1270             writeInt(-1);
   1271         }
   1272     }
   1273 
   1274     /**
   1275      * @hide
   1276      */
   1277     public final void writeCharSequenceArray(CharSequence[] val) {
   1278         if (val != null) {
   1279             int N = val.length;
   1280             writeInt(N);
   1281             for (int i=0; i<N; i++) {
   1282                 writeCharSequence(val[i]);
   1283             }
   1284         } else {
   1285             writeInt(-1);
   1286         }
   1287     }
   1288 
   1289     /**
   1290      * @hide
   1291      */
   1292     public final void writeCharSequenceList(ArrayList<CharSequence> val) {
   1293         if (val != null) {
   1294             int N = val.size();
   1295             writeInt(N);
   1296             for (int i=0; i<N; i++) {
   1297                 writeCharSequence(val.get(i));
   1298             }
   1299         } else {
   1300             writeInt(-1);
   1301         }
   1302     }
   1303 
   1304     public final IBinder[] createBinderArray() {
   1305         int N = readInt();
   1306         if (N >= 0) {
   1307             IBinder[] val = new IBinder[N];
   1308             for (int i=0; i<N; i++) {
   1309                 val[i] = readStrongBinder();
   1310             }
   1311             return val;
   1312         } else {
   1313             return null;
   1314         }
   1315     }
   1316 
   1317     public final void readBinderArray(IBinder[] val) {
   1318         int N = readInt();
   1319         if (N == val.length) {
   1320             for (int i=0; i<N; i++) {
   1321                 val[i] = readStrongBinder();
   1322             }
   1323         } else {
   1324             throw new RuntimeException("bad array lengths");
   1325         }
   1326     }
   1327 
   1328     /**
   1329      * Flatten a List containing a particular object type into the parcel, at
   1330      * the current dataPosition() and growing dataCapacity() if needed.  The
   1331      * type of the objects in the list must be one that implements Parcelable.
   1332      * Unlike the generic writeList() method, however, only the raw data of the
   1333      * objects is written and not their type, so you must use the corresponding
   1334      * readTypedList() to unmarshall them.
   1335      *
   1336      * @param val The list of objects to be written.
   1337      *
   1338      * @see #createTypedArrayList
   1339      * @see #readTypedList
   1340      * @see Parcelable
   1341      */
   1342     public final <T extends Parcelable> void writeTypedList(List<T> val) {
   1343         if (val == null) {
   1344             writeInt(-1);
   1345             return;
   1346         }
   1347         int N = val.size();
   1348         int i=0;
   1349         writeInt(N);
   1350         while (i < N) {
   1351             T item = val.get(i);
   1352             if (item != null) {
   1353                 writeInt(1);
   1354                 item.writeToParcel(this, 0);
   1355             } else {
   1356                 writeInt(0);
   1357             }
   1358             i++;
   1359         }
   1360     }
   1361 
   1362     /**
   1363      * Flatten a List containing String objects into the parcel, at
   1364      * the current dataPosition() and growing dataCapacity() if needed.  They
   1365      * can later be retrieved with {@link #createStringArrayList} or
   1366      * {@link #readStringList}.
   1367      *
   1368      * @param val The list of strings to be written.
   1369      *
   1370      * @see #createStringArrayList
   1371      * @see #readStringList
   1372      */
   1373     public final void writeStringList(List<String> 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             writeString(val.get(i));
   1383             i++;
   1384         }
   1385     }
   1386 
   1387     /**
   1388      * Flatten a List containing IBinder objects into the parcel, at
   1389      * the current dataPosition() and growing dataCapacity() if needed.  They
   1390      * can later be retrieved with {@link #createBinderArrayList} or
   1391      * {@link #readBinderList}.
   1392      *
   1393      * @param val The list of strings to be written.
   1394      *
   1395      * @see #createBinderArrayList
   1396      * @see #readBinderList
   1397      */
   1398     public final void writeBinderList(List<IBinder> val) {
   1399         if (val == null) {
   1400             writeInt(-1);
   1401             return;
   1402         }
   1403         int N = val.size();
   1404         int i=0;
   1405         writeInt(N);
   1406         while (i < N) {
   1407             writeStrongBinder(val.get(i));
   1408             i++;
   1409         }
   1410     }
   1411 
   1412     /**
   1413      * Flatten a {@code List} containing arbitrary {@code Parcelable} objects into this parcel
   1414      * at the current position. They can later be retrieved using
   1415      * {@link #readParcelableList(List, ClassLoader)} if required.
   1416      *
   1417      * @see #readParcelableList(List, ClassLoader)
   1418      * @hide
   1419      */
   1420     public final <T extends Parcelable> void writeParcelableList(List<T> val, int flags) {
   1421         if (val == null) {
   1422             writeInt(-1);
   1423             return;
   1424         }
   1425 
   1426         int N = val.size();
   1427         int i=0;
   1428         writeInt(N);
   1429         while (i < N) {
   1430             writeParcelable(val.get(i), flags);
   1431             i++;
   1432         }
   1433     }
   1434 
   1435     /**
   1436      * Flatten a homogeneous array containing a particular object type into
   1437      * the parcel, at
   1438      * the current dataPosition() and growing dataCapacity() if needed.  The
   1439      * type of the objects in the array must be one that implements Parcelable.
   1440      * Unlike the {@link #writeParcelableArray} method, however, only the
   1441      * raw data of the objects is written and not their type, so you must use
   1442      * {@link #readTypedArray} with the correct corresponding
   1443      * {@link Parcelable.Creator} implementation to unmarshall them.
   1444      *
   1445      * @param val The array of objects to be written.
   1446      * @param parcelableFlags Contextual flags as per
   1447      * {@link Parcelable#writeToParcel(Parcel, int) Parcelable.writeToParcel()}.
   1448      *
   1449      * @see #readTypedArray
   1450      * @see #writeParcelableArray
   1451      * @see Parcelable.Creator
   1452      */
   1453     public final <T extends Parcelable> void writeTypedArray(T[] val,
   1454             int parcelableFlags) {
   1455         if (val != null) {
   1456             int N = val.length;
   1457             writeInt(N);
   1458             for (int i = 0; i < N; i++) {
   1459                 T item = val[i];
   1460                 if (item != null) {
   1461                     writeInt(1);
   1462                     item.writeToParcel(this, parcelableFlags);
   1463                 } else {
   1464                     writeInt(0);
   1465                 }
   1466             }
   1467         } else {
   1468             writeInt(-1);
   1469         }
   1470     }
   1471 
   1472     /**
   1473      * Write a uniform (all items are null or the same class) array list of
   1474      * parcelables.
   1475      *
   1476      * @param list The list to write.
   1477      *
   1478      * @hide
   1479      */
   1480     public final <T extends Parcelable> void writeTypedArrayList(@Nullable ArrayList<T> list,
   1481             int parcelableFlags) {
   1482         if (list != null) {
   1483             int N = list.size();
   1484             writeInt(N);
   1485             boolean wroteCreator = false;
   1486             for (int i = 0; i < N; i++) {
   1487                 T item = list.get(i);
   1488                 if (item != null) {
   1489                     writeInt(1);
   1490                     if (!wroteCreator) {
   1491                         writeParcelableCreator(item);
   1492                         wroteCreator = true;
   1493                     }
   1494                     item.writeToParcel(this, parcelableFlags);
   1495                 } else {
   1496                     writeInt(0);
   1497                 }
   1498             }
   1499         } else {
   1500             writeInt(-1);
   1501         }
   1502     }
   1503 
   1504     /**
   1505      * Reads a uniform (all items are null or the same class) array list of
   1506      * parcelables.
   1507      *
   1508      * @return The list or null.
   1509      *
   1510      * @hide
   1511      */
   1512     public final @Nullable <T> ArrayList<T> readTypedArrayList(@Nullable ClassLoader loader) {
   1513         int N = readInt();
   1514         if (N <= 0) {
   1515             return null;
   1516         }
   1517         Parcelable.Creator<?> creator = null;
   1518         ArrayList<T> result = new ArrayList<T>(N);
   1519         for (int i = 0; i < N; i++) {
   1520             if (readInt() != 0) {
   1521                 if (creator == null) {
   1522                     creator = readParcelableCreator(loader);
   1523                     if (creator == null) {
   1524                         return null;
   1525                     }
   1526                 }
   1527                 final T parcelable;
   1528                 if (creator instanceof Parcelable.ClassLoaderCreator<?>) {
   1529                     Parcelable.ClassLoaderCreator<?> classLoaderCreator =
   1530                             (Parcelable.ClassLoaderCreator<?>) creator;
   1531                     parcelable = (T) classLoaderCreator.createFromParcel(this, loader);
   1532                 } else {
   1533                     parcelable = (T) creator.createFromParcel(this);
   1534                 }
   1535                 result.add(parcelable);
   1536             } else {
   1537                 result.add(null);
   1538             }
   1539         }
   1540         return result;
   1541     }
   1542 
   1543     /**
   1544      * Write a uniform (all items are null or the same class) array set of
   1545      * parcelables.
   1546      *
   1547      * @param set The set to write.
   1548      *
   1549      * @hide
   1550      */
   1551     public final <T extends Parcelable> void writeTypedArraySet(@Nullable ArraySet<T> set,
   1552             int parcelableFlags) {
   1553         if (set != null) {
   1554             int N = set.size();
   1555             writeInt(N);
   1556             boolean wroteCreator = false;
   1557             for (int i = 0; i < N; i++) {
   1558                 T item = set.valueAt(i);
   1559                 if (item != null) {
   1560                     writeInt(1);
   1561                     if (!wroteCreator) {
   1562                         writeParcelableCreator(item);
   1563                         wroteCreator = true;
   1564                     }
   1565                     item.writeToParcel(this, parcelableFlags);
   1566                 } else {
   1567                     writeInt(0);
   1568                 }
   1569             }
   1570         } else {
   1571             writeInt(-1);
   1572         }
   1573     }
   1574 
   1575     /**
   1576      * Reads a uniform (all items are null or the same class) array set of
   1577      * parcelables.
   1578      *
   1579      * @return The set or null.
   1580      *
   1581      * @hide
   1582      */
   1583     public final @Nullable <T> ArraySet<T> readTypedArraySet(@Nullable ClassLoader loader) {
   1584         int N = readInt();
   1585         if (N <= 0) {
   1586             return null;
   1587         }
   1588         Parcelable.Creator<?> creator = null;
   1589         ArraySet<T> result = new ArraySet<T>(N);
   1590         for (int i = 0; i < N; i++) {
   1591             T parcelable = null;
   1592             if (readInt() != 0) {
   1593                 if (creator == null) {
   1594                     creator = readParcelableCreator(loader);
   1595                     if (creator == null) {
   1596                         return null;
   1597                     }
   1598                 }
   1599                 if (creator instanceof Parcelable.ClassLoaderCreator<?>) {
   1600                     Parcelable.ClassLoaderCreator<?> classLoaderCreator =
   1601                             (Parcelable.ClassLoaderCreator<?>) creator;
   1602                     parcelable = (T) classLoaderCreator.createFromParcel(this, loader);
   1603                 } else {
   1604                     parcelable = (T) creator.createFromParcel(this);
   1605                 }
   1606             }
   1607             result.append(parcelable);
   1608         }
   1609         return result;
   1610     }
   1611 
   1612     /**
   1613      * Flatten the Parcelable object into the parcel.
   1614      *
   1615      * @param val The Parcelable object to be written.
   1616      * @param parcelableFlags Contextual flags as per
   1617      * {@link Parcelable#writeToParcel(Parcel, int) Parcelable.writeToParcel()}.
   1618      *
   1619      * @see #readTypedObject
   1620      */
   1621     public final <T extends Parcelable> void writeTypedObject(T val, int parcelableFlags) {
   1622         if (val != null) {
   1623             writeInt(1);
   1624             val.writeToParcel(this, parcelableFlags);
   1625         } else {
   1626             writeInt(0);
   1627         }
   1628     }
   1629 
   1630     /**
   1631      * Flatten a generic object in to a parcel.  The given Object value may
   1632      * currently be one of the following types:
   1633      *
   1634      * <ul>
   1635      * <li> null
   1636      * <li> String
   1637      * <li> Byte
   1638      * <li> Short
   1639      * <li> Integer
   1640      * <li> Long
   1641      * <li> Float
   1642      * <li> Double
   1643      * <li> Boolean
   1644      * <li> String[]
   1645      * <li> boolean[]
   1646      * <li> byte[]
   1647      * <li> int[]
   1648      * <li> long[]
   1649      * <li> Object[] (supporting objects of the same type defined here).
   1650      * <li> {@link Bundle}
   1651      * <li> Map (as supported by {@link #writeMap}).
   1652      * <li> Any object that implements the {@link Parcelable} protocol.
   1653      * <li> Parcelable[]
   1654      * <li> CharSequence (as supported by {@link TextUtils#writeToParcel}).
   1655      * <li> List (as supported by {@link #writeList}).
   1656      * <li> {@link SparseArray} (as supported by {@link #writeSparseArray(SparseArray)}).
   1657      * <li> {@link IBinder}
   1658      * <li> Any object that implements Serializable (but see
   1659      *      {@link #writeSerializable} for caveats).  Note that all of the
   1660      *      previous types have relatively efficient implementations for
   1661      *      writing to a Parcel; having to rely on the generic serialization
   1662      *      approach is much less efficient and should be avoided whenever
   1663      *      possible.
   1664      * </ul>
   1665      *
   1666      * <p class="caution">{@link Parcelable} objects are written with
   1667      * {@link Parcelable#writeToParcel} using contextual flags of 0.  When
   1668      * serializing objects containing {@link ParcelFileDescriptor}s,
   1669      * this may result in file descriptor leaks when they are returned from
   1670      * Binder calls (where {@link Parcelable#PARCELABLE_WRITE_RETURN_VALUE}
   1671      * should be used).</p>
   1672      */
   1673     public final void writeValue(Object v) {
   1674         if (v == null) {
   1675             writeInt(VAL_NULL);
   1676         } else if (v instanceof String) {
   1677             writeInt(VAL_STRING);
   1678             writeString((String) v);
   1679         } else if (v instanceof Integer) {
   1680             writeInt(VAL_INTEGER);
   1681             writeInt((Integer) v);
   1682         } else if (v instanceof Map) {
   1683             writeInt(VAL_MAP);
   1684             writeMap((Map) v);
   1685         } else if (v instanceof Bundle) {
   1686             // Must be before Parcelable
   1687             writeInt(VAL_BUNDLE);
   1688             writeBundle((Bundle) v);
   1689         } else if (v instanceof PersistableBundle) {
   1690             writeInt(VAL_PERSISTABLEBUNDLE);
   1691             writePersistableBundle((PersistableBundle) v);
   1692         } else if (v instanceof Parcelable) {
   1693             // IMPOTANT: cases for classes that implement Parcelable must
   1694             // come before the Parcelable case, so that their specific VAL_*
   1695             // types will be written.
   1696             writeInt(VAL_PARCELABLE);
   1697             writeParcelable((Parcelable) v, 0);
   1698         } else if (v instanceof Short) {
   1699             writeInt(VAL_SHORT);
   1700             writeInt(((Short) v).intValue());
   1701         } else if (v instanceof Long) {
   1702             writeInt(VAL_LONG);
   1703             writeLong((Long) v);
   1704         } else if (v instanceof Float) {
   1705             writeInt(VAL_FLOAT);
   1706             writeFloat((Float) v);
   1707         } else if (v instanceof Double) {
   1708             writeInt(VAL_DOUBLE);
   1709             writeDouble((Double) v);
   1710         } else if (v instanceof Boolean) {
   1711             writeInt(VAL_BOOLEAN);
   1712             writeInt((Boolean) v ? 1 : 0);
   1713         } else if (v instanceof CharSequence) {
   1714             // Must be after String
   1715             writeInt(VAL_CHARSEQUENCE);
   1716             writeCharSequence((CharSequence) v);
   1717         } else if (v instanceof List) {
   1718             writeInt(VAL_LIST);
   1719             writeList((List) v);
   1720         } else if (v instanceof SparseArray) {
   1721             writeInt(VAL_SPARSEARRAY);
   1722             writeSparseArray((SparseArray) v);
   1723         } else if (v instanceof boolean[]) {
   1724             writeInt(VAL_BOOLEANARRAY);
   1725             writeBooleanArray((boolean[]) v);
   1726         } else if (v instanceof byte[]) {
   1727             writeInt(VAL_BYTEARRAY);
   1728             writeByteArray((byte[]) v);
   1729         } else if (v instanceof String[]) {
   1730             writeInt(VAL_STRINGARRAY);
   1731             writeStringArray((String[]) v);
   1732         } else if (v instanceof CharSequence[]) {
   1733             // Must be after String[] and before Object[]
   1734             writeInt(VAL_CHARSEQUENCEARRAY);
   1735             writeCharSequenceArray((CharSequence[]) v);
   1736         } else if (v instanceof IBinder) {
   1737             writeInt(VAL_IBINDER);
   1738             writeStrongBinder((IBinder) v);
   1739         } else if (v instanceof Parcelable[]) {
   1740             writeInt(VAL_PARCELABLEARRAY);
   1741             writeParcelableArray((Parcelable[]) v, 0);
   1742         } else if (v instanceof int[]) {
   1743             writeInt(VAL_INTARRAY);
   1744             writeIntArray((int[]) v);
   1745         } else if (v instanceof long[]) {
   1746             writeInt(VAL_LONGARRAY);
   1747             writeLongArray((long[]) v);
   1748         } else if (v instanceof Byte) {
   1749             writeInt(VAL_BYTE);
   1750             writeInt((Byte) v);
   1751         } else if (v instanceof Size) {
   1752             writeInt(VAL_SIZE);
   1753             writeSize((Size) v);
   1754         } else if (v instanceof SizeF) {
   1755             writeInt(VAL_SIZEF);
   1756             writeSizeF((SizeF) v);
   1757         } else if (v instanceof double[]) {
   1758             writeInt(VAL_DOUBLEARRAY);
   1759             writeDoubleArray((double[]) v);
   1760         } else {
   1761             Class<?> clazz = v.getClass();
   1762             if (clazz.isArray() && clazz.getComponentType() == Object.class) {
   1763                 // Only pure Object[] are written here, Other arrays of non-primitive types are
   1764                 // handled by serialization as this does not record the component type.
   1765                 writeInt(VAL_OBJECTARRAY);
   1766                 writeArray((Object[]) v);
   1767             } else if (v instanceof Serializable) {
   1768                 // Must be last
   1769                 writeInt(VAL_SERIALIZABLE);
   1770                 writeSerializable((Serializable) v);
   1771             } else {
   1772                 throw new RuntimeException("Parcel: unable to marshal value " + v);
   1773             }
   1774         }
   1775     }
   1776 
   1777     /**
   1778      * Flatten the name of the class of the Parcelable and its contents
   1779      * into the parcel.
   1780      *
   1781      * @param p The Parcelable object to be written.
   1782      * @param parcelableFlags Contextual flags as per
   1783      * {@link Parcelable#writeToParcel(Parcel, int) Parcelable.writeToParcel()}.
   1784      */
   1785     public final void writeParcelable(Parcelable p, int parcelableFlags) {
   1786         if (p == null) {
   1787             writeString(null);
   1788             return;
   1789         }
   1790         writeParcelableCreator(p);
   1791         p.writeToParcel(this, parcelableFlags);
   1792     }
   1793 
   1794     /** @hide */
   1795     public final void writeParcelableCreator(Parcelable p) {
   1796         String name = p.getClass().getName();
   1797         writeString(name);
   1798     }
   1799 
   1800     /**
   1801      * Write a generic serializable object in to a Parcel.  It is strongly
   1802      * recommended that this method be avoided, since the serialization
   1803      * overhead is extremely large, and this approach will be much slower than
   1804      * using the other approaches to writing data in to a Parcel.
   1805      */
   1806     public final void writeSerializable(Serializable s) {
   1807         if (s == null) {
   1808             writeString(null);
   1809             return;
   1810         }
   1811         String name = s.getClass().getName();
   1812         writeString(name);
   1813 
   1814         ByteArrayOutputStream baos = new ByteArrayOutputStream();
   1815         try {
   1816             ObjectOutputStream oos = new ObjectOutputStream(baos);
   1817             oos.writeObject(s);
   1818             oos.close();
   1819 
   1820             writeByteArray(baos.toByteArray());
   1821         } catch (IOException ioe) {
   1822             throw new RuntimeException("Parcelable encountered " +
   1823                 "IOException writing serializable object (name = " + name +
   1824                 ")", ioe);
   1825         }
   1826     }
   1827 
   1828     /**
   1829      * Special function for writing an exception result at the header of
   1830      * a parcel, to be used when returning an exception from a transaction.
   1831      * Note that this currently only supports a few exception types; any other
   1832      * exception will be re-thrown by this function as a RuntimeException
   1833      * (to be caught by the system's last-resort exception handling when
   1834      * dispatching a transaction).
   1835      *
   1836      * <p>The supported exception types are:
   1837      * <ul>
   1838      * <li>{@link BadParcelableException}
   1839      * <li>{@link IllegalArgumentException}
   1840      * <li>{@link IllegalStateException}
   1841      * <li>{@link NullPointerException}
   1842      * <li>{@link SecurityException}
   1843      * <li>{@link UnsupportedOperationException}
   1844      * <li>{@link NetworkOnMainThreadException}
   1845      * </ul>
   1846      *
   1847      * @param e The Exception to be written.
   1848      *
   1849      * @see #writeNoException
   1850      * @see #readException
   1851      */
   1852     public final void writeException(Exception e) {
   1853         int code = 0;
   1854         if (e instanceof Parcelable
   1855                 && (e.getClass().getClassLoader() == Parcelable.class.getClassLoader())) {
   1856             // We only send Parcelable exceptions that are in the
   1857             // BootClassLoader to ensure that the receiver can unpack them
   1858             code = EX_PARCELABLE;
   1859         } else if (e instanceof SecurityException) {
   1860             code = EX_SECURITY;
   1861         } else if (e instanceof BadParcelableException) {
   1862             code = EX_BAD_PARCELABLE;
   1863         } else if (e instanceof IllegalArgumentException) {
   1864             code = EX_ILLEGAL_ARGUMENT;
   1865         } else if (e instanceof NullPointerException) {
   1866             code = EX_NULL_POINTER;
   1867         } else if (e instanceof IllegalStateException) {
   1868             code = EX_ILLEGAL_STATE;
   1869         } else if (e instanceof NetworkOnMainThreadException) {
   1870             code = EX_NETWORK_MAIN_THREAD;
   1871         } else if (e instanceof UnsupportedOperationException) {
   1872             code = EX_UNSUPPORTED_OPERATION;
   1873         } else if (e instanceof ServiceSpecificException) {
   1874             code = EX_SERVICE_SPECIFIC;
   1875         }
   1876         writeInt(code);
   1877         StrictMode.clearGatheredViolations();
   1878         if (code == 0) {
   1879             if (e instanceof RuntimeException) {
   1880                 throw (RuntimeException) e;
   1881             }
   1882             throw new RuntimeException(e);
   1883         }
   1884         writeString(e.getMessage());
   1885         switch (code) {
   1886             case EX_SERVICE_SPECIFIC:
   1887                 writeInt(((ServiceSpecificException) e).errorCode);
   1888                 break;
   1889             case EX_PARCELABLE:
   1890                 // Write parceled exception prefixed by length
   1891                 final int sizePosition = dataPosition();
   1892                 writeInt(0);
   1893                 writeParcelable((Parcelable) e, Parcelable.PARCELABLE_WRITE_RETURN_VALUE);
   1894                 final int payloadPosition = dataPosition();
   1895                 setDataPosition(sizePosition);
   1896                 writeInt(payloadPosition - sizePosition);
   1897                 setDataPosition(payloadPosition);
   1898                 break;
   1899         }
   1900     }
   1901 
   1902     /**
   1903      * Special function for writing information at the front of the Parcel
   1904      * indicating that no exception occurred.
   1905      *
   1906      * @see #writeException
   1907      * @see #readException
   1908      */
   1909     public final void writeNoException() {
   1910         // Despite the name of this function ("write no exception"),
   1911         // it should instead be thought of as "write the RPC response
   1912         // header", but because this function name is written out by
   1913         // the AIDL compiler, we're not going to rename it.
   1914         //
   1915         // The response header, in the non-exception case (see also
   1916         // writeException above, also called by the AIDL compiler), is
   1917         // either a 0 (the default case), or EX_HAS_REPLY_HEADER if
   1918         // StrictMode has gathered up violations that have occurred
   1919         // during a Binder call, in which case we write out the number
   1920         // of violations and their details, serialized, before the
   1921         // actual RPC respons data.  The receiving end of this is
   1922         // readException(), below.
   1923         if (StrictMode.hasGatheredViolations()) {
   1924             writeInt(EX_HAS_REPLY_HEADER);
   1925             final int sizePosition = dataPosition();
   1926             writeInt(0);  // total size of fat header, to be filled in later
   1927             StrictMode.writeGatheredViolationsToParcel(this);
   1928             final int payloadPosition = dataPosition();
   1929             setDataPosition(sizePosition);
   1930             writeInt(payloadPosition - sizePosition);  // header size
   1931             setDataPosition(payloadPosition);
   1932         } else {
   1933             writeInt(0);
   1934         }
   1935     }
   1936 
   1937     /**
   1938      * Special function for reading an exception result from the header of
   1939      * a parcel, to be used after receiving the result of a transaction.  This
   1940      * will throw the exception for you if it had been written to the Parcel,
   1941      * otherwise return and let you read the normal result data from the Parcel.
   1942      *
   1943      * @see #writeException
   1944      * @see #writeNoException
   1945      */
   1946     public final void readException() {
   1947         int code = readExceptionCode();
   1948         if (code != 0) {
   1949             String msg = readString();
   1950             readException(code, msg);
   1951         }
   1952     }
   1953 
   1954     /**
   1955      * Parses the header of a Binder call's response Parcel and
   1956      * returns the exception code.  Deals with lite or fat headers.
   1957      * In the common successful case, this header is generally zero.
   1958      * In less common cases, it's a small negative number and will be
   1959      * followed by an error string.
   1960      *
   1961      * This exists purely for android.database.DatabaseUtils and
   1962      * insulating it from having to handle fat headers as returned by
   1963      * e.g. StrictMode-induced RPC responses.
   1964      *
   1965      * @hide
   1966      */
   1967     public final int readExceptionCode() {
   1968         int code = readInt();
   1969         if (code == EX_HAS_REPLY_HEADER) {
   1970             int headerSize = readInt();
   1971             if (headerSize == 0) {
   1972                 Log.e(TAG, "Unexpected zero-sized Parcel reply header.");
   1973             } else {
   1974                 // Currently the only thing in the header is StrictMode stacks,
   1975                 // but discussions around event/RPC tracing suggest we might
   1976                 // put that here too.  If so, switch on sub-header tags here.
   1977                 // But for now, just parse out the StrictMode stuff.
   1978                 StrictMode.readAndHandleBinderCallViolations(this);
   1979             }
   1980             // And fat response headers are currently only used when
   1981             // there are no exceptions, so return no error:
   1982             return 0;
   1983         }
   1984         return code;
   1985     }
   1986 
   1987     /**
   1988      * Throw an exception with the given message. Not intended for use
   1989      * outside the Parcel class.
   1990      *
   1991      * @param code Used to determine which exception class to throw.
   1992      * @param msg The exception message.
   1993      */
   1994     public final void readException(int code, String msg) {
   1995         switch (code) {
   1996             case EX_PARCELABLE:
   1997                 if (readInt() > 0) {
   1998                     SneakyThrow.sneakyThrow(
   1999                             (Exception) readParcelable(Parcelable.class.getClassLoader()));
   2000                 } else {
   2001                     throw new RuntimeException(msg + " [missing Parcelable]");
   2002                 }
   2003             case EX_SECURITY:
   2004                 throw new SecurityException(msg);
   2005             case EX_BAD_PARCELABLE:
   2006                 throw new BadParcelableException(msg);
   2007             case EX_ILLEGAL_ARGUMENT:
   2008                 throw new IllegalArgumentException(msg);
   2009             case EX_NULL_POINTER:
   2010                 throw new NullPointerException(msg);
   2011             case EX_ILLEGAL_STATE:
   2012                 throw new IllegalStateException(msg);
   2013             case EX_NETWORK_MAIN_THREAD:
   2014                 throw new NetworkOnMainThreadException();
   2015             case EX_UNSUPPORTED_OPERATION:
   2016                 throw new UnsupportedOperationException(msg);
   2017             case EX_SERVICE_SPECIFIC:
   2018                 throw new ServiceSpecificException(readInt(), msg);
   2019         }
   2020         throw new RuntimeException("Unknown exception code: " + code
   2021                 + " msg " + msg);
   2022     }
   2023 
   2024     /**
   2025      * Read an integer value from the parcel at the current dataPosition().
   2026      */
   2027     public final int readInt() {
   2028         return nativeReadInt(mNativePtr);
   2029     }
   2030 
   2031     /**
   2032      * Read a long integer value from the parcel at the current dataPosition().
   2033      */
   2034     public final long readLong() {
   2035         return nativeReadLong(mNativePtr);
   2036     }
   2037 
   2038     /**
   2039      * Read a floating point value from the parcel at the current
   2040      * dataPosition().
   2041      */
   2042     public final float readFloat() {
   2043         return nativeReadFloat(mNativePtr);
   2044     }
   2045 
   2046     /**
   2047      * Read a double precision floating point value from the parcel at the
   2048      * current dataPosition().
   2049      */
   2050     public final double readDouble() {
   2051         return nativeReadDouble(mNativePtr);
   2052     }
   2053 
   2054     /**
   2055      * Read a string value from the parcel at the current dataPosition().
   2056      */
   2057     public final String readString() {
   2058         return mReadWriteHelper.readString(this);
   2059     }
   2060 
   2061     /**
   2062      * Read a string without going though a {@link ReadWriteHelper}.  Subclasses of
   2063      * {@link ReadWriteHelper} must use this method instead of {@link #readString} to avoid
   2064      * infinity recursive calls.
   2065      *
   2066      * @hide
   2067      */
   2068     public String readStringNoHelper() {
   2069         return nativeReadString(mNativePtr);
   2070     }
   2071 
   2072     /** @hide */
   2073     public final boolean readBoolean() {
   2074         return readInt() != 0;
   2075     }
   2076 
   2077     /**
   2078      * Read a CharSequence value from the parcel at the current dataPosition().
   2079      * @hide
   2080      */
   2081     public final CharSequence readCharSequence() {
   2082         return TextUtils.CHAR_SEQUENCE_CREATOR.createFromParcel(this);
   2083     }
   2084 
   2085     /**
   2086      * Read an object from the parcel at the current dataPosition().
   2087      */
   2088     public final IBinder readStrongBinder() {
   2089         return nativeReadStrongBinder(mNativePtr);
   2090     }
   2091 
   2092     /**
   2093      * Read a FileDescriptor from the parcel at the current dataPosition().
   2094      */
   2095     public final ParcelFileDescriptor readFileDescriptor() {
   2096         FileDescriptor fd = nativeReadFileDescriptor(mNativePtr);
   2097         return fd != null ? new ParcelFileDescriptor(fd) : null;
   2098     }
   2099 
   2100     /** {@hide} */
   2101     public final FileDescriptor readRawFileDescriptor() {
   2102         return nativeReadFileDescriptor(mNativePtr);
   2103     }
   2104 
   2105     /**
   2106      * {@hide}
   2107      * Read and return a new array of FileDescriptors from the parcel.
   2108      * @return the FileDescriptor array, or null if the array is null.
   2109      **/
   2110     public final FileDescriptor[] createRawFileDescriptorArray() {
   2111         int N = readInt();
   2112         if (N < 0) {
   2113             return null;
   2114         }
   2115         FileDescriptor[] f = new FileDescriptor[N];
   2116         for (int i = 0; i < N; i++) {
   2117             f[i] = readRawFileDescriptor();
   2118         }
   2119         return f;
   2120     }
   2121 
   2122     /**
   2123      * {@hide}
   2124      * Read an array of FileDescriptors from a parcel.
   2125      * The passed array must be exactly the length of the array in the parcel.
   2126      * @return the FileDescriptor array, or null if the array is null.
   2127      **/
   2128     public final void readRawFileDescriptorArray(FileDescriptor[] val) {
   2129         int N = readInt();
   2130         if (N == val.length) {
   2131             for (int i=0; i<N; i++) {
   2132                 val[i] = readRawFileDescriptor();
   2133             }
   2134         } else {
   2135             throw new RuntimeException("bad array lengths");
   2136         }
   2137     }
   2138 
   2139     /** @deprecated use {@link android.system.Os#open(String, int, int)} */
   2140     @Deprecated
   2141     static native FileDescriptor openFileDescriptor(String file, int mode)
   2142             throws FileNotFoundException;
   2143 
   2144     /** @deprecated use {@link android.system.Os#dup(FileDescriptor)} */
   2145     @Deprecated
   2146     static native FileDescriptor dupFileDescriptor(FileDescriptor orig) throws IOException;
   2147 
   2148     /** @deprecated use {@link android.system.Os#close(FileDescriptor)} */
   2149     @Deprecated
   2150     static native void closeFileDescriptor(FileDescriptor desc) throws IOException;
   2151 
   2152     static native void clearFileDescriptor(FileDescriptor desc);
   2153 
   2154     /**
   2155      * Read a byte value from the parcel at the current dataPosition().
   2156      */
   2157     public final byte readByte() {
   2158         return (byte)(readInt() & 0xff);
   2159     }
   2160 
   2161     /**
   2162      * Please use {@link #readBundle(ClassLoader)} instead (whose data must have
   2163      * been written with {@link #writeBundle}.  Read into an existing Map object
   2164      * from the parcel at the current dataPosition().
   2165      */
   2166     public final void readMap(Map outVal, ClassLoader loader) {
   2167         int N = readInt();
   2168         readMapInternal(outVal, N, loader);
   2169     }
   2170 
   2171     /**
   2172      * Read into an existing List object from the parcel at the current
   2173      * dataPosition(), using the given class loader to load any enclosed
   2174      * Parcelables.  If it is null, the default class loader is used.
   2175      */
   2176     public final void readList(List outVal, ClassLoader loader) {
   2177         int N = readInt();
   2178         readListInternal(outVal, N, loader);
   2179     }
   2180 
   2181     /**
   2182      * Please use {@link #readBundle(ClassLoader)} instead (whose data must have
   2183      * been written with {@link #writeBundle}.  Read and return a new HashMap
   2184      * object from the parcel at the current dataPosition(), using the given
   2185      * class loader to load any enclosed Parcelables.  Returns null if
   2186      * the previously written map object was null.
   2187      */
   2188     public final HashMap readHashMap(ClassLoader loader)
   2189     {
   2190         int N = readInt();
   2191         if (N < 0) {
   2192             return null;
   2193         }
   2194         HashMap m = new HashMap(N);
   2195         readMapInternal(m, N, loader);
   2196         return m;
   2197     }
   2198 
   2199     /**
   2200      * Read and return a new Bundle object from the parcel at the current
   2201      * dataPosition().  Returns null if the previously written Bundle object was
   2202      * null.
   2203      */
   2204     public final Bundle readBundle() {
   2205         return readBundle(null);
   2206     }
   2207 
   2208     /**
   2209      * Read and return a new Bundle object from the parcel at the current
   2210      * dataPosition(), using the given class loader to initialize the class
   2211      * loader of the Bundle for later retrieval of Parcelable objects.
   2212      * Returns null if the previously written Bundle object was null.
   2213      */
   2214     public final Bundle readBundle(ClassLoader loader) {
   2215         int length = readInt();
   2216         if (length < 0) {
   2217             if (Bundle.DEBUG) Log.d(TAG, "null bundle: length=" + length);
   2218             return null;
   2219         }
   2220 
   2221         final Bundle bundle = new Bundle(this, length);
   2222         if (loader != null) {
   2223             bundle.setClassLoader(loader);
   2224         }
   2225         return bundle;
   2226     }
   2227 
   2228     /**
   2229      * Read and return a new Bundle object from the parcel at the current
   2230      * dataPosition().  Returns null if the previously written Bundle object was
   2231      * null.
   2232      */
   2233     public final PersistableBundle readPersistableBundle() {
   2234         return readPersistableBundle(null);
   2235     }
   2236 
   2237     /**
   2238      * Read and return a new Bundle object from the parcel at the current
   2239      * dataPosition(), using the given class loader to initialize the class
   2240      * loader of the Bundle for later retrieval of Parcelable objects.
   2241      * Returns null if the previously written Bundle object was null.
   2242      */
   2243     public final PersistableBundle readPersistableBundle(ClassLoader loader) {
   2244         int length = readInt();
   2245         if (length < 0) {
   2246             if (Bundle.DEBUG) Log.d(TAG, "null bundle: length=" + length);
   2247             return null;
   2248         }
   2249 
   2250         final PersistableBundle bundle = new PersistableBundle(this, length);
   2251         if (loader != null) {
   2252             bundle.setClassLoader(loader);
   2253         }
   2254         return bundle;
   2255     }
   2256 
   2257     /**
   2258      * Read a Size from the parcel at the current dataPosition().
   2259      */
   2260     public final Size readSize() {
   2261         final int width = readInt();
   2262         final int height = readInt();
   2263         return new Size(width, height);
   2264     }
   2265 
   2266     /**
   2267      * Read a SizeF from the parcel at the current dataPosition().
   2268      */
   2269     public final SizeF readSizeF() {
   2270         final float width = readFloat();
   2271         final float height = readFloat();
   2272         return new SizeF(width, height);
   2273     }
   2274 
   2275     /**
   2276      * Read and return a byte[] object from the parcel.
   2277      */
   2278     public final byte[] createByteArray() {
   2279         return nativeCreateByteArray(mNativePtr);
   2280     }
   2281 
   2282     /**
   2283      * Read a byte[] object from the parcel and copy it into the
   2284      * given byte array.
   2285      */
   2286     public final void readByteArray(byte[] val) {
   2287         boolean valid = nativeReadByteArray(mNativePtr, val, (val != null) ? val.length : 0);
   2288         if (!valid) {
   2289             throw new RuntimeException("bad array lengths");
   2290         }
   2291     }
   2292 
   2293     /**
   2294      * Read a blob of data from the parcel and return it as a byte array.
   2295      * {@hide}
   2296      * {@SystemApi}
   2297      */
   2298     public final byte[] readBlob() {
   2299         return nativeReadBlob(mNativePtr);
   2300     }
   2301 
   2302     /**
   2303      * Read and return a String[] object from the parcel.
   2304      * {@hide}
   2305      */
   2306     public final String[] readStringArray() {
   2307         String[] array = null;
   2308 
   2309         int length = readInt();
   2310         if (length >= 0)
   2311         {
   2312             array = new String[length];
   2313 
   2314             for (int i = 0 ; i < length ; i++)
   2315             {
   2316                 array[i] = readString();
   2317             }
   2318         }
   2319 
   2320         return array;
   2321     }
   2322 
   2323     /**
   2324      * Read and return a CharSequence[] object from the parcel.
   2325      * {@hide}
   2326      */
   2327     public final CharSequence[] readCharSequenceArray() {
   2328         CharSequence[] array = null;
   2329 
   2330         int length = readInt();
   2331         if (length >= 0)
   2332         {
   2333             array = new CharSequence[length];
   2334 
   2335             for (int i = 0 ; i < length ; i++)
   2336             {
   2337                 array[i] = readCharSequence();
   2338             }
   2339         }
   2340 
   2341         return array;
   2342     }
   2343 
   2344     /**
   2345      * Read and return an ArrayList&lt;CharSequence&gt; object from the parcel.
   2346      * {@hide}
   2347      */
   2348     public final ArrayList<CharSequence> readCharSequenceList() {
   2349         ArrayList<CharSequence> array = null;
   2350 
   2351         int length = readInt();
   2352         if (length >= 0) {
   2353             array = new ArrayList<CharSequence>(length);
   2354 
   2355             for (int i = 0 ; i < length ; i++) {
   2356                 array.add(readCharSequence());
   2357             }
   2358         }
   2359 
   2360         return array;
   2361     }
   2362 
   2363     /**
   2364      * Read and return a new ArrayList object from the parcel at the current
   2365      * dataPosition().  Returns null if the previously written list object was
   2366      * null.  The given class loader will be used to load any enclosed
   2367      * Parcelables.
   2368      */
   2369     public final ArrayList readArrayList(ClassLoader loader) {
   2370         int N = readInt();
   2371         if (N < 0) {
   2372             return null;
   2373         }
   2374         ArrayList l = new ArrayList(N);
   2375         readListInternal(l, N, loader);
   2376         return l;
   2377     }
   2378 
   2379     /**
   2380      * Read and return a new Object array from the parcel at the current
   2381      * dataPosition().  Returns null if the previously written array was
   2382      * null.  The given class loader will be used to load any enclosed
   2383      * Parcelables.
   2384      */
   2385     public final Object[] readArray(ClassLoader loader) {
   2386         int N = readInt();
   2387         if (N < 0) {
   2388             return null;
   2389         }
   2390         Object[] l = new Object[N];
   2391         readArrayInternal(l, N, loader);
   2392         return l;
   2393     }
   2394 
   2395     /**
   2396      * Read and return a new SparseArray object from the parcel at the current
   2397      * dataPosition().  Returns null if the previously written list object was
   2398      * null.  The given class loader will be used to load any enclosed
   2399      * Parcelables.
   2400      */
   2401     public final SparseArray readSparseArray(ClassLoader loader) {
   2402         int N = readInt();
   2403         if (N < 0) {
   2404             return null;
   2405         }
   2406         SparseArray sa = new SparseArray(N);
   2407         readSparseArrayInternal(sa, N, loader);
   2408         return sa;
   2409     }
   2410 
   2411     /**
   2412      * Read and return a new SparseBooleanArray object from the parcel at the current
   2413      * dataPosition().  Returns null if the previously written list object was
   2414      * null.
   2415      */
   2416     public final SparseBooleanArray readSparseBooleanArray() {
   2417         int N = readInt();
   2418         if (N < 0) {
   2419             return null;
   2420         }
   2421         SparseBooleanArray sa = new SparseBooleanArray(N);
   2422         readSparseBooleanArrayInternal(sa, N);
   2423         return sa;
   2424     }
   2425 
   2426     /**
   2427      * Read and return a new SparseIntArray object from the parcel at the current
   2428      * dataPosition(). Returns null if the previously written array object was null.
   2429      * @hide
   2430      */
   2431     public final SparseIntArray readSparseIntArray() {
   2432         int N = readInt();
   2433         if (N < 0) {
   2434             return null;
   2435         }
   2436         SparseIntArray sa = new SparseIntArray(N);
   2437         readSparseIntArrayInternal(sa, N);
   2438         return sa;
   2439     }
   2440 
   2441     /**
   2442      * Read and return a new ArrayList containing a particular object type from
   2443      * the parcel that was written with {@link #writeTypedList} at the
   2444      * current dataPosition().  Returns null if the
   2445      * previously written list object was null.  The list <em>must</em> have
   2446      * previously been written via {@link #writeTypedList} with the same object
   2447      * type.
   2448      *
   2449      * @return A newly created ArrayList containing objects with the same data
   2450      *         as those that were previously written.
   2451      *
   2452      * @see #writeTypedList
   2453      */
   2454     public final <T> ArrayList<T> createTypedArrayList(Parcelable.Creator<T> c) {
   2455         int N = readInt();
   2456         if (N < 0) {
   2457             return null;
   2458         }
   2459         ArrayList<T> l = new ArrayList<T>(N);
   2460         while (N > 0) {
   2461             if (readInt() != 0) {
   2462                 l.add(c.createFromParcel(this));
   2463             } else {
   2464                 l.add(null);
   2465             }
   2466             N--;
   2467         }
   2468         return l;
   2469     }
   2470 
   2471     /**
   2472      * Read into the given List items containing a particular object type
   2473      * that were written with {@link #writeTypedList} at the
   2474      * current dataPosition().  The list <em>must</em> have
   2475      * previously been written via {@link #writeTypedList} with the same object
   2476      * type.
   2477      *
   2478      * @return A newly created ArrayList containing objects with the same data
   2479      *         as those that were previously written.
   2480      *
   2481      * @see #writeTypedList
   2482      */
   2483     public final <T> void readTypedList(List<T> list, Parcelable.Creator<T> c) {
   2484         int M = list.size();
   2485         int N = readInt();
   2486         int i = 0;
   2487         for (; i < M && i < N; i++) {
   2488             if (readInt() != 0) {
   2489                 list.set(i, c.createFromParcel(this));
   2490             } else {
   2491                 list.set(i, null);
   2492             }
   2493         }
   2494         for (; i<N; i++) {
   2495             if (readInt() != 0) {
   2496                 list.add(c.createFromParcel(this));
   2497             } else {
   2498                 list.add(null);
   2499             }
   2500         }
   2501         for (; i<M; i++) {
   2502             list.remove(N);
   2503         }
   2504     }
   2505 
   2506     /**
   2507      * Read and return a new ArrayList containing String objects from
   2508      * the parcel that was written with {@link #writeStringList} at the
   2509      * current dataPosition().  Returns null if the
   2510      * previously written list object was null.
   2511      *
   2512      * @return A newly created ArrayList containing strings with the same data
   2513      *         as those that were previously written.
   2514      *
   2515      * @see #writeStringList
   2516      */
   2517     public final ArrayList<String> createStringArrayList() {
   2518         int N = readInt();
   2519         if (N < 0) {
   2520             return null;
   2521         }
   2522         ArrayList<String> l = new ArrayList<String>(N);
   2523         while (N > 0) {
   2524             l.add(readString());
   2525             N--;
   2526         }
   2527         return l;
   2528     }
   2529 
   2530     /**
   2531      * Read and return a new ArrayList containing IBinder objects from
   2532      * the parcel that was written with {@link #writeBinderList} at the
   2533      * current dataPosition().  Returns null if the
   2534      * previously written list object was null.
   2535      *
   2536      * @return A newly created ArrayList containing strings with the same data
   2537      *         as those that were previously written.
   2538      *
   2539      * @see #writeBinderList
   2540      */
   2541     public final ArrayList<IBinder> createBinderArrayList() {
   2542         int N = readInt();
   2543         if (N < 0) {
   2544             return null;
   2545         }
   2546         ArrayList<IBinder> l = new ArrayList<IBinder>(N);
   2547         while (N > 0) {
   2548             l.add(readStrongBinder());
   2549             N--;
   2550         }
   2551         return l;
   2552     }
   2553 
   2554     /**
   2555      * Read into the given List items String objects that were written with
   2556      * {@link #writeStringList} at the current dataPosition().
   2557      *
   2558      * @return A newly created ArrayList containing strings with the same data
   2559      *         as those that were previously written.
   2560      *
   2561      * @see #writeStringList
   2562      */
   2563     public final void readStringList(List<String> list) {
   2564         int M = list.size();
   2565         int N = readInt();
   2566         int i = 0;
   2567         for (; i < M && i < N; i++) {
   2568             list.set(i, readString());
   2569         }
   2570         for (; i<N; i++) {
   2571             list.add(readString());
   2572         }
   2573         for (; i<M; i++) {
   2574             list.remove(N);
   2575         }
   2576     }
   2577 
   2578     /**
   2579      * Read into the given List items IBinder objects that were written with
   2580      * {@link #writeBinderList} at the current dataPosition().
   2581      *
   2582      * @see #writeBinderList
   2583      */
   2584     public final void readBinderList(List<IBinder> list) {
   2585         int M = list.size();
   2586         int N = readInt();
   2587         int i = 0;
   2588         for (; i < M && i < N; i++) {
   2589             list.set(i, readStrongBinder());
   2590         }
   2591         for (; i<N; i++) {
   2592             list.add(readStrongBinder());
   2593         }
   2594         for (; i<M; i++) {
   2595             list.remove(N);
   2596         }
   2597     }
   2598 
   2599     /**
   2600      * Read the list of {@code Parcelable} objects at the current data position into the
   2601      * given {@code list}. The contents of the {@code list} are replaced. If the serialized
   2602      * list was {@code null}, {@code list} is cleared.
   2603      *
   2604      * @see #writeParcelableList(List, int)
   2605      * @hide
   2606      */
   2607     public final <T extends Parcelable> List<T> readParcelableList(List<T> list, ClassLoader cl) {
   2608         final int N = readInt();
   2609         if (N == -1) {
   2610             list.clear();
   2611             return list;
   2612         }
   2613 
   2614         final int M = list.size();
   2615         int i = 0;
   2616         for (; i < M && i < N; i++) {
   2617             list.set(i, (T) readParcelable(cl));
   2618         }
   2619         for (; i<N; i++) {
   2620             list.add((T) readParcelable(cl));
   2621         }
   2622         for (; i<M; i++) {
   2623             list.remove(N);
   2624         }
   2625         return list;
   2626     }
   2627 
   2628     /**
   2629      * Read and return a new array containing a particular object type from
   2630      * the parcel at the current dataPosition().  Returns null if the
   2631      * previously written array was null.  The array <em>must</em> have
   2632      * previously been written via {@link #writeTypedArray} with the same
   2633      * object type.
   2634      *
   2635      * @return A newly created array containing objects with the same data
   2636      *         as those that were previously written.
   2637      *
   2638      * @see #writeTypedArray
   2639      */
   2640     public final <T> T[] createTypedArray(Parcelable.Creator<T> c) {
   2641         int N = readInt();
   2642         if (N < 0) {
   2643             return null;
   2644         }
   2645         T[] l = c.newArray(N);
   2646         for (int i=0; i<N; i++) {
   2647             if (readInt() != 0) {
   2648                 l[i] = c.createFromParcel(this);
   2649             }
   2650         }
   2651         return l;
   2652     }
   2653 
   2654     public final <T> void readTypedArray(T[] val, Parcelable.Creator<T> c) {
   2655         int N = readInt();
   2656         if (N == val.length) {
   2657             for (int i=0; i<N; i++) {
   2658                 if (readInt() != 0) {
   2659                     val[i] = c.createFromParcel(this);
   2660                 } else {
   2661                     val[i] = null;
   2662                 }
   2663             }
   2664         } else {
   2665             throw new RuntimeException("bad array lengths");
   2666         }
   2667     }
   2668 
   2669     /**
   2670      * @deprecated
   2671      * @hide
   2672      */
   2673     @Deprecated
   2674     public final <T> T[] readTypedArray(Parcelable.Creator<T> c) {
   2675         return createTypedArray(c);
   2676     }
   2677 
   2678     /**
   2679      * Read and return a typed Parcelable object from a parcel.
   2680      * Returns null if the previous written object was null.
   2681      * The object <em>must</em> have previous been written via
   2682      * {@link #writeTypedObject} with the same object type.
   2683      *
   2684      * @return A newly created object of the type that was previously
   2685      *         written.
   2686      *
   2687      * @see #writeTypedObject
   2688      */
   2689     public final <T> T readTypedObject(Parcelable.Creator<T> c) {
   2690         if (readInt() != 0) {
   2691             return c.createFromParcel(this);
   2692         } else {
   2693             return null;
   2694         }
   2695     }
   2696 
   2697     /**
   2698      * Write a heterogeneous array of Parcelable objects into the Parcel.
   2699      * Each object in the array is written along with its class name, so
   2700      * that the correct class can later be instantiated.  As a result, this
   2701      * has significantly more overhead than {@link #writeTypedArray}, but will
   2702      * correctly handle an array containing more than one type of object.
   2703      *
   2704      * @param value The array of objects to be written.
   2705      * @param parcelableFlags Contextual flags as per
   2706      * {@link Parcelable#writeToParcel(Parcel, int) Parcelable.writeToParcel()}.
   2707      *
   2708      * @see #writeTypedArray
   2709      */
   2710     public final <T extends Parcelable> void writeParcelableArray(T[] value,
   2711             int parcelableFlags) {
   2712         if (value != null) {
   2713             int N = value.length;
   2714             writeInt(N);
   2715             for (int i=0; i<N; i++) {
   2716                 writeParcelable(value[i], parcelableFlags);
   2717             }
   2718         } else {
   2719             writeInt(-1);
   2720         }
   2721     }
   2722 
   2723     /**
   2724      * Read a typed object from a parcel.  The given class loader will be
   2725      * used to load any enclosed Parcelables.  If it is null, the default class
   2726      * loader will be used.
   2727      */
   2728     public final Object readValue(ClassLoader loader) {
   2729         int type = readInt();
   2730 
   2731         switch (type) {
   2732         case VAL_NULL:
   2733             return null;
   2734 
   2735         case VAL_STRING:
   2736             return readString();
   2737 
   2738         case VAL_INTEGER:
   2739             return readInt();
   2740 
   2741         case VAL_MAP:
   2742             return readHashMap(loader);
   2743 
   2744         case VAL_PARCELABLE:
   2745             return readParcelable(loader);
   2746 
   2747         case VAL_SHORT:
   2748             return (short) readInt();
   2749 
   2750         case VAL_LONG:
   2751             return readLong();
   2752 
   2753         case VAL_FLOAT:
   2754             return readFloat();
   2755 
   2756         case VAL_DOUBLE:
   2757             return readDouble();
   2758 
   2759         case VAL_BOOLEAN:
   2760             return readInt() == 1;
   2761 
   2762         case VAL_CHARSEQUENCE:
   2763             return readCharSequence();
   2764 
   2765         case VAL_LIST:
   2766             return readArrayList(loader);
   2767 
   2768         case VAL_BOOLEANARRAY:
   2769             return createBooleanArray();
   2770 
   2771         case VAL_BYTEARRAY:
   2772             return createByteArray();
   2773 
   2774         case VAL_STRINGARRAY:
   2775             return readStringArray();
   2776 
   2777         case VAL_CHARSEQUENCEARRAY:
   2778             return readCharSequenceArray();
   2779 
   2780         case VAL_IBINDER:
   2781             return readStrongBinder();
   2782 
   2783         case VAL_OBJECTARRAY:
   2784             return readArray(loader);
   2785 
   2786         case VAL_INTARRAY:
   2787             return createIntArray();
   2788 
   2789         case VAL_LONGARRAY:
   2790             return createLongArray();
   2791 
   2792         case VAL_BYTE:
   2793             return readByte();
   2794 
   2795         case VAL_SERIALIZABLE:
   2796             return readSerializable(loader);
   2797 
   2798         case VAL_PARCELABLEARRAY:
   2799             return readParcelableArray(loader);
   2800 
   2801         case VAL_SPARSEARRAY:
   2802             return readSparseArray(loader);
   2803 
   2804         case VAL_SPARSEBOOLEANARRAY:
   2805             return readSparseBooleanArray();
   2806 
   2807         case VAL_BUNDLE:
   2808             return readBundle(loader); // loading will be deferred
   2809 
   2810         case VAL_PERSISTABLEBUNDLE:
   2811             return readPersistableBundle(loader);
   2812 
   2813         case VAL_SIZE:
   2814             return readSize();
   2815 
   2816         case VAL_SIZEF:
   2817             return readSizeF();
   2818 
   2819         case VAL_DOUBLEARRAY:
   2820             return createDoubleArray();
   2821 
   2822         default:
   2823             int off = dataPosition() - 4;
   2824             throw new RuntimeException(
   2825                 "Parcel " + this + ": Unmarshalling unknown type code " + type + " at offset " + off);
   2826         }
   2827     }
   2828 
   2829     /**
   2830      * Read and return a new Parcelable from the parcel.  The given class loader
   2831      * will be used to load any enclosed Parcelables.  If it is null, the default
   2832      * class loader will be used.
   2833      * @param loader A ClassLoader from which to instantiate the Parcelable
   2834      * object, or null for the default class loader.
   2835      * @return Returns the newly created Parcelable, or null if a null
   2836      * object has been written.
   2837      * @throws BadParcelableException Throws BadParcelableException if there
   2838      * was an error trying to instantiate the Parcelable.
   2839      */
   2840     @SuppressWarnings("unchecked")
   2841     public final <T extends Parcelable> T readParcelable(ClassLoader loader) {
   2842         Parcelable.Creator<?> creator = readParcelableCreator(loader);
   2843         if (creator == null) {
   2844             return null;
   2845         }
   2846         if (creator instanceof Parcelable.ClassLoaderCreator<?>) {
   2847           Parcelable.ClassLoaderCreator<?> classLoaderCreator =
   2848               (Parcelable.ClassLoaderCreator<?>) creator;
   2849           return (T) classLoaderCreator.createFromParcel(this, loader);
   2850         }
   2851         return (T) creator.createFromParcel(this);
   2852     }
   2853 
   2854     /** @hide */
   2855     @SuppressWarnings("unchecked")
   2856     public final <T extends Parcelable> T readCreator(Parcelable.Creator<?> creator,
   2857             ClassLoader loader) {
   2858         if (creator instanceof Parcelable.ClassLoaderCreator<?>) {
   2859           Parcelable.ClassLoaderCreator<?> classLoaderCreator =
   2860               (Parcelable.ClassLoaderCreator<?>) creator;
   2861           return (T) classLoaderCreator.createFromParcel(this, loader);
   2862         }
   2863         return (T) creator.createFromParcel(this);
   2864     }
   2865 
   2866     /** @hide */
   2867     public final Parcelable.Creator<?> readParcelableCreator(ClassLoader loader) {
   2868         String name = readString();
   2869         if (name == null) {
   2870             return null;
   2871         }
   2872         Parcelable.Creator<?> creator;
   2873         synchronized (mCreators) {
   2874             HashMap<String,Parcelable.Creator<?>> map = mCreators.get(loader);
   2875             if (map == null) {
   2876                 map = new HashMap<>();
   2877                 mCreators.put(loader, map);
   2878             }
   2879             creator = map.get(name);
   2880             if (creator == null) {
   2881                 try {
   2882                     // If loader == null, explicitly emulate Class.forName(String) "caller
   2883                     // classloader" behavior.
   2884                     ClassLoader parcelableClassLoader =
   2885                             (loader == null ? getClass().getClassLoader() : loader);
   2886                     // Avoid initializing the Parcelable class until we know it implements
   2887                     // Parcelable and has the necessary CREATOR field. http://b/1171613.
   2888                     Class<?> parcelableClass = Class.forName(name, false /* initialize */,
   2889                             parcelableClassLoader);
   2890                     if (!Parcelable.class.isAssignableFrom(parcelableClass)) {
   2891                         throw new BadParcelableException("Parcelable protocol requires that the "
   2892                                 + "class implements Parcelable");
   2893                     }
   2894                     Field f = parcelableClass.getField("CREATOR");
   2895                     if ((f.getModifiers() & Modifier.STATIC) == 0) {
   2896                         throw new BadParcelableException("Parcelable protocol requires "
   2897                                 + "the CREATOR object to be static on class " + name);
   2898                     }
   2899                     Class<?> creatorType = f.getType();
   2900                     if (!Parcelable.Creator.class.isAssignableFrom(creatorType)) {
   2901                         // Fail before calling Field.get(), not after, to avoid initializing
   2902                         // parcelableClass unnecessarily.
   2903                         throw new BadParcelableException("Parcelable protocol requires a "
   2904                                 + "Parcelable.Creator object called "
   2905                                 + "CREATOR on class " + name);
   2906                     }
   2907                     creator = (Parcelable.Creator<?>) f.get(null);
   2908                 }
   2909                 catch (IllegalAccessException e) {
   2910                     Log.e(TAG, "Illegal access when unmarshalling: " + name, e);
   2911                     throw new BadParcelableException(
   2912                             "IllegalAccessException when unmarshalling: " + name);
   2913                 }
   2914                 catch (ClassNotFoundException e) {
   2915                     Log.e(TAG, "Class not found when unmarshalling: " + name, e);
   2916                     throw new BadParcelableException(
   2917                             "ClassNotFoundException when unmarshalling: " + name);
   2918                 }
   2919                 catch (NoSuchFieldException e) {
   2920                     throw new BadParcelableException("Parcelable protocol requires a "
   2921                             + "Parcelable.Creator object called "
   2922                             + "CREATOR on class " + name);
   2923                 }
   2924                 if (creator == null) {
   2925                     throw new BadParcelableException("Parcelable protocol requires a "
   2926                             + "non-null Parcelable.Creator object called "
   2927                             + "CREATOR on class " + name);
   2928                 }
   2929 
   2930                 map.put(name, creator);
   2931             }
   2932         }
   2933 
   2934         return creator;
   2935     }
   2936 
   2937     /**
   2938      * Read and return a new Parcelable array from the parcel.
   2939      * The given class loader will be used to load any enclosed
   2940      * Parcelables.
   2941      * @return the Parcelable array, or null if the array is null
   2942      */
   2943     public final Parcelable[] readParcelableArray(ClassLoader loader) {
   2944         int N = readInt();
   2945         if (N < 0) {
   2946             return null;
   2947         }
   2948         Parcelable[] p = new Parcelable[N];
   2949         for (int i = 0; i < N; i++) {
   2950             p[i] = readParcelable(loader);
   2951         }
   2952         return p;
   2953     }
   2954 
   2955     /** @hide */
   2956     public final <T extends Parcelable> T[] readParcelableArray(ClassLoader loader,
   2957             Class<T> clazz) {
   2958         int N = readInt();
   2959         if (N < 0) {
   2960             return null;
   2961         }
   2962         T[] p = (T[]) Array.newInstance(clazz, N);
   2963         for (int i = 0; i < N; i++) {
   2964             p[i] = readParcelable(loader);
   2965         }
   2966         return p;
   2967     }
   2968 
   2969     /**
   2970      * Read and return a new Serializable object from the parcel.
   2971      * @return the Serializable object, or null if the Serializable name
   2972      * wasn't found in the parcel.
   2973      */
   2974     public final Serializable readSerializable() {
   2975         return readSerializable(null);
   2976     }
   2977 
   2978     private final Serializable readSerializable(final ClassLoader loader) {
   2979         String name = readString();
   2980         if (name == null) {
   2981             // For some reason we were unable to read the name of the Serializable (either there
   2982             // is nothing left in the Parcel to read, or the next value wasn't a String), so
   2983             // return null, which indicates that the name wasn't found in the parcel.
   2984             return null;
   2985         }
   2986 
   2987         byte[] serializedData = createByteArray();
   2988         ByteArrayInputStream bais = new ByteArrayInputStream(serializedData);
   2989         try {
   2990             ObjectInputStream ois = new ObjectInputStream(bais) {
   2991                 @Override
   2992                 protected Class<?> resolveClass(ObjectStreamClass osClass)
   2993                         throws IOException, ClassNotFoundException {
   2994                     // try the custom classloader if provided
   2995                     if (loader != null) {
   2996                         Class<?> c = Class.forName(osClass.getName(), false, loader);
   2997                         if (c != null) {
   2998                             return c;
   2999                         }
   3000                     }
   3001                     return super.resolveClass(osClass);
   3002                 }
   3003             };
   3004             return (Serializable) ois.readObject();
   3005         } catch (IOException ioe) {
   3006             throw new RuntimeException("Parcelable encountered " +
   3007                 "IOException reading a Serializable object (name = " + name +
   3008                 ")", ioe);
   3009         } catch (ClassNotFoundException cnfe) {
   3010             throw new RuntimeException("Parcelable encountered " +
   3011                 "ClassNotFoundException reading a Serializable object (name = "
   3012                 + name + ")", cnfe);
   3013         }
   3014     }
   3015 
   3016     // Cache of previously looked up CREATOR.createFromParcel() methods for
   3017     // particular classes.  Keys are the names of the classes, values are
   3018     // Method objects.
   3019     private static final HashMap<ClassLoader,HashMap<String,Parcelable.Creator<?>>>
   3020         mCreators = new HashMap<>();
   3021 
   3022     /** @hide for internal use only. */
   3023     static protected final Parcel obtain(int obj) {
   3024         throw new UnsupportedOperationException();
   3025     }
   3026 
   3027     /** @hide */
   3028     static protected final Parcel obtain(long obj) {
   3029         final Parcel[] pool = sHolderPool;
   3030         synchronized (pool) {
   3031             Parcel p;
   3032             for (int i=0; i<POOL_SIZE; i++) {
   3033                 p = pool[i];
   3034                 if (p != null) {
   3035                     pool[i] = null;
   3036                     if (DEBUG_RECYCLE) {
   3037                         p.mStack = new RuntimeException();
   3038                     }
   3039                     p.init(obj);
   3040                     return p;
   3041                 }
   3042             }
   3043         }
   3044         return new Parcel(obj);
   3045     }
   3046 
   3047     private Parcel(long nativePtr) {
   3048         if (DEBUG_RECYCLE) {
   3049             mStack = new RuntimeException();
   3050         }
   3051         //Log.i(TAG, "Initializing obj=0x" + Integer.toHexString(obj), mStack);
   3052         init(nativePtr);
   3053     }
   3054 
   3055     private void init(long nativePtr) {
   3056         if (nativePtr != 0) {
   3057             mNativePtr = nativePtr;
   3058             mOwnsNativeParcelObject = false;
   3059         } else {
   3060             mNativePtr = nativeCreate();
   3061             mOwnsNativeParcelObject = true;
   3062         }
   3063     }
   3064 
   3065     private void freeBuffer() {
   3066         if (mOwnsNativeParcelObject) {
   3067             updateNativeSize(nativeFreeBuffer(mNativePtr));
   3068         }
   3069         mReadWriteHelper = ReadWriteHelper.DEFAULT;
   3070     }
   3071 
   3072     private void destroy() {
   3073         if (mNativePtr != 0) {
   3074             if (mOwnsNativeParcelObject) {
   3075                 nativeDestroy(mNativePtr);
   3076                 updateNativeSize(0);
   3077             }
   3078             mNativePtr = 0;
   3079         }
   3080         mReadWriteHelper = null;
   3081     }
   3082 
   3083     @Override
   3084     protected void finalize() throws Throwable {
   3085         if (DEBUG_RECYCLE) {
   3086             if (mStack != null) {
   3087                 Log.w(TAG, "Client did not call Parcel.recycle()", mStack);
   3088             }
   3089         }
   3090         destroy();
   3091     }
   3092 
   3093     /* package */ void readMapInternal(Map outVal, int N,
   3094         ClassLoader loader) {
   3095         while (N > 0) {
   3096             Object key = readValue(loader);
   3097             Object value = readValue(loader);
   3098             outVal.put(key, value);
   3099             N--;
   3100         }
   3101     }
   3102 
   3103     /* package */ void readArrayMapInternal(ArrayMap outVal, int N,
   3104         ClassLoader loader) {
   3105         if (DEBUG_ARRAY_MAP) {
   3106             RuntimeException here =  new RuntimeException("here");
   3107             here.fillInStackTrace();
   3108             Log.d(TAG, "Reading " + N + " ArrayMap entries", here);
   3109         }
   3110         int startPos;
   3111         while (N > 0) {
   3112             if (DEBUG_ARRAY_MAP) startPos = dataPosition();
   3113             String key = readString();
   3114             Object value = readValue(loader);
   3115             if (DEBUG_ARRAY_MAP) Log.d(TAG, "  Read #" + (N-1) + " "
   3116                     + (dataPosition()-startPos) + " bytes: key=0x"
   3117                     + Integer.toHexString((key != null ? key.hashCode() : 0)) + " " + key);
   3118             outVal.append(key, value);
   3119             N--;
   3120         }
   3121         outVal.validate();
   3122     }
   3123 
   3124     /* package */ void readArrayMapSafelyInternal(ArrayMap outVal, int N,
   3125         ClassLoader loader) {
   3126         if (DEBUG_ARRAY_MAP) {
   3127             RuntimeException here =  new RuntimeException("here");
   3128             here.fillInStackTrace();
   3129             Log.d(TAG, "Reading safely " + N + " ArrayMap entries", here);
   3130         }
   3131         while (N > 0) {
   3132             String key = readString();
   3133             if (DEBUG_ARRAY_MAP) Log.d(TAG, "  Read safe #" + (N-1) + ": key=0x"
   3134                     + (key != null ? key.hashCode() : 0) + " " + key);
   3135             Object value = readValue(loader);
   3136             outVal.put(key, value);
   3137             N--;
   3138         }
   3139     }
   3140 
   3141     /**
   3142      * @hide For testing only.
   3143      */
   3144     public void readArrayMap(ArrayMap outVal, ClassLoader loader) {
   3145         final int N = readInt();
   3146         if (N < 0) {
   3147             return;
   3148         }
   3149         readArrayMapInternal(outVal, N, loader);
   3150     }
   3151 
   3152     /**
   3153      * Reads an array set.
   3154      *
   3155      * @param loader The class loader to use.
   3156      *
   3157      * @hide
   3158      */
   3159     public @Nullable ArraySet<? extends Object> readArraySet(ClassLoader loader) {
   3160         final int size = readInt();
   3161         if (size < 0) {
   3162             return null;
   3163         }
   3164         ArraySet<Object> result = new ArraySet<>(size);
   3165         for (int i = 0; i < size; i++) {
   3166             Object value = readValue(loader);
   3167             result.append(value);
   3168         }
   3169         return result;
   3170     }
   3171 
   3172     private void readListInternal(List outVal, int N,
   3173         ClassLoader loader) {
   3174         while (N > 0) {
   3175             Object value = readValue(loader);
   3176             //Log.d(TAG, "Unmarshalling value=" + value);
   3177             outVal.add(value);
   3178             N--;
   3179         }
   3180     }
   3181 
   3182     private void readArrayInternal(Object[] outVal, int N,
   3183         ClassLoader loader) {
   3184         for (int i = 0; i < N; i++) {
   3185             Object value = readValue(loader);
   3186             //Log.d(TAG, "Unmarshalling value=" + value);
   3187             outVal[i] = value;
   3188         }
   3189     }
   3190 
   3191     private void readSparseArrayInternal(SparseArray outVal, int N,
   3192         ClassLoader loader) {
   3193         while (N > 0) {
   3194             int key = readInt();
   3195             Object value = readValue(loader);
   3196             //Log.i(TAG, "Unmarshalling key=" + key + " value=" + value);
   3197             outVal.append(key, value);
   3198             N--;
   3199         }
   3200     }
   3201 
   3202 
   3203     private void readSparseBooleanArrayInternal(SparseBooleanArray outVal, int N) {
   3204         while (N > 0) {
   3205             int key = readInt();
   3206             boolean value = this.readByte() == 1;
   3207             //Log.i(TAG, "Unmarshalling key=" + key + " value=" + value);
   3208             outVal.append(key, value);
   3209             N--;
   3210         }
   3211     }
   3212 
   3213     private void readSparseIntArrayInternal(SparseIntArray outVal, int N) {
   3214         while (N > 0) {
   3215             int key = readInt();
   3216             int value = readInt();
   3217             outVal.append(key, value);
   3218             N--;
   3219         }
   3220     }
   3221 
   3222     /**
   3223      * @hide For testing
   3224      */
   3225     public long getBlobAshmemSize() {
   3226         return nativeGetBlobAshmemSize(mNativePtr);
   3227     }
   3228 }
   3229