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