• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (C) 2006 The Android Open Source Project
3  *
4  * Licensed under the Apache License, Version 2.0 (the "License");
5  * you may not use this file except in compliance with the License.
6  * You may obtain a copy of the License at
7  *
8  *      http://www.apache.org/licenses/LICENSE-2.0
9  *
10  * Unless required by applicable law or agreed to in writing, software
11  * distributed under the License is distributed on an "AS IS" BASIS,
12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13  * See the License for the specific language governing permissions and
14  * limitations under the License.
15  */
16 
17 package android.os;
18 
19 import android.text.TextUtils;
20 import android.util.Log;
21 import android.util.SparseArray;
22 import android.util.SparseBooleanArray;
23 
24 import java.io.ByteArrayInputStream;
25 import java.io.ByteArrayOutputStream;
26 import java.io.FileDescriptor;
27 import java.io.FileNotFoundException;
28 import java.io.IOException;
29 import java.io.ObjectInputStream;
30 import java.io.ObjectOutputStream;
31 import java.io.Serializable;
32 import java.lang.reflect.Field;
33 import java.util.ArrayList;
34 import java.util.Arrays;
35 import java.util.HashMap;
36 import java.util.List;
37 import java.util.Map;
38 import java.util.Set;
39 
40 /**
41  * Container for a message (data and object references) that can
42  * be sent through an IBinder.  A Parcel can contain both flattened data
43  * that will be unflattened on the other side of the IPC (using the various
44  * methods here for writing specific types, or the general
45  * {@link Parcelable} interface), and references to live {@link IBinder}
46  * objects that will result in the other side receiving a proxy IBinder
47  * connected with the original IBinder in the Parcel.
48  *
49  * <p class="note">Parcel is <strong>not</strong> a general-purpose
50  * serialization mechanism.  This class (and the corresponding
51  * {@link Parcelable} API for placing arbitrary objects into a Parcel) is
52  * designed as a high-performance IPC transport.  As such, it is not
53  * appropriate to place any Parcel data in to persistent storage: changes
54  * in the underlying implementation of any of the data in the Parcel can
55  * render older data unreadable.</p>
56  *
57  * <p>The bulk of the Parcel API revolves around reading and writing data
58  * of various types.  There are six major classes of such functions available.</p>
59  *
60  * <h3>Primitives</h3>
61  *
62  * <p>The most basic data functions are for writing and reading primitive
63  * data types: {@link #writeByte}, {@link #readByte}, {@link #writeDouble},
64  * {@link #readDouble}, {@link #writeFloat}, {@link #readFloat}, {@link #writeInt},
65  * {@link #readInt}, {@link #writeLong}, {@link #readLong},
66  * {@link #writeString}, {@link #readString}.  Most other
67  * data operations are built on top of these.  The given data is written and
68  * read using the endianess of the host CPU.</p>
69  *
70  * <h3>Primitive Arrays</h3>
71  *
72  * <p>There are a variety of methods for reading and writing raw arrays
73  * of primitive objects, which generally result in writing a 4-byte length
74  * followed by the primitive data items.  The methods for reading can either
75  * read the data into an existing array, or create and return a new array.
76  * These available types are:</p>
77  *
78  * <ul>
79  * <li> {@link #writeBooleanArray(boolean[])},
80  * {@link #readBooleanArray(boolean[])}, {@link #createBooleanArray()}
81  * <li> {@link #writeByteArray(byte[])},
82  * {@link #writeByteArray(byte[], int, int)}, {@link #readByteArray(byte[])},
83  * {@link #createByteArray()}
84  * <li> {@link #writeCharArray(char[])}, {@link #readCharArray(char[])},
85  * {@link #createCharArray()}
86  * <li> {@link #writeDoubleArray(double[])}, {@link #readDoubleArray(double[])},
87  * {@link #createDoubleArray()}
88  * <li> {@link #writeFloatArray(float[])}, {@link #readFloatArray(float[])},
89  * {@link #createFloatArray()}
90  * <li> {@link #writeIntArray(int[])}, {@link #readIntArray(int[])},
91  * {@link #createIntArray()}
92  * <li> {@link #writeLongArray(long[])}, {@link #readLongArray(long[])},
93  * {@link #createLongArray()}
94  * <li> {@link #writeStringArray(String[])}, {@link #readStringArray(String[])},
95  * {@link #createStringArray()}.
96  * <li> {@link #writeSparseBooleanArray(SparseBooleanArray)},
97  * {@link #readSparseBooleanArray()}.
98  * </ul>
99  *
100  * <h3>Parcelables</h3>
101  *
102  * <p>The {@link Parcelable} protocol provides an extremely efficient (but
103  * low-level) protocol for objects to write and read themselves from Parcels.
104  * You can use the direct methods {@link #writeParcelable(Parcelable, int)}
105  * and {@link #readParcelable(ClassLoader)} or
106  * {@link #writeParcelableArray} and
107  * {@link #readParcelableArray(ClassLoader)} to write or read.  These
108  * methods write both the class type and its data to the Parcel, allowing
109  * that class to be reconstructed from the appropriate class loader when
110  * later reading.</p>
111  *
112  * <p>There are also some methods that provide a more efficient way to work
113  * with Parcelables: {@link #writeTypedArray},
114  * {@link #writeTypedList(List)},
115  * {@link #readTypedArray} and {@link #readTypedList}.  These methods
116  * do not write the class information of the original object: instead, the
117  * caller of the read function must know what type to expect and pass in the
118  * appropriate {@link Parcelable.Creator Parcelable.Creator} instead to
119  * properly construct the new object and read its data.  (To more efficient
120  * write and read a single Parceable object, you can directly call
121  * {@link Parcelable#writeToParcel Parcelable.writeToParcel} and
122  * {@link Parcelable.Creator#createFromParcel Parcelable.Creator.createFromParcel}
123  * yourself.)</p>
124  *
125  * <h3>Bundles</h3>
126  *
127  * <p>A special type-safe container, called {@link Bundle}, is available
128  * for key/value maps of heterogeneous values.  This has many optimizations
129  * for improved performance when reading and writing data, and its type-safe
130  * API avoids difficult to debug type errors when finally marshalling the
131  * data contents into a Parcel.  The methods to use are
132  * {@link #writeBundle(Bundle)}, {@link #readBundle()}, and
133  * {@link #readBundle(ClassLoader)}.
134  *
135  * <h3>Active Objects</h3>
136  *
137  * <p>An unusual feature of Parcel is the ability to read and write active
138  * objects.  For these objects the actual contents of the object is not
139  * written, rather a special token referencing the object is written.  When
140  * reading the object back from the Parcel, you do not get a new instance of
141  * the object, but rather a handle that operates on the exact same object that
142  * was originally written.  There are two forms of active objects available.</p>
143  *
144  * <p>{@link Binder} objects are a core facility of Android's general cross-process
145  * communication system.  The {@link IBinder} interface describes an abstract
146  * protocol with a Binder object.  Any such interface can be written in to
147  * a Parcel, and upon reading you will receive either the original object
148  * implementing that interface or a special proxy implementation
149  * that communicates calls back to the original object.  The methods to use are
150  * {@link #writeStrongBinder(IBinder)},
151  * {@link #writeStrongInterface(IInterface)}, {@link #readStrongBinder()},
152  * {@link #writeBinderArray(IBinder[])}, {@link #readBinderArray(IBinder[])},
153  * {@link #createBinderArray()},
154  * {@link #writeBinderList(List)}, {@link #readBinderList(List)},
155  * {@link #createBinderArrayList()}.</p>
156  *
157  * <p>FileDescriptor objects, representing raw Linux file descriptor identifiers,
158  * can be written and {@link ParcelFileDescriptor} objects returned to operate
159  * on the original file descriptor.  The returned file descriptor is a dup
160  * of the original file descriptor: the object and fd is different, but
161  * operating on the same underlying file stream, with the same position, etc.
162  * The methods to use are {@link #writeFileDescriptor(FileDescriptor)},
163  * {@link #readFileDescriptor()}.
164  *
165  * <h3>Untyped Containers</h3>
166  *
167  * <p>A final class of methods are for writing and reading standard Java
168  * containers of arbitrary types.  These all revolve around the
169  * {@link #writeValue(Object)} and {@link #readValue(ClassLoader)} methods
170  * which define the types of objects allowed.  The container methods are
171  * {@link #writeArray(Object[])}, {@link #readArray(ClassLoader)},
172  * {@link #writeList(List)}, {@link #readList(List, ClassLoader)},
173  * {@link #readArrayList(ClassLoader)},
174  * {@link #writeMap(Map)}, {@link #readMap(Map, ClassLoader)},
175  * {@link #writeSparseArray(SparseArray)},
176  * {@link #readSparseArray(ClassLoader)}.
177  */
178 public final class Parcel {
179     private static final boolean DEBUG_RECYCLE = false;
180     private static final String TAG = "Parcel";
181 
182     @SuppressWarnings({"UnusedDeclaration"})
183     private int mObject; // used by native code
184     @SuppressWarnings({"UnusedDeclaration"})
185     private int mOwnObject; // used by native code
186     private RuntimeException mStack;
187 
188     private static final int POOL_SIZE = 6;
189     private static final Parcel[] sOwnedPool = new Parcel[POOL_SIZE];
190     private static final Parcel[] sHolderPool = new Parcel[POOL_SIZE];
191 
192     private static final int VAL_NULL = -1;
193     private static final int VAL_STRING = 0;
194     private static final int VAL_INTEGER = 1;
195     private static final int VAL_MAP = 2;
196     private static final int VAL_BUNDLE = 3;
197     private static final int VAL_PARCELABLE = 4;
198     private static final int VAL_SHORT = 5;
199     private static final int VAL_LONG = 6;
200     private static final int VAL_FLOAT = 7;
201     private static final int VAL_DOUBLE = 8;
202     private static final int VAL_BOOLEAN = 9;
203     private static final int VAL_CHARSEQUENCE = 10;
204     private static final int VAL_LIST  = 11;
205     private static final int VAL_SPARSEARRAY = 12;
206     private static final int VAL_BYTEARRAY = 13;
207     private static final int VAL_STRINGARRAY = 14;
208     private static final int VAL_IBINDER = 15;
209     private static final int VAL_PARCELABLEARRAY = 16;
210     private static final int VAL_OBJECTARRAY = 17;
211     private static final int VAL_INTARRAY = 18;
212     private static final int VAL_LONGARRAY = 19;
213     private static final int VAL_BYTE = 20;
214     private static final int VAL_SERIALIZABLE = 21;
215     private static final int VAL_SPARSEBOOLEANARRAY = 22;
216     private static final int VAL_BOOLEANARRAY = 23;
217     private static final int VAL_CHARSEQUENCEARRAY = 24;
218 
219     // The initial int32 in a Binder call's reply Parcel header:
220     private static final int EX_SECURITY = -1;
221     private static final int EX_BAD_PARCELABLE = -2;
222     private static final int EX_ILLEGAL_ARGUMENT = -3;
223     private static final int EX_NULL_POINTER = -4;
224     private static final int EX_ILLEGAL_STATE = -5;
225     private static final int EX_HAS_REPLY_HEADER = -128;  // special; see below
226 
227     public final static Parcelable.Creator<String> STRING_CREATOR
228              = new Parcelable.Creator<String>() {
229         public String createFromParcel(Parcel source) {
230             return source.readString();
231         }
232         public String[] newArray(int size) {
233             return new String[size];
234         }
235     };
236 
237     /**
238      * Retrieve a new Parcel object from the pool.
239      */
obtain()240     public static Parcel obtain() {
241         final Parcel[] pool = sOwnedPool;
242         synchronized (pool) {
243             Parcel p;
244             for (int i=0; i<POOL_SIZE; i++) {
245                 p = pool[i];
246                 if (p != null) {
247                     pool[i] = null;
248                     if (DEBUG_RECYCLE) {
249                         p.mStack = new RuntimeException();
250                     }
251                     return p;
252                 }
253             }
254         }
255         return new Parcel(0);
256     }
257 
258     /**
259      * Put a Parcel object back into the pool.  You must not touch
260      * the object after this call.
261      */
recycle()262     public final void recycle() {
263         if (DEBUG_RECYCLE) mStack = null;
264         freeBuffer();
265         final Parcel[] pool = mOwnObject != 0 ? sOwnedPool : sHolderPool;
266         synchronized (pool) {
267             for (int i=0; i<POOL_SIZE; i++) {
268                 if (pool[i] == null) {
269                     pool[i] = this;
270                     return;
271                 }
272             }
273         }
274     }
275 
276     /**
277      * Returns the total amount of data contained in the parcel.
278      */
dataSize()279     public final native int dataSize();
280 
281     /**
282      * Returns the amount of data remaining to be read from the
283      * parcel.  That is, {@link #dataSize}-{@link #dataPosition}.
284      */
dataAvail()285     public final native int dataAvail();
286 
287     /**
288      * Returns the current position in the parcel data.  Never
289      * more than {@link #dataSize}.
290      */
dataPosition()291     public final native int dataPosition();
292 
293     /**
294      * Returns the total amount of space in the parcel.  This is always
295      * >= {@link #dataSize}.  The difference between it and dataSize() is the
296      * amount of room left until the parcel needs to re-allocate its
297      * data buffer.
298      */
dataCapacity()299     public final native int dataCapacity();
300 
301     /**
302      * Change the amount of data in the parcel.  Can be either smaller or
303      * larger than the current size.  If larger than the current capacity,
304      * more memory will be allocated.
305      *
306      * @param size The new number of bytes in the Parcel.
307      */
setDataSize(int size)308     public final native void setDataSize(int size);
309 
310     /**
311      * Move the current read/write position in the parcel.
312      * @param pos New offset in the parcel; must be between 0 and
313      * {@link #dataSize}.
314      */
setDataPosition(int pos)315     public final native void setDataPosition(int pos);
316 
317     /**
318      * Change the capacity (current available space) of the parcel.
319      *
320      * @param size The new capacity of the parcel, in bytes.  Can not be
321      * less than {@link #dataSize} -- that is, you can not drop existing data
322      * with this method.
323      */
setDataCapacity(int size)324     public final native void setDataCapacity(int size);
325 
326     /** @hide */
pushAllowFds(boolean allowFds)327     public final native boolean pushAllowFds(boolean allowFds);
328 
329     /** @hide */
restoreAllowFds(boolean lastValue)330     public final native void restoreAllowFds(boolean lastValue);
331 
332     /**
333      * Returns the raw bytes of the parcel.
334      *
335      * <p class="note">The data you retrieve here <strong>must not</strong>
336      * be placed in any kind of persistent storage (on local disk, across
337      * a network, etc).  For that, you should use standard serialization
338      * or another kind of general serialization mechanism.  The Parcel
339      * marshalled representation is highly optimized for local IPC, and as
340      * such does not attempt to maintain compatibility with data created
341      * in different versions of the platform.
342      */
marshall()343     public final native byte[] marshall();
344 
345     /**
346      * Set the bytes in data to be the raw bytes of this Parcel.
347      */
unmarshall(byte[] data, int offest, int length)348     public final native void unmarshall(byte[] data, int offest, int length);
349 
appendFrom(Parcel parcel, int offset, int length)350     public final native void appendFrom(Parcel parcel, int offset, int length);
351 
352     /**
353      * Report whether the parcel contains any marshalled file descriptors.
354      */
hasFileDescriptors()355     public final native boolean hasFileDescriptors();
356 
357     /**
358      * Store or read an IBinder interface token in the parcel at the current
359      * {@link #dataPosition}.  This is used to validate that the marshalled
360      * transaction is intended for the target interface.
361      */
writeInterfaceToken(String interfaceName)362     public final native void writeInterfaceToken(String interfaceName);
enforceInterface(String interfaceName)363     public final native void enforceInterface(String interfaceName);
364 
365     /**
366      * Write a byte array into the parcel at the current {@link #dataPosition},
367      * growing {@link #dataCapacity} if needed.
368      * @param b Bytes to place into the parcel.
369      */
writeByteArray(byte[] b)370     public final void writeByteArray(byte[] b) {
371         writeByteArray(b, 0, (b != null) ? b.length : 0);
372     }
373 
374     /**
375      * Write an byte array into the parcel at the current {@link #dataPosition},
376      * growing {@link #dataCapacity} if needed.
377      * @param b Bytes to place into the parcel.
378      * @param offset Index of first byte to be written.
379      * @param len Number of bytes to write.
380      */
writeByteArray(byte[] b, int offset, int len)381     public final void writeByteArray(byte[] b, int offset, int len) {
382         if (b == null) {
383             writeInt(-1);
384             return;
385         }
386         Arrays.checkOffsetAndCount(b.length, offset, len);
387         writeNative(b, offset, len);
388     }
389 
writeNative(byte[] b, int offset, int len)390     private native void writeNative(byte[] b, int offset, int len);
391 
392     /**
393      * Write an integer value into the parcel at the current dataPosition(),
394      * growing dataCapacity() if needed.
395      */
writeInt(int val)396     public final native void writeInt(int val);
397 
398     /**
399      * Write a long integer value into the parcel at the current dataPosition(),
400      * growing dataCapacity() if needed.
401      */
writeLong(long val)402     public final native void writeLong(long val);
403 
404     /**
405      * Write a floating point value into the parcel at the current
406      * dataPosition(), growing dataCapacity() if needed.
407      */
writeFloat(float val)408     public final native void writeFloat(float val);
409 
410     /**
411      * Write a double precision floating point value into the parcel at the
412      * current dataPosition(), growing dataCapacity() if needed.
413      */
writeDouble(double val)414     public final native void writeDouble(double val);
415 
416     /**
417      * Write a string value into the parcel at the current dataPosition(),
418      * growing dataCapacity() if needed.
419      */
writeString(String val)420     public final native void writeString(String val);
421 
422     /**
423      * Write a CharSequence value into the parcel at the current dataPosition(),
424      * growing dataCapacity() if needed.
425      * @hide
426      */
writeCharSequence(CharSequence val)427     public final void writeCharSequence(CharSequence val) {
428         TextUtils.writeToParcel(val, this, 0);
429     }
430 
431     /**
432      * Write an object into the parcel at the current dataPosition(),
433      * growing dataCapacity() if needed.
434      */
writeStrongBinder(IBinder val)435     public final native void writeStrongBinder(IBinder val);
436 
437     /**
438      * Write an object into the parcel at the current dataPosition(),
439      * growing dataCapacity() if needed.
440      */
writeStrongInterface(IInterface val)441     public final void writeStrongInterface(IInterface val) {
442         writeStrongBinder(val == null ? null : val.asBinder());
443     }
444 
445     /**
446      * Write a FileDescriptor into the parcel at the current dataPosition(),
447      * growing dataCapacity() if needed.
448      *
449      * <p class="caution">The file descriptor will not be closed, which may
450      * result in file descriptor leaks when objects are returned from Binder
451      * calls.  Use {@link ParcelFileDescriptor#writeToParcel} instead, which
452      * accepts contextual flags and will close the original file descriptor
453      * if {@link Parcelable#PARCELABLE_WRITE_RETURN_VALUE} is set.</p>
454      */
writeFileDescriptor(FileDescriptor val)455     public final native void writeFileDescriptor(FileDescriptor val);
456 
457     /**
458      * Write an byte value into the parcel at the current dataPosition(),
459      * growing dataCapacity() if needed.
460      */
writeByte(byte val)461     public final void writeByte(byte val) {
462         writeInt(val);
463     }
464 
465     /**
466      * Please use {@link #writeBundle} instead.  Flattens a Map into the parcel
467      * at the current dataPosition(),
468      * growing dataCapacity() if needed.  The Map keys must be String objects.
469      * The Map values are written using {@link #writeValue} and must follow
470      * the specification there.
471      *
472      * <p>It is strongly recommended to use {@link #writeBundle} instead of
473      * this method, since the Bundle class provides a type-safe API that
474      * allows you to avoid mysterious type errors at the point of marshalling.
475      */
writeMap(Map val)476     public final void writeMap(Map val) {
477         writeMapInternal((Map<String,Object>) val);
478     }
479 
480     /**
481      * Flatten a Map into the parcel at the current dataPosition(),
482      * growing dataCapacity() if needed.  The Map keys must be String objects.
483      */
writeMapInternal(Map<String,Object> val)484     /* package */ void writeMapInternal(Map<String,Object> val) {
485         if (val == null) {
486             writeInt(-1);
487             return;
488         }
489         Set<Map.Entry<String,Object>> entries = val.entrySet();
490         writeInt(entries.size());
491         for (Map.Entry<String,Object> e : entries) {
492             writeValue(e.getKey());
493             writeValue(e.getValue());
494         }
495     }
496 
497     /**
498      * Flatten a Bundle into the parcel at the current dataPosition(),
499      * growing dataCapacity() if needed.
500      */
writeBundle(Bundle val)501     public final void writeBundle(Bundle val) {
502         if (val == null) {
503             writeInt(-1);
504             return;
505         }
506 
507         val.writeToParcel(this, 0);
508     }
509 
510     /**
511      * Flatten a List into the parcel at the current dataPosition(), growing
512      * dataCapacity() if needed.  The List values are written using
513      * {@link #writeValue} and must follow the specification there.
514      */
writeList(List val)515     public final void writeList(List val) {
516         if (val == null) {
517             writeInt(-1);
518             return;
519         }
520         int N = val.size();
521         int i=0;
522         writeInt(N);
523         while (i < N) {
524             writeValue(val.get(i));
525             i++;
526         }
527     }
528 
529     /**
530      * Flatten an Object array into the parcel at the current dataPosition(),
531      * growing dataCapacity() if needed.  The array values are written using
532      * {@link #writeValue} and must follow the specification there.
533      */
writeArray(Object[] val)534     public final void writeArray(Object[] val) {
535         if (val == null) {
536             writeInt(-1);
537             return;
538         }
539         int N = val.length;
540         int i=0;
541         writeInt(N);
542         while (i < N) {
543             writeValue(val[i]);
544             i++;
545         }
546     }
547 
548     /**
549      * Flatten a generic SparseArray into the parcel at the current
550      * dataPosition(), growing dataCapacity() if needed.  The SparseArray
551      * values are written using {@link #writeValue} and must follow the
552      * specification there.
553      */
writeSparseArray(SparseArray<Object> val)554     public final void writeSparseArray(SparseArray<Object> val) {
555         if (val == null) {
556             writeInt(-1);
557             return;
558         }
559         int N = val.size();
560         writeInt(N);
561         int i=0;
562         while (i < N) {
563             writeInt(val.keyAt(i));
564             writeValue(val.valueAt(i));
565             i++;
566         }
567     }
568 
writeSparseBooleanArray(SparseBooleanArray val)569     public final void writeSparseBooleanArray(SparseBooleanArray val) {
570         if (val == null) {
571             writeInt(-1);
572             return;
573         }
574         int N = val.size();
575         writeInt(N);
576         int i=0;
577         while (i < N) {
578             writeInt(val.keyAt(i));
579             writeByte((byte)(val.valueAt(i) ? 1 : 0));
580             i++;
581         }
582     }
583 
writeBooleanArray(boolean[] val)584     public final void writeBooleanArray(boolean[] val) {
585         if (val != null) {
586             int N = val.length;
587             writeInt(N);
588             for (int i=0; i<N; i++) {
589                 writeInt(val[i] ? 1 : 0);
590             }
591         } else {
592             writeInt(-1);
593         }
594     }
595 
createBooleanArray()596     public final boolean[] createBooleanArray() {
597         int N = readInt();
598         // >>2 as a fast divide-by-4 works in the create*Array() functions
599         // because dataAvail() will never return a negative number.  4 is
600         // the size of a stored boolean in the stream.
601         if (N >= 0 && N <= (dataAvail() >> 2)) {
602             boolean[] val = new boolean[N];
603             for (int i=0; i<N; i++) {
604                 val[i] = readInt() != 0;
605             }
606             return val;
607         } else {
608             return null;
609         }
610     }
611 
readBooleanArray(boolean[] val)612     public final void readBooleanArray(boolean[] val) {
613         int N = readInt();
614         if (N == val.length) {
615             for (int i=0; i<N; i++) {
616                 val[i] = readInt() != 0;
617             }
618         } else {
619             throw new RuntimeException("bad array lengths");
620         }
621     }
622 
writeCharArray(char[] val)623     public final void writeCharArray(char[] val) {
624         if (val != null) {
625             int N = val.length;
626             writeInt(N);
627             for (int i=0; i<N; i++) {
628                 writeInt((int)val[i]);
629             }
630         } else {
631             writeInt(-1);
632         }
633     }
634 
createCharArray()635     public final char[] createCharArray() {
636         int N = readInt();
637         if (N >= 0 && N <= (dataAvail() >> 2)) {
638             char[] val = new char[N];
639             for (int i=0; i<N; i++) {
640                 val[i] = (char)readInt();
641             }
642             return val;
643         } else {
644             return null;
645         }
646     }
647 
readCharArray(char[] val)648     public final void readCharArray(char[] val) {
649         int N = readInt();
650         if (N == val.length) {
651             for (int i=0; i<N; i++) {
652                 val[i] = (char)readInt();
653             }
654         } else {
655             throw new RuntimeException("bad array lengths");
656         }
657     }
658 
writeIntArray(int[] val)659     public final void writeIntArray(int[] val) {
660         if (val != null) {
661             int N = val.length;
662             writeInt(N);
663             for (int i=0; i<N; i++) {
664                 writeInt(val[i]);
665             }
666         } else {
667             writeInt(-1);
668         }
669     }
670 
createIntArray()671     public final int[] createIntArray() {
672         int N = readInt();
673         if (N >= 0 && N <= (dataAvail() >> 2)) {
674             int[] val = new int[N];
675             for (int i=0; i<N; i++) {
676                 val[i] = readInt();
677             }
678             return val;
679         } else {
680             return null;
681         }
682     }
683 
readIntArray(int[] val)684     public final void readIntArray(int[] val) {
685         int N = readInt();
686         if (N == val.length) {
687             for (int i=0; i<N; i++) {
688                 val[i] = readInt();
689             }
690         } else {
691             throw new RuntimeException("bad array lengths");
692         }
693     }
694 
writeLongArray(long[] val)695     public final void writeLongArray(long[] val) {
696         if (val != null) {
697             int N = val.length;
698             writeInt(N);
699             for (int i=0; i<N; i++) {
700                 writeLong(val[i]);
701             }
702         } else {
703             writeInt(-1);
704         }
705     }
706 
createLongArray()707     public final long[] createLongArray() {
708         int N = readInt();
709         // >>3 because stored longs are 64 bits
710         if (N >= 0 && N <= (dataAvail() >> 3)) {
711             long[] val = new long[N];
712             for (int i=0; i<N; i++) {
713                 val[i] = readLong();
714             }
715             return val;
716         } else {
717             return null;
718         }
719     }
720 
readLongArray(long[] val)721     public final void readLongArray(long[] val) {
722         int N = readInt();
723         if (N == val.length) {
724             for (int i=0; i<N; i++) {
725                 val[i] = readLong();
726             }
727         } else {
728             throw new RuntimeException("bad array lengths");
729         }
730     }
731 
writeFloatArray(float[] val)732     public final void writeFloatArray(float[] val) {
733         if (val != null) {
734             int N = val.length;
735             writeInt(N);
736             for (int i=0; i<N; i++) {
737                 writeFloat(val[i]);
738             }
739         } else {
740             writeInt(-1);
741         }
742     }
743 
createFloatArray()744     public final float[] createFloatArray() {
745         int N = readInt();
746         // >>2 because stored floats are 4 bytes
747         if (N >= 0 && N <= (dataAvail() >> 2)) {
748             float[] val = new float[N];
749             for (int i=0; i<N; i++) {
750                 val[i] = readFloat();
751             }
752             return val;
753         } else {
754             return null;
755         }
756     }
757 
readFloatArray(float[] val)758     public final void readFloatArray(float[] val) {
759         int N = readInt();
760         if (N == val.length) {
761             for (int i=0; i<N; i++) {
762                 val[i] = readFloat();
763             }
764         } else {
765             throw new RuntimeException("bad array lengths");
766         }
767     }
768 
writeDoubleArray(double[] val)769     public final void writeDoubleArray(double[] val) {
770         if (val != null) {
771             int N = val.length;
772             writeInt(N);
773             for (int i=0; i<N; i++) {
774                 writeDouble(val[i]);
775             }
776         } else {
777             writeInt(-1);
778         }
779     }
780 
createDoubleArray()781     public final double[] createDoubleArray() {
782         int N = readInt();
783         // >>3 because stored doubles are 8 bytes
784         if (N >= 0 && N <= (dataAvail() >> 3)) {
785             double[] val = new double[N];
786             for (int i=0; i<N; i++) {
787                 val[i] = readDouble();
788             }
789             return val;
790         } else {
791             return null;
792         }
793     }
794 
readDoubleArray(double[] val)795     public final void readDoubleArray(double[] val) {
796         int N = readInt();
797         if (N == val.length) {
798             for (int i=0; i<N; i++) {
799                 val[i] = readDouble();
800             }
801         } else {
802             throw new RuntimeException("bad array lengths");
803         }
804     }
805 
writeStringArray(String[] val)806     public final void writeStringArray(String[] val) {
807         if (val != null) {
808             int N = val.length;
809             writeInt(N);
810             for (int i=0; i<N; i++) {
811                 writeString(val[i]);
812             }
813         } else {
814             writeInt(-1);
815         }
816     }
817 
createStringArray()818     public final String[] createStringArray() {
819         int N = readInt();
820         if (N >= 0) {
821             String[] val = new String[N];
822             for (int i=0; i<N; i++) {
823                 val[i] = readString();
824             }
825             return val;
826         } else {
827             return null;
828         }
829     }
830 
readStringArray(String[] val)831     public final void readStringArray(String[] val) {
832         int N = readInt();
833         if (N == val.length) {
834             for (int i=0; i<N; i++) {
835                 val[i] = readString();
836             }
837         } else {
838             throw new RuntimeException("bad array lengths");
839         }
840     }
841 
writeBinderArray(IBinder[] val)842     public final void writeBinderArray(IBinder[] val) {
843         if (val != null) {
844             int N = val.length;
845             writeInt(N);
846             for (int i=0; i<N; i++) {
847                 writeStrongBinder(val[i]);
848             }
849         } else {
850             writeInt(-1);
851         }
852     }
853 
854     /**
855      * @hide
856      */
writeCharSequenceArray(CharSequence[] val)857     public final void writeCharSequenceArray(CharSequence[] val) {
858         if (val != null) {
859             int N = val.length;
860             writeInt(N);
861             for (int i=0; i<N; i++) {
862                 writeCharSequence(val[i]);
863             }
864         } else {
865             writeInt(-1);
866         }
867     }
868 
createBinderArray()869     public final IBinder[] createBinderArray() {
870         int N = readInt();
871         if (N >= 0) {
872             IBinder[] val = new IBinder[N];
873             for (int i=0; i<N; i++) {
874                 val[i] = readStrongBinder();
875             }
876             return val;
877         } else {
878             return null;
879         }
880     }
881 
readBinderArray(IBinder[] val)882     public final void readBinderArray(IBinder[] val) {
883         int N = readInt();
884         if (N == val.length) {
885             for (int i=0; i<N; i++) {
886                 val[i] = readStrongBinder();
887             }
888         } else {
889             throw new RuntimeException("bad array lengths");
890         }
891     }
892 
893     /**
894      * Flatten a List containing a particular object type into the parcel, at
895      * the current dataPosition() and growing dataCapacity() if needed.  The
896      * type of the objects in the list must be one that implements Parcelable.
897      * Unlike the generic writeList() method, however, only the raw data of the
898      * objects is written and not their type, so you must use the corresponding
899      * readTypedList() to unmarshall them.
900      *
901      * @param val The list of objects to be written.
902      *
903      * @see #createTypedArrayList
904      * @see #readTypedList
905      * @see Parcelable
906      */
writeTypedList(List<T> val)907     public final <T extends Parcelable> void writeTypedList(List<T> val) {
908         if (val == null) {
909             writeInt(-1);
910             return;
911         }
912         int N = val.size();
913         int i=0;
914         writeInt(N);
915         while (i < N) {
916             T item = val.get(i);
917             if (item != null) {
918                 writeInt(1);
919                 item.writeToParcel(this, 0);
920             } else {
921                 writeInt(0);
922             }
923             i++;
924         }
925     }
926 
927     /**
928      * Flatten a List containing String objects into the parcel, at
929      * the current dataPosition() and growing dataCapacity() if needed.  They
930      * can later be retrieved with {@link #createStringArrayList} or
931      * {@link #readStringList}.
932      *
933      * @param val The list of strings to be written.
934      *
935      * @see #createStringArrayList
936      * @see #readStringList
937      */
writeStringList(List<String> val)938     public final void writeStringList(List<String> val) {
939         if (val == null) {
940             writeInt(-1);
941             return;
942         }
943         int N = val.size();
944         int i=0;
945         writeInt(N);
946         while (i < N) {
947             writeString(val.get(i));
948             i++;
949         }
950     }
951 
952     /**
953      * Flatten a List containing IBinder objects into the parcel, at
954      * the current dataPosition() and growing dataCapacity() if needed.  They
955      * can later be retrieved with {@link #createBinderArrayList} or
956      * {@link #readBinderList}.
957      *
958      * @param val The list of strings to be written.
959      *
960      * @see #createBinderArrayList
961      * @see #readBinderList
962      */
writeBinderList(List<IBinder> val)963     public final void writeBinderList(List<IBinder> val) {
964         if (val == null) {
965             writeInt(-1);
966             return;
967         }
968         int N = val.size();
969         int i=0;
970         writeInt(N);
971         while (i < N) {
972             writeStrongBinder(val.get(i));
973             i++;
974         }
975     }
976 
977     /**
978      * Flatten a heterogeneous array containing a particular object type into
979      * the parcel, at
980      * the current dataPosition() and growing dataCapacity() if needed.  The
981      * type of the objects in the array must be one that implements Parcelable.
982      * Unlike the {@link #writeParcelableArray} method, however, only the
983      * raw data of the objects is written and not their type, so you must use
984      * {@link #readTypedArray} with the correct corresponding
985      * {@link Parcelable.Creator} implementation to unmarshall them.
986      *
987      * @param val The array of objects to be written.
988      * @param parcelableFlags Contextual flags as per
989      * {@link Parcelable#writeToParcel(Parcel, int) Parcelable.writeToParcel()}.
990      *
991      * @see #readTypedArray
992      * @see #writeParcelableArray
993      * @see Parcelable.Creator
994      */
writeTypedArray(T[] val, int parcelableFlags)995     public final <T extends Parcelable> void writeTypedArray(T[] val,
996             int parcelableFlags) {
997         if (val != null) {
998             int N = val.length;
999             writeInt(N);
1000             for (int i=0; i<N; i++) {
1001                 T item = val[i];
1002                 if (item != null) {
1003                     writeInt(1);
1004                     item.writeToParcel(this, parcelableFlags);
1005                 } else {
1006                     writeInt(0);
1007                 }
1008             }
1009         } else {
1010             writeInt(-1);
1011         }
1012     }
1013 
1014     /**
1015      * Flatten a generic object in to a parcel.  The given Object value may
1016      * currently be one of the following types:
1017      *
1018      * <ul>
1019      * <li> null
1020      * <li> String
1021      * <li> Byte
1022      * <li> Short
1023      * <li> Integer
1024      * <li> Long
1025      * <li> Float
1026      * <li> Double
1027      * <li> Boolean
1028      * <li> String[]
1029      * <li> boolean[]
1030      * <li> byte[]
1031      * <li> int[]
1032      * <li> long[]
1033      * <li> Object[] (supporting objects of the same type defined here).
1034      * <li> {@link Bundle}
1035      * <li> Map (as supported by {@link #writeMap}).
1036      * <li> Any object that implements the {@link Parcelable} protocol.
1037      * <li> Parcelable[]
1038      * <li> CharSequence (as supported by {@link TextUtils#writeToParcel}).
1039      * <li> List (as supported by {@link #writeList}).
1040      * <li> {@link SparseArray} (as supported by {@link #writeSparseArray(SparseArray)}).
1041      * <li> {@link IBinder}
1042      * <li> Any object that implements Serializable (but see
1043      *      {@link #writeSerializable} for caveats).  Note that all of the
1044      *      previous types have relatively efficient implementations for
1045      *      writing to a Parcel; having to rely on the generic serialization
1046      *      approach is much less efficient and should be avoided whenever
1047      *      possible.
1048      * </ul>
1049      *
1050      * <p class="caution">{@link Parcelable} objects are written with
1051      * {@link Parcelable#writeToParcel} using contextual flags of 0.  When
1052      * serializing objects containing {@link ParcelFileDescriptor}s,
1053      * this may result in file descriptor leaks when they are returned from
1054      * Binder calls (where {@link Parcelable#PARCELABLE_WRITE_RETURN_VALUE}
1055      * should be used).</p>
1056      */
writeValue(Object v)1057     public final void writeValue(Object v) {
1058         if (v == null) {
1059             writeInt(VAL_NULL);
1060         } else if (v instanceof String) {
1061             writeInt(VAL_STRING);
1062             writeString((String) v);
1063         } else if (v instanceof Integer) {
1064             writeInt(VAL_INTEGER);
1065             writeInt((Integer) v);
1066         } else if (v instanceof Map) {
1067             writeInt(VAL_MAP);
1068             writeMap((Map) v);
1069         } else if (v instanceof Bundle) {
1070             // Must be before Parcelable
1071             writeInt(VAL_BUNDLE);
1072             writeBundle((Bundle) v);
1073         } else if (v instanceof Parcelable) {
1074             writeInt(VAL_PARCELABLE);
1075             writeParcelable((Parcelable) v, 0);
1076         } else if (v instanceof Short) {
1077             writeInt(VAL_SHORT);
1078             writeInt(((Short) v).intValue());
1079         } else if (v instanceof Long) {
1080             writeInt(VAL_LONG);
1081             writeLong((Long) v);
1082         } else if (v instanceof Float) {
1083             writeInt(VAL_FLOAT);
1084             writeFloat((Float) v);
1085         } else if (v instanceof Double) {
1086             writeInt(VAL_DOUBLE);
1087             writeDouble((Double) v);
1088         } else if (v instanceof Boolean) {
1089             writeInt(VAL_BOOLEAN);
1090             writeInt((Boolean) v ? 1 : 0);
1091         } else if (v instanceof CharSequence) {
1092             // Must be after String
1093             writeInt(VAL_CHARSEQUENCE);
1094             writeCharSequence((CharSequence) v);
1095         } else if (v instanceof List) {
1096             writeInt(VAL_LIST);
1097             writeList((List) v);
1098         } else if (v instanceof SparseArray) {
1099             writeInt(VAL_SPARSEARRAY);
1100             writeSparseArray((SparseArray) v);
1101         } else if (v instanceof boolean[]) {
1102             writeInt(VAL_BOOLEANARRAY);
1103             writeBooleanArray((boolean[]) v);
1104         } else if (v instanceof byte[]) {
1105             writeInt(VAL_BYTEARRAY);
1106             writeByteArray((byte[]) v);
1107         } else if (v instanceof String[]) {
1108             writeInt(VAL_STRINGARRAY);
1109             writeStringArray((String[]) v);
1110         } else if (v instanceof CharSequence[]) {
1111             // Must be after String[] and before Object[]
1112             writeInt(VAL_CHARSEQUENCEARRAY);
1113             writeCharSequenceArray((CharSequence[]) v);
1114         } else if (v instanceof IBinder) {
1115             writeInt(VAL_IBINDER);
1116             writeStrongBinder((IBinder) v);
1117         } else if (v instanceof Parcelable[]) {
1118             writeInt(VAL_PARCELABLEARRAY);
1119             writeParcelableArray((Parcelable[]) v, 0);
1120         } else if (v instanceof Object[]) {
1121             writeInt(VAL_OBJECTARRAY);
1122             writeArray((Object[]) v);
1123         } else if (v instanceof int[]) {
1124             writeInt(VAL_INTARRAY);
1125             writeIntArray((int[]) v);
1126         } else if (v instanceof long[]) {
1127             writeInt(VAL_LONGARRAY);
1128             writeLongArray((long[]) v);
1129         } else if (v instanceof Byte) {
1130             writeInt(VAL_BYTE);
1131             writeInt((Byte) v);
1132         } else if (v instanceof Serializable) {
1133             // Must be last
1134             writeInt(VAL_SERIALIZABLE);
1135             writeSerializable((Serializable) v);
1136         } else {
1137             throw new RuntimeException("Parcel: unable to marshal value " + v);
1138         }
1139     }
1140 
1141     /**
1142      * Flatten the name of the class of the Parcelable and its contents
1143      * into the parcel.
1144      *
1145      * @param p The Parcelable object to be written.
1146      * @param parcelableFlags Contextual flags as per
1147      * {@link Parcelable#writeToParcel(Parcel, int) Parcelable.writeToParcel()}.
1148      */
writeParcelable(Parcelable p, int parcelableFlags)1149     public final void writeParcelable(Parcelable p, int parcelableFlags) {
1150         if (p == null) {
1151             writeString(null);
1152             return;
1153         }
1154         String name = p.getClass().getName();
1155         writeString(name);
1156         p.writeToParcel(this, parcelableFlags);
1157     }
1158 
1159     /**
1160      * Write a generic serializable object in to a Parcel.  It is strongly
1161      * recommended that this method be avoided, since the serialization
1162      * overhead is extremely large, and this approach will be much slower than
1163      * using the other approaches to writing data in to a Parcel.
1164      */
writeSerializable(Serializable s)1165     public final void writeSerializable(Serializable s) {
1166         if (s == null) {
1167             writeString(null);
1168             return;
1169         }
1170         String name = s.getClass().getName();
1171         writeString(name);
1172 
1173         ByteArrayOutputStream baos = new ByteArrayOutputStream();
1174         try {
1175             ObjectOutputStream oos = new ObjectOutputStream(baos);
1176             oos.writeObject(s);
1177             oos.close();
1178 
1179             writeByteArray(baos.toByteArray());
1180         } catch (IOException ioe) {
1181             throw new RuntimeException("Parcelable encountered " +
1182                 "IOException writing serializable object (name = " + name +
1183                 ")", ioe);
1184         }
1185     }
1186 
1187     /**
1188      * Special function for writing an exception result at the header of
1189      * a parcel, to be used when returning an exception from a transaction.
1190      * Note that this currently only supports a few exception types; any other
1191      * exception will be re-thrown by this function as a RuntimeException
1192      * (to be caught by the system's last-resort exception handling when
1193      * dispatching a transaction).
1194      *
1195      * <p>The supported exception types are:
1196      * <ul>
1197      * <li>{@link BadParcelableException}
1198      * <li>{@link IllegalArgumentException}
1199      * <li>{@link IllegalStateException}
1200      * <li>{@link NullPointerException}
1201      * <li>{@link SecurityException}
1202      * </ul>
1203      *
1204      * @param e The Exception to be written.
1205      *
1206      * @see #writeNoException
1207      * @see #readException
1208      */
writeException(Exception e)1209     public final void writeException(Exception e) {
1210         int code = 0;
1211         if (e instanceof SecurityException) {
1212             code = EX_SECURITY;
1213         } else if (e instanceof BadParcelableException) {
1214             code = EX_BAD_PARCELABLE;
1215         } else if (e instanceof IllegalArgumentException) {
1216             code = EX_ILLEGAL_ARGUMENT;
1217         } else if (e instanceof NullPointerException) {
1218             code = EX_NULL_POINTER;
1219         } else if (e instanceof IllegalStateException) {
1220             code = EX_ILLEGAL_STATE;
1221         }
1222         writeInt(code);
1223         StrictMode.clearGatheredViolations();
1224         if (code == 0) {
1225             if (e instanceof RuntimeException) {
1226                 throw (RuntimeException) e;
1227             }
1228             throw new RuntimeException(e);
1229         }
1230         writeString(e.getMessage());
1231     }
1232 
1233     /**
1234      * Special function for writing information at the front of the Parcel
1235      * indicating that no exception occurred.
1236      *
1237      * @see #writeException
1238      * @see #readException
1239      */
writeNoException()1240     public final void writeNoException() {
1241         // Despite the name of this function ("write no exception"),
1242         // it should instead be thought of as "write the RPC response
1243         // header", but because this function name is written out by
1244         // the AIDL compiler, we're not going to rename it.
1245         //
1246         // The response header, in the non-exception case (see also
1247         // writeException above, also called by the AIDL compiler), is
1248         // either a 0 (the default case), or EX_HAS_REPLY_HEADER if
1249         // StrictMode has gathered up violations that have occurred
1250         // during a Binder call, in which case we write out the number
1251         // of violations and their details, serialized, before the
1252         // actual RPC respons data.  The receiving end of this is
1253         // readException(), below.
1254         if (StrictMode.hasGatheredViolations()) {
1255             writeInt(EX_HAS_REPLY_HEADER);
1256             final int sizePosition = dataPosition();
1257             writeInt(0);  // total size of fat header, to be filled in later
1258             StrictMode.writeGatheredViolationsToParcel(this);
1259             final int payloadPosition = dataPosition();
1260             setDataPosition(sizePosition);
1261             writeInt(payloadPosition - sizePosition);  // header size
1262             setDataPosition(payloadPosition);
1263         } else {
1264             writeInt(0);
1265         }
1266     }
1267 
1268     /**
1269      * Special function for reading an exception result from the header of
1270      * a parcel, to be used after receiving the result of a transaction.  This
1271      * will throw the exception for you if it had been written to the Parcel,
1272      * otherwise return and let you read the normal result data from the Parcel.
1273      *
1274      * @see #writeException
1275      * @see #writeNoException
1276      */
readException()1277     public final void readException() {
1278         int code = readExceptionCode();
1279         if (code != 0) {
1280             String msg = readString();
1281             readException(code, msg);
1282         }
1283     }
1284 
1285     /**
1286      * Parses the header of a Binder call's response Parcel and
1287      * returns the exception code.  Deals with lite or fat headers.
1288      * In the common successful case, this header is generally zero.
1289      * In less common cases, it's a small negative number and will be
1290      * followed by an error string.
1291      *
1292      * This exists purely for android.database.DatabaseUtils and
1293      * insulating it from having to handle fat headers as returned by
1294      * e.g. StrictMode-induced RPC responses.
1295      *
1296      * @hide
1297      */
readExceptionCode()1298     public final int readExceptionCode() {
1299         int code = readInt();
1300         if (code == EX_HAS_REPLY_HEADER) {
1301             int headerSize = readInt();
1302             if (headerSize == 0) {
1303                 Log.e(TAG, "Unexpected zero-sized Parcel reply header.");
1304             } else {
1305                 // Currently the only thing in the header is StrictMode stacks,
1306                 // but discussions around event/RPC tracing suggest we might
1307                 // put that here too.  If so, switch on sub-header tags here.
1308                 // But for now, just parse out the StrictMode stuff.
1309                 StrictMode.readAndHandleBinderCallViolations(this);
1310             }
1311             // And fat response headers are currently only used when
1312             // there are no exceptions, so return no error:
1313             return 0;
1314         }
1315         return code;
1316     }
1317 
1318     /**
1319      * Use this function for customized exception handling.
1320      * customized method call this method for all unknown case
1321      * @param code exception code
1322      * @param msg exception message
1323      */
readException(int code, String msg)1324     public final void readException(int code, String msg) {
1325         switch (code) {
1326             case EX_SECURITY:
1327                 throw new SecurityException(msg);
1328             case EX_BAD_PARCELABLE:
1329                 throw new BadParcelableException(msg);
1330             case EX_ILLEGAL_ARGUMENT:
1331                 throw new IllegalArgumentException(msg);
1332             case EX_NULL_POINTER:
1333                 throw new NullPointerException(msg);
1334             case EX_ILLEGAL_STATE:
1335                 throw new IllegalStateException(msg);
1336         }
1337         throw new RuntimeException("Unknown exception code: " + code
1338                 + " msg " + msg);
1339     }
1340 
1341     /**
1342      * Read an integer value from the parcel at the current dataPosition().
1343      */
readInt()1344     public final native int readInt();
1345 
1346     /**
1347      * Read a long integer value from the parcel at the current dataPosition().
1348      */
readLong()1349     public final native long readLong();
1350 
1351     /**
1352      * Read a floating point value from the parcel at the current
1353      * dataPosition().
1354      */
readFloat()1355     public final native float readFloat();
1356 
1357     /**
1358      * Read a double precision floating point value from the parcel at the
1359      * current dataPosition().
1360      */
readDouble()1361     public final native double readDouble();
1362 
1363     /**
1364      * Read a string value from the parcel at the current dataPosition().
1365      */
readString()1366     public final native String readString();
1367 
1368     /**
1369      * Read a CharSequence value from the parcel at the current dataPosition().
1370      * @hide
1371      */
readCharSequence()1372     public final CharSequence readCharSequence() {
1373         return TextUtils.CHAR_SEQUENCE_CREATOR.createFromParcel(this);
1374     }
1375 
1376     /**
1377      * Read an object from the parcel at the current dataPosition().
1378      */
readStrongBinder()1379     public final native IBinder readStrongBinder();
1380 
1381     /**
1382      * Read a FileDescriptor from the parcel at the current dataPosition().
1383      */
readFileDescriptor()1384     public final ParcelFileDescriptor readFileDescriptor() {
1385         FileDescriptor fd = internalReadFileDescriptor();
1386         return fd != null ? new ParcelFileDescriptor(fd) : null;
1387     }
1388 
internalReadFileDescriptor()1389     private native FileDescriptor internalReadFileDescriptor();
openFileDescriptor(String file, int mode)1390     /*package*/ static native FileDescriptor openFileDescriptor(String file,
1391             int mode) throws FileNotFoundException;
dupFileDescriptor(FileDescriptor orig)1392     /*package*/ static native FileDescriptor dupFileDescriptor(FileDescriptor orig)
1393             throws IOException;
closeFileDescriptor(FileDescriptor desc)1394     /*package*/ static native void closeFileDescriptor(FileDescriptor desc)
1395             throws IOException;
clearFileDescriptor(FileDescriptor desc)1396     /*package*/ static native void clearFileDescriptor(FileDescriptor desc);
1397 
1398     /**
1399      * Read a byte value from the parcel at the current dataPosition().
1400      */
readByte()1401     public final byte readByte() {
1402         return (byte)(readInt() & 0xff);
1403     }
1404 
1405     /**
1406      * Please use {@link #readBundle(ClassLoader)} instead (whose data must have
1407      * been written with {@link #writeBundle}.  Read into an existing Map object
1408      * from the parcel at the current dataPosition().
1409      */
readMap(Map outVal, ClassLoader loader)1410     public final void readMap(Map outVal, ClassLoader loader) {
1411         int N = readInt();
1412         readMapInternal(outVal, N, loader);
1413     }
1414 
1415     /**
1416      * Read into an existing List object from the parcel at the current
1417      * dataPosition(), using the given class loader to load any enclosed
1418      * Parcelables.  If it is null, the default class loader is used.
1419      */
readList(List outVal, ClassLoader loader)1420     public final void readList(List outVal, ClassLoader loader) {
1421         int N = readInt();
1422         readListInternal(outVal, N, loader);
1423     }
1424 
1425     /**
1426      * Please use {@link #readBundle(ClassLoader)} instead (whose data must have
1427      * been written with {@link #writeBundle}.  Read and return a new HashMap
1428      * object from the parcel at the current dataPosition(), using the given
1429      * class loader to load any enclosed Parcelables.  Returns null if
1430      * the previously written map object was null.
1431      */
readHashMap(ClassLoader loader)1432     public final HashMap readHashMap(ClassLoader loader)
1433     {
1434         int N = readInt();
1435         if (N < 0) {
1436             return null;
1437         }
1438         HashMap m = new HashMap(N);
1439         readMapInternal(m, N, loader);
1440         return m;
1441     }
1442 
1443     /**
1444      * Read and return a new Bundle object from the parcel at the current
1445      * dataPosition().  Returns null if the previously written Bundle object was
1446      * null.
1447      */
readBundle()1448     public final Bundle readBundle() {
1449         return readBundle(null);
1450     }
1451 
1452     /**
1453      * Read and return a new Bundle object from the parcel at the current
1454      * dataPosition(), using the given class loader to initialize the class
1455      * loader of the Bundle for later retrieval of Parcelable objects.
1456      * Returns null if the previously written Bundle object was null.
1457      */
readBundle(ClassLoader loader)1458     public final Bundle readBundle(ClassLoader loader) {
1459         int length = readInt();
1460         if (length < 0) {
1461             return null;
1462         }
1463 
1464         final Bundle bundle = new Bundle(this, length);
1465         if (loader != null) {
1466             bundle.setClassLoader(loader);
1467         }
1468         return bundle;
1469     }
1470 
1471     /**
1472      * Read and return a byte[] object from the parcel.
1473      */
createByteArray()1474     public final native byte[] createByteArray();
1475 
1476     /**
1477      * Read a byte[] object from the parcel and copy it into the
1478      * given byte array.
1479      */
readByteArray(byte[] val)1480     public final void readByteArray(byte[] val) {
1481         // TODO: make this a native method to avoid the extra copy.
1482         byte[] ba = createByteArray();
1483         if (ba.length == val.length) {
1484            System.arraycopy(ba, 0, val, 0, ba.length);
1485         } else {
1486             throw new RuntimeException("bad array lengths");
1487         }
1488     }
1489 
1490     /**
1491      * Read and return a String[] object from the parcel.
1492      * {@hide}
1493      */
readStringArray()1494     public final String[] readStringArray() {
1495         String[] array = null;
1496 
1497         int length = readInt();
1498         if (length >= 0)
1499         {
1500             array = new String[length];
1501 
1502             for (int i = 0 ; i < length ; i++)
1503             {
1504                 array[i] = readString();
1505             }
1506         }
1507 
1508         return array;
1509     }
1510 
1511     /**
1512      * Read and return a CharSequence[] object from the parcel.
1513      * {@hide}
1514      */
readCharSequenceArray()1515     public final CharSequence[] readCharSequenceArray() {
1516         CharSequence[] array = null;
1517 
1518         int length = readInt();
1519         if (length >= 0)
1520         {
1521             array = new CharSequence[length];
1522 
1523             for (int i = 0 ; i < length ; i++)
1524             {
1525                 array[i] = readCharSequence();
1526             }
1527         }
1528 
1529         return array;
1530     }
1531 
1532     /**
1533      * Read and return a new ArrayList object from the parcel at the current
1534      * dataPosition().  Returns null if the previously written list object was
1535      * null.  The given class loader will be used to load any enclosed
1536      * Parcelables.
1537      */
readArrayList(ClassLoader loader)1538     public final ArrayList readArrayList(ClassLoader loader) {
1539         int N = readInt();
1540         if (N < 0) {
1541             return null;
1542         }
1543         ArrayList l = new ArrayList(N);
1544         readListInternal(l, N, loader);
1545         return l;
1546     }
1547 
1548     /**
1549      * Read and return a new Object array from the parcel at the current
1550      * dataPosition().  Returns null if the previously written array was
1551      * null.  The given class loader will be used to load any enclosed
1552      * Parcelables.
1553      */
readArray(ClassLoader loader)1554     public final Object[] readArray(ClassLoader loader) {
1555         int N = readInt();
1556         if (N < 0) {
1557             return null;
1558         }
1559         Object[] l = new Object[N];
1560         readArrayInternal(l, N, loader);
1561         return l;
1562     }
1563 
1564     /**
1565      * Read and return a new SparseArray object from the parcel at the current
1566      * dataPosition().  Returns null if the previously written list object was
1567      * null.  The given class loader will be used to load any enclosed
1568      * Parcelables.
1569      */
readSparseArray(ClassLoader loader)1570     public final SparseArray readSparseArray(ClassLoader loader) {
1571         int N = readInt();
1572         if (N < 0) {
1573             return null;
1574         }
1575         SparseArray sa = new SparseArray(N);
1576         readSparseArrayInternal(sa, N, loader);
1577         return sa;
1578     }
1579 
1580     /**
1581      * Read and return a new SparseBooleanArray object from the parcel at the current
1582      * dataPosition().  Returns null if the previously written list object was
1583      * null.
1584      */
readSparseBooleanArray()1585     public final SparseBooleanArray readSparseBooleanArray() {
1586         int N = readInt();
1587         if (N < 0) {
1588             return null;
1589         }
1590         SparseBooleanArray sa = new SparseBooleanArray(N);
1591         readSparseBooleanArrayInternal(sa, N);
1592         return sa;
1593     }
1594 
1595     /**
1596      * Read and return a new ArrayList containing a particular object type from
1597      * the parcel that was written with {@link #writeTypedList} at the
1598      * current dataPosition().  Returns null if the
1599      * previously written list object was null.  The list <em>must</em> have
1600      * previously been written via {@link #writeTypedList} with the same object
1601      * type.
1602      *
1603      * @return A newly created ArrayList containing objects with the same data
1604      *         as those that were previously written.
1605      *
1606      * @see #writeTypedList
1607      */
createTypedArrayList(Parcelable.Creator<T> c)1608     public final <T> ArrayList<T> createTypedArrayList(Parcelable.Creator<T> c) {
1609         int N = readInt();
1610         if (N < 0) {
1611             return null;
1612         }
1613         ArrayList<T> l = new ArrayList<T>(N);
1614         while (N > 0) {
1615             if (readInt() != 0) {
1616                 l.add(c.createFromParcel(this));
1617             } else {
1618                 l.add(null);
1619             }
1620             N--;
1621         }
1622         return l;
1623     }
1624 
1625     /**
1626      * Read into the given List items containing a particular object type
1627      * that were written with {@link #writeTypedList} at the
1628      * current dataPosition().  The list <em>must</em> have
1629      * previously been written via {@link #writeTypedList} with the same object
1630      * type.
1631      *
1632      * @return A newly created ArrayList containing objects with the same data
1633      *         as those that were previously written.
1634      *
1635      * @see #writeTypedList
1636      */
readTypedList(List<T> list, Parcelable.Creator<T> c)1637     public final <T> void readTypedList(List<T> list, Parcelable.Creator<T> c) {
1638         int M = list.size();
1639         int N = readInt();
1640         int i = 0;
1641         for (; i < M && i < N; i++) {
1642             if (readInt() != 0) {
1643                 list.set(i, c.createFromParcel(this));
1644             } else {
1645                 list.set(i, null);
1646             }
1647         }
1648         for (; i<N; i++) {
1649             if (readInt() != 0) {
1650                 list.add(c.createFromParcel(this));
1651             } else {
1652                 list.add(null);
1653             }
1654         }
1655         for (; i<M; i++) {
1656             list.remove(N);
1657         }
1658     }
1659 
1660     /**
1661      * Read and return a new ArrayList containing String objects from
1662      * the parcel that was written with {@link #writeStringList} at the
1663      * current dataPosition().  Returns null if the
1664      * previously written list object was null.
1665      *
1666      * @return A newly created ArrayList containing strings with the same data
1667      *         as those that were previously written.
1668      *
1669      * @see #writeStringList
1670      */
createStringArrayList()1671     public final ArrayList<String> createStringArrayList() {
1672         int N = readInt();
1673         if (N < 0) {
1674             return null;
1675         }
1676         ArrayList<String> l = new ArrayList<String>(N);
1677         while (N > 0) {
1678             l.add(readString());
1679             N--;
1680         }
1681         return l;
1682     }
1683 
1684     /**
1685      * Read and return a new ArrayList containing IBinder objects from
1686      * the parcel that was written with {@link #writeBinderList} at the
1687      * current dataPosition().  Returns null if the
1688      * previously written list object was null.
1689      *
1690      * @return A newly created ArrayList containing strings with the same data
1691      *         as those that were previously written.
1692      *
1693      * @see #writeBinderList
1694      */
createBinderArrayList()1695     public final ArrayList<IBinder> createBinderArrayList() {
1696         int N = readInt();
1697         if (N < 0) {
1698             return null;
1699         }
1700         ArrayList<IBinder> l = new ArrayList<IBinder>(N);
1701         while (N > 0) {
1702             l.add(readStrongBinder());
1703             N--;
1704         }
1705         return l;
1706     }
1707 
1708     /**
1709      * Read into the given List items String objects that were written with
1710      * {@link #writeStringList} at the current dataPosition().
1711      *
1712      * @return A newly created ArrayList containing strings with the same data
1713      *         as those that were previously written.
1714      *
1715      * @see #writeStringList
1716      */
readStringList(List<String> list)1717     public final void readStringList(List<String> list) {
1718         int M = list.size();
1719         int N = readInt();
1720         int i = 0;
1721         for (; i < M && i < N; i++) {
1722             list.set(i, readString());
1723         }
1724         for (; i<N; i++) {
1725             list.add(readString());
1726         }
1727         for (; i<M; i++) {
1728             list.remove(N);
1729         }
1730     }
1731 
1732     /**
1733      * Read into the given List items IBinder objects that were written with
1734      * {@link #writeBinderList} at the current dataPosition().
1735      *
1736      * @return A newly created ArrayList containing strings with the same data
1737      *         as those that were previously written.
1738      *
1739      * @see #writeBinderList
1740      */
readBinderList(List<IBinder> list)1741     public final void readBinderList(List<IBinder> list) {
1742         int M = list.size();
1743         int N = readInt();
1744         int i = 0;
1745         for (; i < M && i < N; i++) {
1746             list.set(i, readStrongBinder());
1747         }
1748         for (; i<N; i++) {
1749             list.add(readStrongBinder());
1750         }
1751         for (; i<M; i++) {
1752             list.remove(N);
1753         }
1754     }
1755 
1756     /**
1757      * Read and return a new array containing a particular object type from
1758      * the parcel at the current dataPosition().  Returns null if the
1759      * previously written array was null.  The array <em>must</em> have
1760      * previously been written via {@link #writeTypedArray} with the same
1761      * object type.
1762      *
1763      * @return A newly created array containing objects with the same data
1764      *         as those that were previously written.
1765      *
1766      * @see #writeTypedArray
1767      */
createTypedArray(Parcelable.Creator<T> c)1768     public final <T> T[] createTypedArray(Parcelable.Creator<T> c) {
1769         int N = readInt();
1770         if (N < 0) {
1771             return null;
1772         }
1773         T[] l = c.newArray(N);
1774         for (int i=0; i<N; i++) {
1775             if (readInt() != 0) {
1776                 l[i] = c.createFromParcel(this);
1777             }
1778         }
1779         return l;
1780     }
1781 
readTypedArray(T[] val, Parcelable.Creator<T> c)1782     public final <T> void readTypedArray(T[] val, Parcelable.Creator<T> c) {
1783         int N = readInt();
1784         if (N == val.length) {
1785             for (int i=0; i<N; i++) {
1786                 if (readInt() != 0) {
1787                     val[i] = c.createFromParcel(this);
1788                 } else {
1789                     val[i] = null;
1790                 }
1791             }
1792         } else {
1793             throw new RuntimeException("bad array lengths");
1794         }
1795     }
1796 
1797     /**
1798      * @deprecated
1799      * @hide
1800      */
1801     @Deprecated
readTypedArray(Parcelable.Creator<T> c)1802     public final <T> T[] readTypedArray(Parcelable.Creator<T> c) {
1803         return createTypedArray(c);
1804     }
1805 
1806     /**
1807      * Write a heterogeneous array of Parcelable objects into the Parcel.
1808      * Each object in the array is written along with its class name, so
1809      * that the correct class can later be instantiated.  As a result, this
1810      * has significantly more overhead than {@link #writeTypedArray}, but will
1811      * correctly handle an array containing more than one type of object.
1812      *
1813      * @param value The array of objects to be written.
1814      * @param parcelableFlags Contextual flags as per
1815      * {@link Parcelable#writeToParcel(Parcel, int) Parcelable.writeToParcel()}.
1816      *
1817      * @see #writeTypedArray
1818      */
writeParcelableArray(T[] value, int parcelableFlags)1819     public final <T extends Parcelable> void writeParcelableArray(T[] value,
1820             int parcelableFlags) {
1821         if (value != null) {
1822             int N = value.length;
1823             writeInt(N);
1824             for (int i=0; i<N; i++) {
1825                 writeParcelable(value[i], parcelableFlags);
1826             }
1827         } else {
1828             writeInt(-1);
1829         }
1830     }
1831 
1832     /**
1833      * Read a typed object from a parcel.  The given class loader will be
1834      * used to load any enclosed Parcelables.  If it is null, the default class
1835      * loader will be used.
1836      */
readValue(ClassLoader loader)1837     public final Object readValue(ClassLoader loader) {
1838         int type = readInt();
1839 
1840         switch (type) {
1841         case VAL_NULL:
1842             return null;
1843 
1844         case VAL_STRING:
1845             return readString();
1846 
1847         case VAL_INTEGER:
1848             return readInt();
1849 
1850         case VAL_MAP:
1851             return readHashMap(loader);
1852 
1853         case VAL_PARCELABLE:
1854             return readParcelable(loader);
1855 
1856         case VAL_SHORT:
1857             return (short) readInt();
1858 
1859         case VAL_LONG:
1860             return readLong();
1861 
1862         case VAL_FLOAT:
1863             return readFloat();
1864 
1865         case VAL_DOUBLE:
1866             return readDouble();
1867 
1868         case VAL_BOOLEAN:
1869             return readInt() == 1;
1870 
1871         case VAL_CHARSEQUENCE:
1872             return readCharSequence();
1873 
1874         case VAL_LIST:
1875             return readArrayList(loader);
1876 
1877         case VAL_BOOLEANARRAY:
1878             return createBooleanArray();
1879 
1880         case VAL_BYTEARRAY:
1881             return createByteArray();
1882 
1883         case VAL_STRINGARRAY:
1884             return readStringArray();
1885 
1886         case VAL_CHARSEQUENCEARRAY:
1887             return readCharSequenceArray();
1888 
1889         case VAL_IBINDER:
1890             return readStrongBinder();
1891 
1892         case VAL_OBJECTARRAY:
1893             return readArray(loader);
1894 
1895         case VAL_INTARRAY:
1896             return createIntArray();
1897 
1898         case VAL_LONGARRAY:
1899             return createLongArray();
1900 
1901         case VAL_BYTE:
1902             return readByte();
1903 
1904         case VAL_SERIALIZABLE:
1905             return readSerializable();
1906 
1907         case VAL_PARCELABLEARRAY:
1908             return readParcelableArray(loader);
1909 
1910         case VAL_SPARSEARRAY:
1911             return readSparseArray(loader);
1912 
1913         case VAL_SPARSEBOOLEANARRAY:
1914             return readSparseBooleanArray();
1915 
1916         case VAL_BUNDLE:
1917             return readBundle(loader); // loading will be deferred
1918 
1919         default:
1920             int off = dataPosition() - 4;
1921             throw new RuntimeException(
1922                 "Parcel " + this + ": Unmarshalling unknown type code " + type + " at offset " + off);
1923         }
1924     }
1925 
1926     /**
1927      * Read and return a new Parcelable from the parcel.  The given class loader
1928      * will be used to load any enclosed Parcelables.  If it is null, the default
1929      * class loader will be used.
1930      * @param loader A ClassLoader from which to instantiate the Parcelable
1931      * object, or null for the default class loader.
1932      * @return Returns the newly created Parcelable, or null if a null
1933      * object has been written.
1934      * @throws BadParcelableException Throws BadParcelableException if there
1935      * was an error trying to instantiate the Parcelable.
1936      */
readParcelable(ClassLoader loader)1937     public final <T extends Parcelable> T readParcelable(ClassLoader loader) {
1938         String name = readString();
1939         if (name == null) {
1940             return null;
1941         }
1942         Parcelable.Creator<T> creator;
1943         synchronized (mCreators) {
1944             HashMap<String,Parcelable.Creator> map = mCreators.get(loader);
1945             if (map == null) {
1946                 map = new HashMap<String,Parcelable.Creator>();
1947                 mCreators.put(loader, map);
1948             }
1949             creator = map.get(name);
1950             if (creator == null) {
1951                 try {
1952                     Class c = loader == null ?
1953                         Class.forName(name) : Class.forName(name, true, loader);
1954                     Field f = c.getField("CREATOR");
1955                     creator = (Parcelable.Creator)f.get(null);
1956                 }
1957                 catch (IllegalAccessException e) {
1958                     Log.e(TAG, "Class not found when unmarshalling: "
1959                                         + name + ", e: " + e);
1960                     throw new BadParcelableException(
1961                             "IllegalAccessException when unmarshalling: " + name);
1962                 }
1963                 catch (ClassNotFoundException e) {
1964                     Log.e(TAG, "Class not found when unmarshalling: "
1965                                         + name + ", e: " + e);
1966                     throw new BadParcelableException(
1967                             "ClassNotFoundException when unmarshalling: " + name);
1968                 }
1969                 catch (ClassCastException e) {
1970                     throw new BadParcelableException("Parcelable protocol requires a "
1971                                         + "Parcelable.Creator object called "
1972                                         + " CREATOR on class " + name);
1973                 }
1974                 catch (NoSuchFieldException e) {
1975                     throw new BadParcelableException("Parcelable protocol requires a "
1976                                         + "Parcelable.Creator object called "
1977                                         + " CREATOR on class " + name);
1978                 }
1979                 if (creator == null) {
1980                     throw new BadParcelableException("Parcelable protocol requires a "
1981                                         + "Parcelable.Creator object called "
1982                                         + " CREATOR on class " + name);
1983                 }
1984 
1985                 map.put(name, creator);
1986             }
1987         }
1988 
1989         if (creator instanceof Parcelable.ClassLoaderCreator<?>) {
1990             return ((Parcelable.ClassLoaderCreator<T>)creator).createFromParcel(this, loader);
1991         }
1992         return creator.createFromParcel(this);
1993     }
1994 
1995     /**
1996      * Read and return a new Parcelable array from the parcel.
1997      * The given class loader will be used to load any enclosed
1998      * Parcelables.
1999      * @return the Parcelable array, or null if the array is null
2000      */
readParcelableArray(ClassLoader loader)2001     public final Parcelable[] readParcelableArray(ClassLoader loader) {
2002         int N = readInt();
2003         if (N < 0) {
2004             return null;
2005         }
2006         Parcelable[] p = new Parcelable[N];
2007         for (int i = 0; i < N; i++) {
2008             p[i] = (Parcelable) readParcelable(loader);
2009         }
2010         return p;
2011     }
2012 
2013     /**
2014      * Read and return a new Serializable object from the parcel.
2015      * @return the Serializable object, or null if the Serializable name
2016      * wasn't found in the parcel.
2017      */
readSerializable()2018     public final Serializable readSerializable() {
2019         String name = readString();
2020         if (name == null) {
2021             // For some reason we were unable to read the name of the Serializable (either there
2022             // is nothing left in the Parcel to read, or the next value wasn't a String), so
2023             // return null, which indicates that the name wasn't found in the parcel.
2024             return null;
2025         }
2026 
2027         byte[] serializedData = createByteArray();
2028         ByteArrayInputStream bais = new ByteArrayInputStream(serializedData);
2029         try {
2030             ObjectInputStream ois = new ObjectInputStream(bais);
2031             return (Serializable) ois.readObject();
2032         } catch (IOException ioe) {
2033             throw new RuntimeException("Parcelable encountered " +
2034                 "IOException reading a Serializable object (name = " + name +
2035                 ")", ioe);
2036         } catch (ClassNotFoundException cnfe) {
2037             throw new RuntimeException("Parcelable encountered" +
2038                 "ClassNotFoundException reading a Serializable object (name = "
2039                 + name + ")", cnfe);
2040         }
2041     }
2042 
2043     // Cache of previously looked up CREATOR.createFromParcel() methods for
2044     // particular classes.  Keys are the names of the classes, values are
2045     // Method objects.
2046     private static final HashMap<ClassLoader,HashMap<String,Parcelable.Creator>>
2047         mCreators = new HashMap<ClassLoader,HashMap<String,Parcelable.Creator>>();
2048 
obtain(int obj)2049     static protected final Parcel obtain(int obj) {
2050         final Parcel[] pool = sHolderPool;
2051         synchronized (pool) {
2052             Parcel p;
2053             for (int i=0; i<POOL_SIZE; i++) {
2054                 p = pool[i];
2055                 if (p != null) {
2056                     pool[i] = null;
2057                     if (DEBUG_RECYCLE) {
2058                         p.mStack = new RuntimeException();
2059                     }
2060                     p.init(obj);
2061                     return p;
2062                 }
2063             }
2064         }
2065         return new Parcel(obj);
2066     }
2067 
Parcel(int obj)2068     private Parcel(int obj) {
2069         if (DEBUG_RECYCLE) {
2070             mStack = new RuntimeException();
2071         }
2072         //Log.i(TAG, "Initializing obj=0x" + Integer.toHexString(obj), mStack);
2073         init(obj);
2074     }
2075 
2076     @Override
finalize()2077     protected void finalize() throws Throwable {
2078         if (DEBUG_RECYCLE) {
2079             if (mStack != null) {
2080                 Log.w(TAG, "Client did not call Parcel.recycle()", mStack);
2081             }
2082         }
2083         destroy();
2084     }
2085 
freeBuffer()2086     private native void freeBuffer();
init(int obj)2087     private native void init(int obj);
destroy()2088     private native void destroy();
2089 
readMapInternal(Map outVal, int N, ClassLoader loader)2090     /* package */ void readMapInternal(Map outVal, int N,
2091         ClassLoader loader) {
2092         while (N > 0) {
2093             Object key = readValue(loader);
2094             Object value = readValue(loader);
2095             outVal.put(key, value);
2096             N--;
2097         }
2098     }
2099 
readListInternal(List outVal, int N, ClassLoader loader)2100     private void readListInternal(List outVal, int N,
2101         ClassLoader loader) {
2102         while (N > 0) {
2103             Object value = readValue(loader);
2104             //Log.d(TAG, "Unmarshalling value=" + value);
2105             outVal.add(value);
2106             N--;
2107         }
2108     }
2109 
readArrayInternal(Object[] outVal, int N, ClassLoader loader)2110     private void readArrayInternal(Object[] outVal, int N,
2111         ClassLoader loader) {
2112         for (int i = 0; i < N; i++) {
2113             Object value = readValue(loader);
2114             //Log.d(TAG, "Unmarshalling value=" + value);
2115             outVal[i] = value;
2116         }
2117     }
2118 
readSparseArrayInternal(SparseArray outVal, int N, ClassLoader loader)2119     private void readSparseArrayInternal(SparseArray outVal, int N,
2120         ClassLoader loader) {
2121         while (N > 0) {
2122             int key = readInt();
2123             Object value = readValue(loader);
2124             //Log.i(TAG, "Unmarshalling key=" + key + " value=" + value);
2125             outVal.append(key, value);
2126             N--;
2127         }
2128     }
2129 
2130 
readSparseBooleanArrayInternal(SparseBooleanArray outVal, int N)2131     private void readSparseBooleanArrayInternal(SparseBooleanArray outVal, int N) {
2132         while (N > 0) {
2133             int key = readInt();
2134             boolean value = this.readByte() == 1;
2135             //Log.i(TAG, "Unmarshalling key=" + key + " value=" + value);
2136             outVal.append(key, value);
2137             N--;
2138         }
2139     }
2140 }
2141