blob: 26312475297c3681b01b6c09b0ee516064ddec27 [file] [log] [blame]
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001/*
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
17package android.os;
18
Adrian Roos04505652015-10-22 16:12:01 -070019import android.annotation.IntegerRes;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080020import android.text.TextUtils;
Dianne Hackbornb87655b2013-07-17 19:06:22 -070021import android.util.ArrayMap;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080022import android.util.Log;
Jeff Sharkey5ef33982014-09-04 18:13:39 -070023import android.util.Size;
24import android.util.SizeF;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080025import android.util.SparseArray;
26import android.util.SparseBooleanArray;
27
28import java.io.ByteArrayInputStream;
29import java.io.ByteArrayOutputStream;
30import java.io.FileDescriptor;
31import java.io.FileNotFoundException;
32import java.io.IOException;
33import java.io.ObjectInputStream;
34import java.io.ObjectOutputStream;
John Spurlock5002b8c2014-01-10 13:32:12 -050035import java.io.ObjectStreamClass;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080036import java.io.Serializable;
37import java.lang.reflect.Field;
Neil Fuller44e440c2015-04-20 14:39:00 +010038import java.lang.reflect.Modifier;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080039import java.util.ArrayList;
Elliott Hughesa28b83e2011-02-28 14:26:13 -080040import java.util.Arrays;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080041import java.util.HashMap;
42import java.util.List;
43import java.util.Map;
44import java.util.Set;
45
Adrian Roos04505652015-10-22 16:12:01 -070046import dalvik.system.VMRuntime;
47
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080048/**
49 * Container for a message (data and object references) that can
50 * be sent through an IBinder. A Parcel can contain both flattened data
51 * that will be unflattened on the other side of the IPC (using the various
52 * methods here for writing specific types, or the general
53 * {@link Parcelable} interface), and references to live {@link IBinder}
54 * objects that will result in the other side receiving a proxy IBinder
55 * connected with the original IBinder in the Parcel.
56 *
57 * <p class="note">Parcel is <strong>not</strong> a general-purpose
58 * serialization mechanism. This class (and the corresponding
59 * {@link Parcelable} API for placing arbitrary objects into a Parcel) is
60 * designed as a high-performance IPC transport. As such, it is not
61 * appropriate to place any Parcel data in to persistent storage: changes
62 * in the underlying implementation of any of the data in the Parcel can
63 * render older data unreadable.</p>
Samuel Tana8036662015-11-23 14:36:00 -080064 *
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080065 * <p>The bulk of the Parcel API revolves around reading and writing data
66 * of various types. There are six major classes of such functions available.</p>
Samuel Tana8036662015-11-23 14:36:00 -080067 *
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080068 * <h3>Primitives</h3>
Samuel Tana8036662015-11-23 14:36:00 -080069 *
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080070 * <p>The most basic data functions are for writing and reading primitive
71 * data types: {@link #writeByte}, {@link #readByte}, {@link #writeDouble},
72 * {@link #readDouble}, {@link #writeFloat}, {@link #readFloat}, {@link #writeInt},
73 * {@link #readInt}, {@link #writeLong}, {@link #readLong},
74 * {@link #writeString}, {@link #readString}. Most other
75 * data operations are built on top of these. The given data is written and
76 * read using the endianess of the host CPU.</p>
Samuel Tana8036662015-11-23 14:36:00 -080077 *
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080078 * <h3>Primitive Arrays</h3>
Samuel Tana8036662015-11-23 14:36:00 -080079 *
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080080 * <p>There are a variety of methods for reading and writing raw arrays
81 * of primitive objects, which generally result in writing a 4-byte length
82 * followed by the primitive data items. The methods for reading can either
83 * read the data into an existing array, or create and return a new array.
84 * These available types are:</p>
Samuel Tana8036662015-11-23 14:36:00 -080085 *
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080086 * <ul>
87 * <li> {@link #writeBooleanArray(boolean[])},
88 * {@link #readBooleanArray(boolean[])}, {@link #createBooleanArray()}
89 * <li> {@link #writeByteArray(byte[])},
90 * {@link #writeByteArray(byte[], int, int)}, {@link #readByteArray(byte[])},
91 * {@link #createByteArray()}
92 * <li> {@link #writeCharArray(char[])}, {@link #readCharArray(char[])},
93 * {@link #createCharArray()}
94 * <li> {@link #writeDoubleArray(double[])}, {@link #readDoubleArray(double[])},
95 * {@link #createDoubleArray()}
96 * <li> {@link #writeFloatArray(float[])}, {@link #readFloatArray(float[])},
97 * {@link #createFloatArray()}
98 * <li> {@link #writeIntArray(int[])}, {@link #readIntArray(int[])},
99 * {@link #createIntArray()}
100 * <li> {@link #writeLongArray(long[])}, {@link #readLongArray(long[])},
101 * {@link #createLongArray()}
102 * <li> {@link #writeStringArray(String[])}, {@link #readStringArray(String[])},
103 * {@link #createStringArray()}.
104 * <li> {@link #writeSparseBooleanArray(SparseBooleanArray)},
105 * {@link #readSparseBooleanArray()}.
106 * </ul>
Samuel Tana8036662015-11-23 14:36:00 -0800107 *
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800108 * <h3>Parcelables</h3>
Samuel Tana8036662015-11-23 14:36:00 -0800109 *
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800110 * <p>The {@link Parcelable} protocol provides an extremely efficient (but
111 * low-level) protocol for objects to write and read themselves from Parcels.
112 * You can use the direct methods {@link #writeParcelable(Parcelable, int)}
113 * and {@link #readParcelable(ClassLoader)} or
114 * {@link #writeParcelableArray} and
115 * {@link #readParcelableArray(ClassLoader)} to write or read. These
116 * methods write both the class type and its data to the Parcel, allowing
117 * that class to be reconstructed from the appropriate class loader when
118 * later reading.</p>
Samuel Tana8036662015-11-23 14:36:00 -0800119 *
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800120 * <p>There are also some methods that provide a more efficient way to work
Jens Ole Lauridsen8dea8742015-04-20 11:18:51 -0700121 * with Parcelables: {@link #writeTypedObject}, {@link #writeTypedArray},
122 * {@link #writeTypedList}, {@link #readTypedObject},
123 * {@link #createTypedArray} and {@link #createTypedArrayList}. These methods
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800124 * do not write the class information of the original object: instead, the
125 * caller of the read function must know what type to expect and pass in the
126 * appropriate {@link Parcelable.Creator Parcelable.Creator} instead to
127 * properly construct the new object and read its data. (To more efficient
Jens Ole Lauridsen8dea8742015-04-20 11:18:51 -0700128 * write and read a single Parceable object that is not null, you can directly
129 * call {@link Parcelable#writeToParcel Parcelable.writeToParcel} and
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800130 * {@link Parcelable.Creator#createFromParcel Parcelable.Creator.createFromParcel}
131 * yourself.)</p>
Samuel Tana8036662015-11-23 14:36:00 -0800132 *
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800133 * <h3>Bundles</h3>
Samuel Tana8036662015-11-23 14:36:00 -0800134 *
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800135 * <p>A special type-safe container, called {@link Bundle}, is available
136 * for key/value maps of heterogeneous values. This has many optimizations
137 * for improved performance when reading and writing data, and its type-safe
138 * API avoids difficult to debug type errors when finally marshalling the
139 * data contents into a Parcel. The methods to use are
140 * {@link #writeBundle(Bundle)}, {@link #readBundle()}, and
141 * {@link #readBundle(ClassLoader)}.
Samuel Tana8036662015-11-23 14:36:00 -0800142 *
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800143 * <h3>Active Objects</h3>
Samuel Tana8036662015-11-23 14:36:00 -0800144 *
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800145 * <p>An unusual feature of Parcel is the ability to read and write active
146 * objects. For these objects the actual contents of the object is not
147 * written, rather a special token referencing the object is written. When
148 * reading the object back from the Parcel, you do not get a new instance of
149 * the object, but rather a handle that operates on the exact same object that
150 * was originally written. There are two forms of active objects available.</p>
Samuel Tana8036662015-11-23 14:36:00 -0800151 *
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800152 * <p>{@link Binder} objects are a core facility of Android's general cross-process
153 * communication system. The {@link IBinder} interface describes an abstract
154 * protocol with a Binder object. Any such interface can be written in to
155 * a Parcel, and upon reading you will receive either the original object
156 * implementing that interface or a special proxy implementation
157 * that communicates calls back to the original object. The methods to use are
158 * {@link #writeStrongBinder(IBinder)},
159 * {@link #writeStrongInterface(IInterface)}, {@link #readStrongBinder()},
160 * {@link #writeBinderArray(IBinder[])}, {@link #readBinderArray(IBinder[])},
161 * {@link #createBinderArray()},
162 * {@link #writeBinderList(List)}, {@link #readBinderList(List)},
163 * {@link #createBinderArrayList()}.</p>
Samuel Tana8036662015-11-23 14:36:00 -0800164 *
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800165 * <p>FileDescriptor objects, representing raw Linux file descriptor identifiers,
166 * can be written and {@link ParcelFileDescriptor} objects returned to operate
167 * on the original file descriptor. The returned file descriptor is a dup
168 * of the original file descriptor: the object and fd is different, but
169 * operating on the same underlying file stream, with the same position, etc.
170 * The methods to use are {@link #writeFileDescriptor(FileDescriptor)},
171 * {@link #readFileDescriptor()}.
Samuel Tana8036662015-11-23 14:36:00 -0800172 *
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800173 * <h3>Untyped Containers</h3>
Samuel Tana8036662015-11-23 14:36:00 -0800174 *
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800175 * <p>A final class of methods are for writing and reading standard Java
176 * containers of arbitrary types. These all revolve around the
177 * {@link #writeValue(Object)} and {@link #readValue(ClassLoader)} methods
178 * which define the types of objects allowed. The container methods are
179 * {@link #writeArray(Object[])}, {@link #readArray(ClassLoader)},
180 * {@link #writeList(List)}, {@link #readList(List, ClassLoader)},
181 * {@link #readArrayList(ClassLoader)},
182 * {@link #writeMap(Map)}, {@link #readMap(Map, ClassLoader)},
183 * {@link #writeSparseArray(SparseArray)},
184 * {@link #readSparseArray(ClassLoader)}.
185 */
186public final class Parcel {
187 private static final boolean DEBUG_RECYCLE = false;
Dianne Hackborne784d1e2013-09-20 18:13:52 -0700188 private static final boolean DEBUG_ARRAY_MAP = false;
Brad Fitzpatrick5b747192010-07-12 11:05:38 -0700189 private static final String TAG = "Parcel";
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800190
191 @SuppressWarnings({"UnusedDeclaration"})
Ashok Bhat8ab665d2014-01-22 16:00:20 +0000192 private long mNativePtr; // used by native code
Jeff Sharkey047238c2012-03-07 16:51:38 -0800193
194 /**
195 * Flag indicating if {@link #mNativePtr} was allocated by this object,
196 * indicating that we're responsible for its lifecycle.
197 */
198 private boolean mOwnsNativeParcelObject;
Adrian Roos04505652015-10-22 16:12:01 -0700199 private long mNativeSize;
Jeff Sharkey047238c2012-03-07 16:51:38 -0800200
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800201 private RuntimeException mStack;
202
203 private static final int POOL_SIZE = 6;
204 private static final Parcel[] sOwnedPool = new Parcel[POOL_SIZE];
205 private static final Parcel[] sHolderPool = new Parcel[POOL_SIZE];
206
Samuel Tan3cefe6a2015-12-14 13:29:17 -0800207 // Keep in sync with frameworks/native/libs/binder/PersistableBundle.cpp.
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800208 private static final int VAL_NULL = -1;
209 private static final int VAL_STRING = 0;
210 private static final int VAL_INTEGER = 1;
211 private static final int VAL_MAP = 2;
212 private static final int VAL_BUNDLE = 3;
213 private static final int VAL_PARCELABLE = 4;
214 private static final int VAL_SHORT = 5;
215 private static final int VAL_LONG = 6;
216 private static final int VAL_FLOAT = 7;
217 private static final int VAL_DOUBLE = 8;
218 private static final int VAL_BOOLEAN = 9;
219 private static final int VAL_CHARSEQUENCE = 10;
220 private static final int VAL_LIST = 11;
221 private static final int VAL_SPARSEARRAY = 12;
222 private static final int VAL_BYTEARRAY = 13;
223 private static final int VAL_STRINGARRAY = 14;
224 private static final int VAL_IBINDER = 15;
225 private static final int VAL_PARCELABLEARRAY = 16;
226 private static final int VAL_OBJECTARRAY = 17;
227 private static final int VAL_INTARRAY = 18;
228 private static final int VAL_LONGARRAY = 19;
229 private static final int VAL_BYTE = 20;
230 private static final int VAL_SERIALIZABLE = 21;
231 private static final int VAL_SPARSEBOOLEANARRAY = 22;
232 private static final int VAL_BOOLEANARRAY = 23;
Bjorn Bringert08bbffb2010-02-25 11:16:22 +0000233 private static final int VAL_CHARSEQUENCEARRAY = 24;
Craig Mautner719e6b12014-04-04 20:29:41 -0700234 private static final int VAL_PERSISTABLEBUNDLE = 25;
Jeff Sharkey5ef33982014-09-04 18:13:39 -0700235 private static final int VAL_SIZE = 26;
236 private static final int VAL_SIZEF = 27;
Samuel Tana8036662015-11-23 14:36:00 -0800237 private static final int VAL_DOUBLEARRAY = 28;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800238
Brad Fitzpatrick5b747192010-07-12 11:05:38 -0700239 // The initial int32 in a Binder call's reply Parcel header:
Christopher Wiley80fd1202015-11-22 17:12:37 -0800240 // Keep these in sync with libbinder's binder/Status.h.
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800241 private static final int EX_SECURITY = -1;
242 private static final int EX_BAD_PARCELABLE = -2;
243 private static final int EX_ILLEGAL_ARGUMENT = -3;
244 private static final int EX_NULL_POINTER = -4;
245 private static final int EX_ILLEGAL_STATE = -5;
Dianne Hackborn7e714422013-09-13 17:32:57 -0700246 private static final int EX_NETWORK_MAIN_THREAD = -6;
Dianne Hackborn33d738a2014-09-12 14:23:58 -0700247 private static final int EX_UNSUPPORTED_OPERATION = -7;
Christopher Wiley80fd1202015-11-22 17:12:37 -0800248 private static final int EX_SERVICE_SPECIFIC = -8;
Brad Fitzpatrick5b747192010-07-12 11:05:38 -0700249 private static final int EX_HAS_REPLY_HEADER = -128; // special; see below
Christopher Wiley80fd1202015-11-22 17:12:37 -0800250 // EX_TRANSACTION_FAILED is used exclusively in native code.
251 // see libbinder's binder/Status.h
252 private static final int EX_TRANSACTION_FAILED = -129;
Brad Fitzpatrick5b747192010-07-12 11:05:38 -0700253
Ashok Bhat8ab665d2014-01-22 16:00:20 +0000254 private static native int nativeDataSize(long nativePtr);
255 private static native int nativeDataAvail(long nativePtr);
256 private static native int nativeDataPosition(long nativePtr);
257 private static native int nativeDataCapacity(long nativePtr);
Adrian Roos04505652015-10-22 16:12:01 -0700258 private static native long nativeSetDataSize(long nativePtr, int size);
Ashok Bhat8ab665d2014-01-22 16:00:20 +0000259 private static native void nativeSetDataPosition(long nativePtr, int pos);
260 private static native void nativeSetDataCapacity(long nativePtr, int size);
Jeff Sharkey047238c2012-03-07 16:51:38 -0800261
Ashok Bhat8ab665d2014-01-22 16:00:20 +0000262 private static native boolean nativePushAllowFds(long nativePtr, boolean allowFds);
263 private static native void nativeRestoreAllowFds(long nativePtr, boolean lastValue);
Jeff Sharkey047238c2012-03-07 16:51:38 -0800264
Ashok Bhat8ab665d2014-01-22 16:00:20 +0000265 private static native void nativeWriteByteArray(long nativePtr, byte[] b, int offset, int len);
Sandeep Siddhartha90d7a3e2014-07-25 16:19:42 -0700266 private static native void nativeWriteBlob(long nativePtr, byte[] b, int offset, int len);
Ashok Bhat8ab665d2014-01-22 16:00:20 +0000267 private static native void nativeWriteInt(long nativePtr, int val);
268 private static native void nativeWriteLong(long nativePtr, long val);
269 private static native void nativeWriteFloat(long nativePtr, float val);
270 private static native void nativeWriteDouble(long nativePtr, double val);
271 private static native void nativeWriteString(long nativePtr, String val);
272 private static native void nativeWriteStrongBinder(long nativePtr, IBinder val);
Adrian Roos04505652015-10-22 16:12:01 -0700273 private static native long nativeWriteFileDescriptor(long nativePtr, FileDescriptor val);
Jeff Sharkey047238c2012-03-07 16:51:38 -0800274
Ashok Bhat8ab665d2014-01-22 16:00:20 +0000275 private static native byte[] nativeCreateByteArray(long nativePtr);
Sandeep Siddhartha90d7a3e2014-07-25 16:19:42 -0700276 private static native byte[] nativeReadBlob(long nativePtr);
Ashok Bhat8ab665d2014-01-22 16:00:20 +0000277 private static native int nativeReadInt(long nativePtr);
278 private static native long nativeReadLong(long nativePtr);
279 private static native float nativeReadFloat(long nativePtr);
280 private static native double nativeReadDouble(long nativePtr);
281 private static native String nativeReadString(long nativePtr);
282 private static native IBinder nativeReadStrongBinder(long nativePtr);
283 private static native FileDescriptor nativeReadFileDescriptor(long nativePtr);
Jeff Sharkey047238c2012-03-07 16:51:38 -0800284
Ashok Bhat8ab665d2014-01-22 16:00:20 +0000285 private static native long nativeCreate();
Adrian Roos04505652015-10-22 16:12:01 -0700286 private static native long nativeFreeBuffer(long nativePtr);
Ashok Bhat8ab665d2014-01-22 16:00:20 +0000287 private static native void nativeDestroy(long nativePtr);
Jeff Sharkey047238c2012-03-07 16:51:38 -0800288
Ashok Bhat8ab665d2014-01-22 16:00:20 +0000289 private static native byte[] nativeMarshall(long nativePtr);
Adrian Roos04505652015-10-22 16:12:01 -0700290 private static native long nativeUnmarshall(
John Spurlocke0852362015-02-04 15:47:40 -0500291 long nativePtr, byte[] data, int offset, int length);
Adrian Roos04505652015-10-22 16:12:01 -0700292 private static native long nativeAppendFrom(
Ashok Bhat8ab665d2014-01-22 16:00:20 +0000293 long thisNativePtr, long otherNativePtr, int offset, int length);
294 private static native boolean nativeHasFileDescriptors(long nativePtr);
295 private static native void nativeWriteInterfaceToken(long nativePtr, String interfaceName);
296 private static native void nativeEnforceInterface(long nativePtr, String interfaceName);
Jeff Sharkey047238c2012-03-07 16:51:38 -0800297
Dan Sandleraa861662015-04-21 10:24:32 -0400298 private static native long nativeGetBlobAshmemSize(long nativePtr);
Dan Sandler5ce04302015-04-09 23:50:15 -0400299
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800300 public final static Parcelable.Creator<String> STRING_CREATOR
301 = new Parcelable.Creator<String>() {
302 public String createFromParcel(Parcel source) {
303 return source.readString();
304 }
305 public String[] newArray(int size) {
306 return new String[size];
307 }
308 };
309
310 /**
311 * Retrieve a new Parcel object from the pool.
312 */
313 public static Parcel obtain() {
314 final Parcel[] pool = sOwnedPool;
315 synchronized (pool) {
316 Parcel p;
317 for (int i=0; i<POOL_SIZE; i++) {
318 p = pool[i];
319 if (p != null) {
320 pool[i] = null;
321 if (DEBUG_RECYCLE) {
322 p.mStack = new RuntimeException();
323 }
324 return p;
325 }
326 }
327 }
328 return new Parcel(0);
329 }
330
331 /**
332 * Put a Parcel object back into the pool. You must not touch
333 * the object after this call.
334 */
335 public final void recycle() {
336 if (DEBUG_RECYCLE) mStack = null;
337 freeBuffer();
Jeff Sharkey047238c2012-03-07 16:51:38 -0800338
339 final Parcel[] pool;
340 if (mOwnsNativeParcelObject) {
341 pool = sOwnedPool;
342 } else {
343 mNativePtr = 0;
344 pool = sHolderPool;
345 }
346
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800347 synchronized (pool) {
348 for (int i=0; i<POOL_SIZE; i++) {
349 if (pool[i] == null) {
350 pool[i] = this;
351 return;
352 }
353 }
354 }
355 }
356
Dianne Hackbornfabb70b2014-11-11 12:22:36 -0800357 /** @hide */
358 public static native long getGlobalAllocSize();
359
360 /** @hide */
361 public static native long getGlobalAllocCount();
362
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800363 /**
364 * Returns the total amount of data contained in the parcel.
365 */
Jeff Sharkey047238c2012-03-07 16:51:38 -0800366 public final int dataSize() {
367 return nativeDataSize(mNativePtr);
368 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800369
370 /**
371 * Returns the amount of data remaining to be read from the
372 * parcel. That is, {@link #dataSize}-{@link #dataPosition}.
373 */
Jeff Sharkey047238c2012-03-07 16:51:38 -0800374 public final int dataAvail() {
375 return nativeDataAvail(mNativePtr);
376 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800377
378 /**
379 * Returns the current position in the parcel data. Never
380 * more than {@link #dataSize}.
381 */
Jeff Sharkey047238c2012-03-07 16:51:38 -0800382 public final int dataPosition() {
383 return nativeDataPosition(mNativePtr);
384 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800385
386 /**
387 * Returns the total amount of space in the parcel. This is always
388 * >= {@link #dataSize}. The difference between it and dataSize() is the
389 * amount of room left until the parcel needs to re-allocate its
390 * data buffer.
391 */
Jeff Sharkey047238c2012-03-07 16:51:38 -0800392 public final int dataCapacity() {
393 return nativeDataCapacity(mNativePtr);
394 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800395
396 /**
397 * Change the amount of data in the parcel. Can be either smaller or
398 * larger than the current size. If larger than the current capacity,
399 * more memory will be allocated.
400 *
401 * @param size The new number of bytes in the Parcel.
402 */
Jeff Sharkey047238c2012-03-07 16:51:38 -0800403 public final void setDataSize(int size) {
Adrian Roos04505652015-10-22 16:12:01 -0700404 updateNativeSize(nativeSetDataSize(mNativePtr, size));
Jeff Sharkey047238c2012-03-07 16:51:38 -0800405 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800406
407 /**
408 * Move the current read/write position in the parcel.
409 * @param pos New offset in the parcel; must be between 0 and
410 * {@link #dataSize}.
411 */
Jeff Sharkey047238c2012-03-07 16:51:38 -0800412 public final void setDataPosition(int pos) {
413 nativeSetDataPosition(mNativePtr, pos);
414 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800415
416 /**
417 * Change the capacity (current available space) of the parcel.
418 *
419 * @param size The new capacity of the parcel, in bytes. Can not be
420 * less than {@link #dataSize} -- that is, you can not drop existing data
421 * with this method.
422 */
Jeff Sharkey047238c2012-03-07 16:51:38 -0800423 public final void setDataCapacity(int size) {
424 nativeSetDataCapacity(mNativePtr, size);
425 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800426
Dianne Hackborn9ecebbf2011-09-28 23:19:47 -0400427 /** @hide */
Jeff Sharkey047238c2012-03-07 16:51:38 -0800428 public final boolean pushAllowFds(boolean allowFds) {
429 return nativePushAllowFds(mNativePtr, allowFds);
430 }
Dianne Hackbornc04db7e2011-10-03 21:09:35 -0700431
432 /** @hide */
Jeff Sharkey047238c2012-03-07 16:51:38 -0800433 public final void restoreAllowFds(boolean lastValue) {
434 nativeRestoreAllowFds(mNativePtr, lastValue);
435 }
Dianne Hackborn9ecebbf2011-09-28 23:19:47 -0400436
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800437 /**
438 * Returns the raw bytes of the parcel.
439 *
440 * <p class="note">The data you retrieve here <strong>must not</strong>
441 * be placed in any kind of persistent storage (on local disk, across
442 * a network, etc). For that, you should use standard serialization
443 * or another kind of general serialization mechanism. The Parcel
444 * marshalled representation is highly optimized for local IPC, and as
445 * such does not attempt to maintain compatibility with data created
446 * in different versions of the platform.
447 */
Jeff Sharkey047238c2012-03-07 16:51:38 -0800448 public final byte[] marshall() {
449 return nativeMarshall(mNativePtr);
450 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800451
452 /**
453 * Set the bytes in data to be the raw bytes of this Parcel.
454 */
John Spurlocke0852362015-02-04 15:47:40 -0500455 public final void unmarshall(byte[] data, int offset, int length) {
Adrian Roos04505652015-10-22 16:12:01 -0700456 updateNativeSize(nativeUnmarshall(mNativePtr, data, offset, length));
Jeff Sharkey047238c2012-03-07 16:51:38 -0800457 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800458
Jeff Sharkey047238c2012-03-07 16:51:38 -0800459 public final void appendFrom(Parcel parcel, int offset, int length) {
Adrian Roos04505652015-10-22 16:12:01 -0700460 updateNativeSize(nativeAppendFrom(mNativePtr, parcel.mNativePtr, offset, length));
Jeff Sharkey047238c2012-03-07 16:51:38 -0800461 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800462
463 /**
464 * Report whether the parcel contains any marshalled file descriptors.
465 */
Jeff Sharkey047238c2012-03-07 16:51:38 -0800466 public final boolean hasFileDescriptors() {
467 return nativeHasFileDescriptors(mNativePtr);
468 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800469
470 /**
471 * Store or read an IBinder interface token in the parcel at the current
472 * {@link #dataPosition}. This is used to validate that the marshalled
473 * transaction is intended for the target interface.
474 */
Jeff Sharkey047238c2012-03-07 16:51:38 -0800475 public final void writeInterfaceToken(String interfaceName) {
476 nativeWriteInterfaceToken(mNativePtr, interfaceName);
477 }
478
479 public final void enforceInterface(String interfaceName) {
480 nativeEnforceInterface(mNativePtr, interfaceName);
481 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800482
483 /**
Elliott Hughesa28b83e2011-02-28 14:26:13 -0800484 * Write a byte array into the parcel at the current {@link #dataPosition},
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800485 * growing {@link #dataCapacity} if needed.
486 * @param b Bytes to place into the parcel.
487 */
488 public final void writeByteArray(byte[] b) {
489 writeByteArray(b, 0, (b != null) ? b.length : 0);
490 }
491
492 /**
Ken Wakasaf76a50c2012-03-09 19:56:35 +0900493 * Write a byte array into the parcel at the current {@link #dataPosition},
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800494 * growing {@link #dataCapacity} if needed.
495 * @param b Bytes to place into the parcel.
496 * @param offset Index of first byte to be written.
497 * @param len Number of bytes to write.
498 */
499 public final void writeByteArray(byte[] b, int offset, int len) {
500 if (b == null) {
501 writeInt(-1);
502 return;
503 }
Elliott Hughesa28b83e2011-02-28 14:26:13 -0800504 Arrays.checkOffsetAndCount(b.length, offset, len);
Jeff Sharkey047238c2012-03-07 16:51:38 -0800505 nativeWriteByteArray(mNativePtr, b, offset, len);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800506 }
507
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800508 /**
Sandeep Siddhartha90d7a3e2014-07-25 16:19:42 -0700509 * Write a blob of data into the parcel at the current {@link #dataPosition},
510 * growing {@link #dataCapacity} if needed.
511 * @param b Bytes to place into the parcel.
512 * {@hide}
Sandeep Siddhartha39c12fa2014-07-25 18:37:29 -0700513 * {@SystemApi}
Sandeep Siddhartha90d7a3e2014-07-25 16:19:42 -0700514 */
515 public final void writeBlob(byte[] b) {
Dan Sandlerb9f7aac32015-03-04 13:08:49 -0500516 writeBlob(b, 0, (b != null) ? b.length : 0);
517 }
518
519 /**
520 * Write a blob of data into the parcel at the current {@link #dataPosition},
521 * growing {@link #dataCapacity} if needed.
522 * @param b Bytes to place into the parcel.
523 * @param offset Index of first byte to be written.
524 * @param len Number of bytes to write.
525 * {@hide}
526 * {@SystemApi}
527 */
528 public final void writeBlob(byte[] b, int offset, int len) {
529 if (b == null) {
530 writeInt(-1);
531 return;
532 }
533 Arrays.checkOffsetAndCount(b.length, offset, len);
534 nativeWriteBlob(mNativePtr, b, offset, len);
Sandeep Siddhartha90d7a3e2014-07-25 16:19:42 -0700535 }
536
537 /**
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800538 * Write an integer value into the parcel at the current dataPosition(),
539 * growing dataCapacity() if needed.
540 */
Jeff Sharkey047238c2012-03-07 16:51:38 -0800541 public final void writeInt(int val) {
542 nativeWriteInt(mNativePtr, val);
543 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800544
545 /**
546 * Write a long integer value into the parcel at the current dataPosition(),
547 * growing dataCapacity() if needed.
548 */
Jeff Sharkey047238c2012-03-07 16:51:38 -0800549 public final void writeLong(long val) {
550 nativeWriteLong(mNativePtr, val);
551 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800552
553 /**
554 * Write a floating point value into the parcel at the current
555 * dataPosition(), growing dataCapacity() if needed.
556 */
Jeff Sharkey047238c2012-03-07 16:51:38 -0800557 public final void writeFloat(float val) {
558 nativeWriteFloat(mNativePtr, val);
559 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800560
561 /**
562 * Write a double precision floating point value into the parcel at the
563 * current dataPosition(), growing dataCapacity() if needed.
564 */
Jeff Sharkey047238c2012-03-07 16:51:38 -0800565 public final void writeDouble(double val) {
566 nativeWriteDouble(mNativePtr, val);
567 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800568
569 /**
570 * Write a string value into the parcel at the current dataPosition(),
571 * growing dataCapacity() if needed.
572 */
Jeff Sharkey047238c2012-03-07 16:51:38 -0800573 public final void writeString(String val) {
574 nativeWriteString(mNativePtr, val);
575 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800576
577 /**
Bjorn Bringert08bbffb2010-02-25 11:16:22 +0000578 * Write a CharSequence value into the parcel at the current dataPosition(),
579 * growing dataCapacity() if needed.
580 * @hide
581 */
582 public final void writeCharSequence(CharSequence val) {
583 TextUtils.writeToParcel(val, this, 0);
584 }
585
586 /**
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800587 * Write an object into the parcel at the current dataPosition(),
588 * growing dataCapacity() if needed.
589 */
Jeff Sharkey047238c2012-03-07 16:51:38 -0800590 public final void writeStrongBinder(IBinder val) {
591 nativeWriteStrongBinder(mNativePtr, val);
592 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800593
594 /**
595 * Write an object into the parcel at the current dataPosition(),
596 * growing dataCapacity() if needed.
597 */
598 public final void writeStrongInterface(IInterface val) {
599 writeStrongBinder(val == null ? null : val.asBinder());
600 }
601
602 /**
603 * Write a FileDescriptor into the parcel at the current dataPosition(),
604 * growing dataCapacity() if needed.
Dan Egnorb3e4ef32010-07-20 09:03:35 -0700605 *
606 * <p class="caution">The file descriptor will not be closed, which may
607 * result in file descriptor leaks when objects are returned from Binder
608 * calls. Use {@link ParcelFileDescriptor#writeToParcel} instead, which
609 * accepts contextual flags and will close the original file descriptor
610 * if {@link Parcelable#PARCELABLE_WRITE_RETURN_VALUE} is set.</p>
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800611 */
Jeff Sharkey047238c2012-03-07 16:51:38 -0800612 public final void writeFileDescriptor(FileDescriptor val) {
Adrian Roos04505652015-10-22 16:12:01 -0700613 updateNativeSize(nativeWriteFileDescriptor(mNativePtr, val));
614 }
615
616 private void updateNativeSize(long newNativeSize) {
617 if (mOwnsNativeParcelObject) {
618 if (newNativeSize > Integer.MAX_VALUE) {
619 newNativeSize = Integer.MAX_VALUE;
620 }
621 if (newNativeSize != mNativeSize) {
622 int delta = (int) (newNativeSize - mNativeSize);
623 if (delta > 0) {
624 VMRuntime.getRuntime().registerNativeAllocation(delta);
625 } else {
626 VMRuntime.getRuntime().registerNativeFree(-delta);
627 }
628 mNativeSize = newNativeSize;
629 }
630 }
Jeff Sharkey047238c2012-03-07 16:51:38 -0800631 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800632
633 /**
Casey Dahlin2f974b22015-11-05 12:19:13 -0800634 * {@hide}
635 * This will be the new name for writeFileDescriptor, for consistency.
636 **/
637 public final void writeRawFileDescriptor(FileDescriptor val) {
638 nativeWriteFileDescriptor(mNativePtr, val);
639 }
640
641 /**
642 * {@hide}
643 * Write an array of FileDescriptor objects into the Parcel.
644 *
645 * @param value The array of objects to be written.
646 */
647 public final void writeRawFileDescriptorArray(FileDescriptor[] value) {
648 if (value != null) {
649 int N = value.length;
650 writeInt(N);
651 for (int i=0; i<N; i++) {
652 writeRawFileDescriptor(value[i]);
653 }
654 } else {
655 writeInt(-1);
656 }
657 }
658
659 /**
Ken Wakasaf76a50c2012-03-09 19:56:35 +0900660 * Write a byte value into the parcel at the current dataPosition(),
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800661 * growing dataCapacity() if needed.
662 */
663 public final void writeByte(byte val) {
664 writeInt(val);
665 }
666
667 /**
668 * Please use {@link #writeBundle} instead. Flattens a Map into the parcel
669 * at the current dataPosition(),
670 * growing dataCapacity() if needed. The Map keys must be String objects.
671 * The Map values are written using {@link #writeValue} and must follow
672 * the specification there.
Samuel Tana8036662015-11-23 14:36:00 -0800673 *
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800674 * <p>It is strongly recommended to use {@link #writeBundle} instead of
675 * this method, since the Bundle class provides a type-safe API that
676 * allows you to avoid mysterious type errors at the point of marshalling.
677 */
678 public final void writeMap(Map val) {
Dianne Hackbornb87655b2013-07-17 19:06:22 -0700679 writeMapInternal((Map<String, Object>) val);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800680 }
681
682 /**
683 * Flatten a Map into the parcel at the current dataPosition(),
684 * growing dataCapacity() if needed. The Map keys must be String objects.
685 */
Dianne Hackborn6aff9052009-05-22 13:20:23 -0700686 /* package */ void writeMapInternal(Map<String,Object> val) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800687 if (val == null) {
688 writeInt(-1);
689 return;
690 }
691 Set<Map.Entry<String,Object>> entries = val.entrySet();
692 writeInt(entries.size());
693 for (Map.Entry<String,Object> e : entries) {
694 writeValue(e.getKey());
695 writeValue(e.getValue());
696 }
697 }
698
699 /**
Dianne Hackbornb87655b2013-07-17 19:06:22 -0700700 * Flatten an ArrayMap into the parcel at the current dataPosition(),
701 * growing dataCapacity() if needed. The Map keys must be String objects.
702 */
Dianne Hackborn9c3e74f2014-08-13 15:39:50 -0700703 /* package */ void writeArrayMapInternal(ArrayMap<String, Object> val) {
Dianne Hackbornb87655b2013-07-17 19:06:22 -0700704 if (val == null) {
705 writeInt(-1);
706 return;
707 }
Samuel Tan3cefe6a2015-12-14 13:29:17 -0800708 // Keep the format of this Parcel in sync with writeToParcelInner() in
709 // frameworks/native/libs/binder/PersistableBundle.cpp.
Dianne Hackbornb87655b2013-07-17 19:06:22 -0700710 final int N = val.size();
711 writeInt(N);
Dianne Hackborne784d1e2013-09-20 18:13:52 -0700712 if (DEBUG_ARRAY_MAP) {
713 RuntimeException here = new RuntimeException("here");
714 here.fillInStackTrace();
715 Log.d(TAG, "Writing " + N + " ArrayMap entries", here);
716 }
Dianne Hackborn8aee64d2013-10-25 10:41:50 -0700717 int startPos;
Dianne Hackbornb87655b2013-07-17 19:06:22 -0700718 for (int i=0; i<N; i++) {
Dianne Hackborn8aee64d2013-10-25 10:41:50 -0700719 if (DEBUG_ARRAY_MAP) startPos = dataPosition();
Dianne Hackborn9c3e74f2014-08-13 15:39:50 -0700720 writeString(val.keyAt(i));
Dianne Hackbornb87655b2013-07-17 19:06:22 -0700721 writeValue(val.valueAt(i));
Dianne Hackborn8aee64d2013-10-25 10:41:50 -0700722 if (DEBUG_ARRAY_MAP) Log.d(TAG, " Write #" + i + " "
723 + (dataPosition()-startPos) + " bytes: key=0x"
724 + Integer.toHexString(val.keyAt(i) != null ? val.keyAt(i).hashCode() : 0)
725 + " " + val.keyAt(i));
Dianne Hackbornb87655b2013-07-17 19:06:22 -0700726 }
727 }
728
729 /**
Dianne Hackborn9c3e74f2014-08-13 15:39:50 -0700730 * @hide For testing only.
731 */
732 public void writeArrayMap(ArrayMap<String, Object> val) {
733 writeArrayMapInternal(val);
734 }
735
736 /**
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800737 * Flatten a Bundle into the parcel at the current dataPosition(),
738 * growing dataCapacity() if needed.
739 */
740 public final void writeBundle(Bundle val) {
741 if (val == null) {
742 writeInt(-1);
743 return;
744 }
745
Dianne Hackborn6aff9052009-05-22 13:20:23 -0700746 val.writeToParcel(this, 0);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800747 }
748
749 /**
Craig Mautner719e6b12014-04-04 20:29:41 -0700750 * Flatten a PersistableBundle into the parcel at the current dataPosition(),
751 * growing dataCapacity() if needed.
752 */
753 public final void writePersistableBundle(PersistableBundle val) {
754 if (val == null) {
755 writeInt(-1);
756 return;
757 }
758
759 val.writeToParcel(this, 0);
760 }
761
762 /**
Jeff Sharkey5ef33982014-09-04 18:13:39 -0700763 * Flatten a Size into the parcel at the current dataPosition(),
764 * growing dataCapacity() if needed.
765 */
766 public final void writeSize(Size val) {
767 writeInt(val.getWidth());
768 writeInt(val.getHeight());
769 }
770
771 /**
772 * Flatten a SizeF into the parcel at the current dataPosition(),
773 * growing dataCapacity() if needed.
774 */
775 public final void writeSizeF(SizeF val) {
776 writeFloat(val.getWidth());
777 writeFloat(val.getHeight());
778 }
779
780 /**
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800781 * Flatten a List into the parcel at the current dataPosition(), growing
782 * dataCapacity() if needed. The List values are written using
783 * {@link #writeValue} and must follow the specification there.
784 */
785 public final void writeList(List val) {
786 if (val == null) {
787 writeInt(-1);
788 return;
789 }
790 int N = val.size();
791 int i=0;
792 writeInt(N);
793 while (i < N) {
794 writeValue(val.get(i));
795 i++;
796 }
797 }
798
799 /**
800 * Flatten an Object array into the parcel at the current dataPosition(),
801 * growing dataCapacity() if needed. The array values are written using
802 * {@link #writeValue} and must follow the specification there.
803 */
804 public final void writeArray(Object[] val) {
805 if (val == null) {
806 writeInt(-1);
807 return;
808 }
809 int N = val.length;
810 int i=0;
811 writeInt(N);
812 while (i < N) {
813 writeValue(val[i]);
814 i++;
815 }
816 }
817
818 /**
819 * Flatten a generic SparseArray into the parcel at the current
820 * dataPosition(), growing dataCapacity() if needed. The SparseArray
821 * values are written using {@link #writeValue} and must follow the
822 * specification there.
823 */
824 public final void writeSparseArray(SparseArray<Object> val) {
825 if (val == null) {
826 writeInt(-1);
827 return;
828 }
829 int N = val.size();
830 writeInt(N);
831 int i=0;
832 while (i < N) {
833 writeInt(val.keyAt(i));
834 writeValue(val.valueAt(i));
835 i++;
836 }
837 }
838
839 public final void writeSparseBooleanArray(SparseBooleanArray val) {
840 if (val == null) {
841 writeInt(-1);
842 return;
843 }
844 int N = val.size();
845 writeInt(N);
846 int i=0;
847 while (i < N) {
848 writeInt(val.keyAt(i));
849 writeByte((byte)(val.valueAt(i) ? 1 : 0));
850 i++;
851 }
852 }
853
854 public final void writeBooleanArray(boolean[] val) {
855 if (val != null) {
856 int N = val.length;
857 writeInt(N);
858 for (int i=0; i<N; i++) {
859 writeInt(val[i] ? 1 : 0);
860 }
861 } else {
862 writeInt(-1);
863 }
864 }
865
866 public final boolean[] createBooleanArray() {
867 int N = readInt();
868 // >>2 as a fast divide-by-4 works in the create*Array() functions
869 // because dataAvail() will never return a negative number. 4 is
870 // the size of a stored boolean in the stream.
871 if (N >= 0 && N <= (dataAvail() >> 2)) {
872 boolean[] val = new boolean[N];
873 for (int i=0; i<N; i++) {
874 val[i] = readInt() != 0;
875 }
876 return val;
877 } else {
878 return null;
879 }
880 }
881
882 public final void readBooleanArray(boolean[] val) {
883 int N = readInt();
884 if (N == val.length) {
885 for (int i=0; i<N; i++) {
886 val[i] = readInt() != 0;
887 }
888 } else {
889 throw new RuntimeException("bad array lengths");
890 }
891 }
892
893 public final void writeCharArray(char[] val) {
894 if (val != null) {
895 int N = val.length;
896 writeInt(N);
897 for (int i=0; i<N; i++) {
898 writeInt((int)val[i]);
899 }
900 } else {
901 writeInt(-1);
902 }
903 }
904
905 public final char[] createCharArray() {
906 int N = readInt();
907 if (N >= 0 && N <= (dataAvail() >> 2)) {
908 char[] val = new char[N];
909 for (int i=0; i<N; i++) {
910 val[i] = (char)readInt();
911 }
912 return val;
913 } else {
914 return null;
915 }
916 }
917
918 public final void readCharArray(char[] val) {
919 int N = readInt();
920 if (N == val.length) {
921 for (int i=0; i<N; i++) {
922 val[i] = (char)readInt();
923 }
924 } else {
925 throw new RuntimeException("bad array lengths");
926 }
927 }
928
929 public final void writeIntArray(int[] val) {
930 if (val != null) {
931 int N = val.length;
932 writeInt(N);
933 for (int i=0; i<N; i++) {
934 writeInt(val[i]);
935 }
936 } else {
937 writeInt(-1);
938 }
939 }
940
941 public final int[] createIntArray() {
942 int N = readInt();
943 if (N >= 0 && N <= (dataAvail() >> 2)) {
944 int[] val = new int[N];
945 for (int i=0; i<N; i++) {
946 val[i] = readInt();
947 }
948 return val;
949 } else {
950 return null;
951 }
952 }
953
954 public final void readIntArray(int[] val) {
955 int N = readInt();
956 if (N == val.length) {
957 for (int i=0; i<N; i++) {
958 val[i] = readInt();
959 }
960 } else {
961 throw new RuntimeException("bad array lengths");
962 }
963 }
964
965 public final void writeLongArray(long[] val) {
966 if (val != null) {
967 int N = val.length;
968 writeInt(N);
969 for (int i=0; i<N; i++) {
970 writeLong(val[i]);
971 }
972 } else {
973 writeInt(-1);
974 }
975 }
976
977 public final long[] createLongArray() {
978 int N = readInt();
979 // >>3 because stored longs are 64 bits
980 if (N >= 0 && N <= (dataAvail() >> 3)) {
981 long[] val = new long[N];
982 for (int i=0; i<N; i++) {
983 val[i] = readLong();
984 }
985 return val;
986 } else {
987 return null;
988 }
989 }
990
991 public final void readLongArray(long[] val) {
992 int N = readInt();
993 if (N == val.length) {
994 for (int i=0; i<N; i++) {
995 val[i] = readLong();
996 }
997 } else {
998 throw new RuntimeException("bad array lengths");
999 }
1000 }
1001
1002 public final void writeFloatArray(float[] val) {
1003 if (val != null) {
1004 int N = val.length;
1005 writeInt(N);
1006 for (int i=0; i<N; i++) {
1007 writeFloat(val[i]);
1008 }
1009 } else {
1010 writeInt(-1);
1011 }
1012 }
1013
1014 public final float[] createFloatArray() {
1015 int N = readInt();
1016 // >>2 because stored floats are 4 bytes
1017 if (N >= 0 && N <= (dataAvail() >> 2)) {
1018 float[] val = new float[N];
1019 for (int i=0; i<N; i++) {
1020 val[i] = readFloat();
1021 }
1022 return val;
1023 } else {
1024 return null;
1025 }
1026 }
1027
1028 public final void readFloatArray(float[] val) {
1029 int N = readInt();
1030 if (N == val.length) {
1031 for (int i=0; i<N; i++) {
1032 val[i] = readFloat();
1033 }
1034 } else {
1035 throw new RuntimeException("bad array lengths");
1036 }
1037 }
1038
1039 public final void writeDoubleArray(double[] val) {
1040 if (val != null) {
1041 int N = val.length;
1042 writeInt(N);
1043 for (int i=0; i<N; i++) {
1044 writeDouble(val[i]);
1045 }
1046 } else {
1047 writeInt(-1);
1048 }
1049 }
1050
1051 public final double[] createDoubleArray() {
1052 int N = readInt();
1053 // >>3 because stored doubles are 8 bytes
1054 if (N >= 0 && N <= (dataAvail() >> 3)) {
1055 double[] val = new double[N];
1056 for (int i=0; i<N; i++) {
1057 val[i] = readDouble();
1058 }
1059 return val;
1060 } else {
1061 return null;
1062 }
1063 }
1064
1065 public final void readDoubleArray(double[] val) {
1066 int N = readInt();
1067 if (N == val.length) {
1068 for (int i=0; i<N; i++) {
1069 val[i] = readDouble();
1070 }
1071 } else {
1072 throw new RuntimeException("bad array lengths");
1073 }
1074 }
1075
1076 public final void writeStringArray(String[] val) {
1077 if (val != null) {
1078 int N = val.length;
1079 writeInt(N);
1080 for (int i=0; i<N; i++) {
1081 writeString(val[i]);
1082 }
1083 } else {
1084 writeInt(-1);
1085 }
1086 }
1087
1088 public final String[] createStringArray() {
1089 int N = readInt();
1090 if (N >= 0) {
1091 String[] val = new String[N];
1092 for (int i=0; i<N; i++) {
1093 val[i] = readString();
1094 }
1095 return val;
1096 } else {
1097 return null;
1098 }
1099 }
1100
1101 public final void readStringArray(String[] val) {
1102 int N = readInt();
1103 if (N == val.length) {
1104 for (int i=0; i<N; i++) {
1105 val[i] = readString();
1106 }
1107 } else {
1108 throw new RuntimeException("bad array lengths");
1109 }
1110 }
1111
1112 public final void writeBinderArray(IBinder[] val) {
1113 if (val != null) {
1114 int N = val.length;
1115 writeInt(N);
1116 for (int i=0; i<N; i++) {
1117 writeStrongBinder(val[i]);
1118 }
1119 } else {
1120 writeInt(-1);
1121 }
1122 }
1123
Bjorn Bringert08bbffb2010-02-25 11:16:22 +00001124 /**
1125 * @hide
1126 */
1127 public final void writeCharSequenceArray(CharSequence[] val) {
1128 if (val != null) {
1129 int N = val.length;
1130 writeInt(N);
1131 for (int i=0; i<N; i++) {
1132 writeCharSequence(val[i]);
1133 }
1134 } else {
1135 writeInt(-1);
1136 }
1137 }
1138
Dianne Hackborn3d07c942015-03-13 18:02:54 -07001139 /**
1140 * @hide
1141 */
1142 public final void writeCharSequenceList(ArrayList<CharSequence> val) {
1143 if (val != null) {
1144 int N = val.size();
1145 writeInt(N);
1146 for (int i=0; i<N; i++) {
1147 writeCharSequence(val.get(i));
1148 }
1149 } else {
1150 writeInt(-1);
1151 }
1152 }
1153
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001154 public final IBinder[] createBinderArray() {
1155 int N = readInt();
1156 if (N >= 0) {
1157 IBinder[] val = new IBinder[N];
1158 for (int i=0; i<N; i++) {
1159 val[i] = readStrongBinder();
1160 }
1161 return val;
1162 } else {
1163 return null;
1164 }
1165 }
1166
1167 public final void readBinderArray(IBinder[] val) {
1168 int N = readInt();
1169 if (N == val.length) {
1170 for (int i=0; i<N; i++) {
1171 val[i] = readStrongBinder();
1172 }
1173 } else {
1174 throw new RuntimeException("bad array lengths");
1175 }
1176 }
1177
1178 /**
1179 * Flatten a List containing a particular object type into the parcel, at
1180 * the current dataPosition() and growing dataCapacity() if needed. The
1181 * type of the objects in the list must be one that implements Parcelable.
1182 * Unlike the generic writeList() method, however, only the raw data of the
1183 * objects is written and not their type, so you must use the corresponding
1184 * readTypedList() to unmarshall them.
1185 *
1186 * @param val The list of objects to be written.
1187 *
1188 * @see #createTypedArrayList
1189 * @see #readTypedList
1190 * @see Parcelable
1191 */
1192 public final <T extends Parcelable> void writeTypedList(List<T> val) {
1193 if (val == null) {
1194 writeInt(-1);
1195 return;
1196 }
1197 int N = val.size();
1198 int i=0;
1199 writeInt(N);
1200 while (i < N) {
1201 T item = val.get(i);
1202 if (item != null) {
1203 writeInt(1);
1204 item.writeToParcel(this, 0);
1205 } else {
1206 writeInt(0);
1207 }
1208 i++;
1209 }
1210 }
1211
1212 /**
1213 * Flatten a List containing String objects into the parcel, at
1214 * the current dataPosition() and growing dataCapacity() if needed. They
1215 * can later be retrieved with {@link #createStringArrayList} or
1216 * {@link #readStringList}.
1217 *
1218 * @param val The list of strings to be written.
1219 *
1220 * @see #createStringArrayList
1221 * @see #readStringList
1222 */
1223 public final void writeStringList(List<String> val) {
1224 if (val == null) {
1225 writeInt(-1);
1226 return;
1227 }
1228 int N = val.size();
1229 int i=0;
1230 writeInt(N);
1231 while (i < N) {
1232 writeString(val.get(i));
1233 i++;
1234 }
1235 }
1236
1237 /**
1238 * Flatten a List containing IBinder objects into the parcel, at
1239 * the current dataPosition() and growing dataCapacity() if needed. They
1240 * can later be retrieved with {@link #createBinderArrayList} or
1241 * {@link #readBinderList}.
1242 *
1243 * @param val The list of strings to be written.
1244 *
1245 * @see #createBinderArrayList
1246 * @see #readBinderList
1247 */
1248 public final void writeBinderList(List<IBinder> val) {
1249 if (val == null) {
1250 writeInt(-1);
1251 return;
1252 }
1253 int N = val.size();
1254 int i=0;
1255 writeInt(N);
1256 while (i < N) {
1257 writeStrongBinder(val.get(i));
1258 i++;
1259 }
1260 }
1261
1262 /**
1263 * Flatten a heterogeneous array containing a particular object type into
1264 * the parcel, at
1265 * the current dataPosition() and growing dataCapacity() if needed. The
1266 * type of the objects in the array must be one that implements Parcelable.
1267 * Unlike the {@link #writeParcelableArray} method, however, only the
1268 * raw data of the objects is written and not their type, so you must use
1269 * {@link #readTypedArray} with the correct corresponding
1270 * {@link Parcelable.Creator} implementation to unmarshall them.
1271 *
1272 * @param val The array of objects to be written.
1273 * @param parcelableFlags Contextual flags as per
1274 * {@link Parcelable#writeToParcel(Parcel, int) Parcelable.writeToParcel()}.
1275 *
1276 * @see #readTypedArray
1277 * @see #writeParcelableArray
1278 * @see Parcelable.Creator
1279 */
1280 public final <T extends Parcelable> void writeTypedArray(T[] val,
1281 int parcelableFlags) {
1282 if (val != null) {
1283 int N = val.length;
1284 writeInt(N);
1285 for (int i=0; i<N; i++) {
1286 T item = val[i];
1287 if (item != null) {
1288 writeInt(1);
1289 item.writeToParcel(this, parcelableFlags);
1290 } else {
1291 writeInt(0);
1292 }
1293 }
1294 } else {
1295 writeInt(-1);
1296 }
1297 }
1298
1299 /**
Jens Ole Lauridsen8dea8742015-04-20 11:18:51 -07001300 * Flatten the Parcelable object into the parcel.
1301 *
1302 * @param val The Parcelable object to be written.
1303 * @param parcelableFlags Contextual flags as per
1304 * {@link Parcelable#writeToParcel(Parcel, int) Parcelable.writeToParcel()}.
1305 *
1306 * @see #readTypedObject
1307 */
1308 public final <T extends Parcelable> void writeTypedObject(T val, int parcelableFlags) {
1309 if (val != null) {
1310 writeInt(1);
1311 val.writeToParcel(this, parcelableFlags);
1312 } else {
1313 writeInt(0);
1314 }
1315 }
1316
1317 /**
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001318 * Flatten a generic object in to a parcel. The given Object value may
1319 * currently be one of the following types:
Dan Egnorb3e4ef32010-07-20 09:03:35 -07001320 *
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001321 * <ul>
1322 * <li> null
1323 * <li> String
1324 * <li> Byte
1325 * <li> Short
1326 * <li> Integer
1327 * <li> Long
1328 * <li> Float
1329 * <li> Double
1330 * <li> Boolean
1331 * <li> String[]
1332 * <li> boolean[]
1333 * <li> byte[]
1334 * <li> int[]
1335 * <li> long[]
1336 * <li> Object[] (supporting objects of the same type defined here).
1337 * <li> {@link Bundle}
1338 * <li> Map (as supported by {@link #writeMap}).
1339 * <li> Any object that implements the {@link Parcelable} protocol.
1340 * <li> Parcelable[]
1341 * <li> CharSequence (as supported by {@link TextUtils#writeToParcel}).
1342 * <li> List (as supported by {@link #writeList}).
Dan Egnorb3e4ef32010-07-20 09:03:35 -07001343 * <li> {@link SparseArray} (as supported by {@link #writeSparseArray(SparseArray)}).
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001344 * <li> {@link IBinder}
1345 * <li> Any object that implements Serializable (but see
1346 * {@link #writeSerializable} for caveats). Note that all of the
1347 * previous types have relatively efficient implementations for
1348 * writing to a Parcel; having to rely on the generic serialization
1349 * approach is much less efficient and should be avoided whenever
1350 * possible.
1351 * </ul>
Dan Egnorb3e4ef32010-07-20 09:03:35 -07001352 *
1353 * <p class="caution">{@link Parcelable} objects are written with
1354 * {@link Parcelable#writeToParcel} using contextual flags of 0. When
1355 * serializing objects containing {@link ParcelFileDescriptor}s,
1356 * this may result in file descriptor leaks when they are returned from
1357 * Binder calls (where {@link Parcelable#PARCELABLE_WRITE_RETURN_VALUE}
1358 * should be used).</p>
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001359 */
1360 public final void writeValue(Object v) {
1361 if (v == null) {
1362 writeInt(VAL_NULL);
1363 } else if (v instanceof String) {
1364 writeInt(VAL_STRING);
1365 writeString((String) v);
1366 } else if (v instanceof Integer) {
1367 writeInt(VAL_INTEGER);
1368 writeInt((Integer) v);
1369 } else if (v instanceof Map) {
1370 writeInt(VAL_MAP);
1371 writeMap((Map) v);
1372 } else if (v instanceof Bundle) {
1373 // Must be before Parcelable
1374 writeInt(VAL_BUNDLE);
1375 writeBundle((Bundle) v);
Samuel Tanceafe5e2015-12-11 16:50:58 -08001376 } else if (v instanceof PersistableBundle) {
1377 writeInt(VAL_PERSISTABLEBUNDLE);
1378 writePersistableBundle((PersistableBundle) v);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001379 } else if (v instanceof Parcelable) {
Samuel Tanceafe5e2015-12-11 16:50:58 -08001380 // IMPOTANT: cases for classes that implement Parcelable must
1381 // come before the Parcelable case, so that their specific VAL_*
1382 // types will be written.
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001383 writeInt(VAL_PARCELABLE);
1384 writeParcelable((Parcelable) v, 0);
1385 } else if (v instanceof Short) {
1386 writeInt(VAL_SHORT);
1387 writeInt(((Short) v).intValue());
1388 } else if (v instanceof Long) {
1389 writeInt(VAL_LONG);
1390 writeLong((Long) v);
1391 } else if (v instanceof Float) {
1392 writeInt(VAL_FLOAT);
1393 writeFloat((Float) v);
1394 } else if (v instanceof Double) {
1395 writeInt(VAL_DOUBLE);
1396 writeDouble((Double) v);
1397 } else if (v instanceof Boolean) {
1398 writeInt(VAL_BOOLEAN);
1399 writeInt((Boolean) v ? 1 : 0);
1400 } else if (v instanceof CharSequence) {
1401 // Must be after String
1402 writeInt(VAL_CHARSEQUENCE);
Bjorn Bringert08bbffb2010-02-25 11:16:22 +00001403 writeCharSequence((CharSequence) v);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001404 } else if (v instanceof List) {
1405 writeInt(VAL_LIST);
1406 writeList((List) v);
1407 } else if (v instanceof SparseArray) {
1408 writeInt(VAL_SPARSEARRAY);
1409 writeSparseArray((SparseArray) v);
1410 } else if (v instanceof boolean[]) {
1411 writeInt(VAL_BOOLEANARRAY);
1412 writeBooleanArray((boolean[]) v);
1413 } else if (v instanceof byte[]) {
1414 writeInt(VAL_BYTEARRAY);
1415 writeByteArray((byte[]) v);
1416 } else if (v instanceof String[]) {
1417 writeInt(VAL_STRINGARRAY);
1418 writeStringArray((String[]) v);
Bjorn Bringert08bbffb2010-02-25 11:16:22 +00001419 } else if (v instanceof CharSequence[]) {
1420 // Must be after String[] and before Object[]
1421 writeInt(VAL_CHARSEQUENCEARRAY);
1422 writeCharSequenceArray((CharSequence[]) v);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001423 } else if (v instanceof IBinder) {
1424 writeInt(VAL_IBINDER);
1425 writeStrongBinder((IBinder) v);
1426 } else if (v instanceof Parcelable[]) {
1427 writeInt(VAL_PARCELABLEARRAY);
1428 writeParcelableArray((Parcelable[]) v, 0);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001429 } else if (v instanceof int[]) {
1430 writeInt(VAL_INTARRAY);
1431 writeIntArray((int[]) v);
1432 } else if (v instanceof long[]) {
1433 writeInt(VAL_LONGARRAY);
1434 writeLongArray((long[]) v);
1435 } else if (v instanceof Byte) {
1436 writeInt(VAL_BYTE);
1437 writeInt((Byte) v);
Jeff Sharkey5ef33982014-09-04 18:13:39 -07001438 } else if (v instanceof Size) {
1439 writeInt(VAL_SIZE);
1440 writeSize((Size) v);
1441 } else if (v instanceof SizeF) {
1442 writeInt(VAL_SIZEF);
1443 writeSizeF((SizeF) v);
Samuel Tana8036662015-11-23 14:36:00 -08001444 } else if (v instanceof double[]) {
1445 writeInt(VAL_DOUBLEARRAY);
1446 writeDoubleArray((double[]) v);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001447 } else {
Paul Duffinac5a0822014-02-03 15:02:17 +00001448 Class<?> clazz = v.getClass();
1449 if (clazz.isArray() && clazz.getComponentType() == Object.class) {
1450 // Only pure Object[] are written here, Other arrays of non-primitive types are
1451 // handled by serialization as this does not record the component type.
1452 writeInt(VAL_OBJECTARRAY);
1453 writeArray((Object[]) v);
1454 } else if (v instanceof Serializable) {
1455 // Must be last
1456 writeInt(VAL_SERIALIZABLE);
1457 writeSerializable((Serializable) v);
1458 } else {
1459 throw new RuntimeException("Parcel: unable to marshal value " + v);
1460 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001461 }
1462 }
1463
1464 /**
1465 * Flatten the name of the class of the Parcelable and its contents
1466 * into the parcel.
Dan Egnorb3e4ef32010-07-20 09:03:35 -07001467 *
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001468 * @param p The Parcelable object to be written.
1469 * @param parcelableFlags Contextual flags as per
1470 * {@link Parcelable#writeToParcel(Parcel, int) Parcelable.writeToParcel()}.
1471 */
1472 public final void writeParcelable(Parcelable p, int parcelableFlags) {
1473 if (p == null) {
1474 writeString(null);
1475 return;
1476 }
Neil Fuller44e440c2015-04-20 14:39:00 +01001477 writeParcelableCreator(p);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001478 p.writeToParcel(this, parcelableFlags);
1479 }
1480
Dianne Hackbornd8e1dbb2013-01-17 17:47:37 -08001481 /** @hide */
1482 public final void writeParcelableCreator(Parcelable p) {
1483 String name = p.getClass().getName();
1484 writeString(name);
1485 }
1486
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001487 /**
1488 * Write a generic serializable object in to a Parcel. It is strongly
1489 * recommended that this method be avoided, since the serialization
1490 * overhead is extremely large, and this approach will be much slower than
1491 * using the other approaches to writing data in to a Parcel.
1492 */
1493 public final void writeSerializable(Serializable s) {
1494 if (s == null) {
1495 writeString(null);
1496 return;
1497 }
1498 String name = s.getClass().getName();
1499 writeString(name);
1500
1501 ByteArrayOutputStream baos = new ByteArrayOutputStream();
1502 try {
1503 ObjectOutputStream oos = new ObjectOutputStream(baos);
1504 oos.writeObject(s);
1505 oos.close();
1506
1507 writeByteArray(baos.toByteArray());
1508 } catch (IOException ioe) {
1509 throw new RuntimeException("Parcelable encountered " +
1510 "IOException writing serializable object (name = " + name +
1511 ")", ioe);
1512 }
1513 }
1514
1515 /**
1516 * Special function for writing an exception result at the header of
1517 * a parcel, to be used when returning an exception from a transaction.
1518 * Note that this currently only supports a few exception types; any other
1519 * exception will be re-thrown by this function as a RuntimeException
1520 * (to be caught by the system's last-resort exception handling when
1521 * dispatching a transaction).
Samuel Tana8036662015-11-23 14:36:00 -08001522 *
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001523 * <p>The supported exception types are:
1524 * <ul>
1525 * <li>{@link BadParcelableException}
1526 * <li>{@link IllegalArgumentException}
1527 * <li>{@link IllegalStateException}
1528 * <li>{@link NullPointerException}
1529 * <li>{@link SecurityException}
Dianne Hackborn7e714422013-09-13 17:32:57 -07001530 * <li>{@link NetworkOnMainThreadException}
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001531 * </ul>
Samuel Tana8036662015-11-23 14:36:00 -08001532 *
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001533 * @param e The Exception to be written.
1534 *
1535 * @see #writeNoException
1536 * @see #readException
1537 */
1538 public final void writeException(Exception e) {
1539 int code = 0;
1540 if (e instanceof SecurityException) {
1541 code = EX_SECURITY;
1542 } else if (e instanceof BadParcelableException) {
1543 code = EX_BAD_PARCELABLE;
1544 } else if (e instanceof IllegalArgumentException) {
1545 code = EX_ILLEGAL_ARGUMENT;
1546 } else if (e instanceof NullPointerException) {
1547 code = EX_NULL_POINTER;
1548 } else if (e instanceof IllegalStateException) {
1549 code = EX_ILLEGAL_STATE;
Dianne Hackborn7e714422013-09-13 17:32:57 -07001550 } else if (e instanceof NetworkOnMainThreadException) {
1551 code = EX_NETWORK_MAIN_THREAD;
Dianne Hackborn33d738a2014-09-12 14:23:58 -07001552 } else if (e instanceof UnsupportedOperationException) {
1553 code = EX_UNSUPPORTED_OPERATION;
Christopher Wiley80fd1202015-11-22 17:12:37 -08001554 } else if (e instanceof ServiceSpecificException) {
1555 code = EX_SERVICE_SPECIFIC;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001556 }
1557 writeInt(code);
Brad Fitzpatrick703e5d32010-07-15 13:16:41 -07001558 StrictMode.clearGatheredViolations();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001559 if (code == 0) {
1560 if (e instanceof RuntimeException) {
1561 throw (RuntimeException) e;
1562 }
1563 throw new RuntimeException(e);
1564 }
1565 writeString(e.getMessage());
Christopher Wiley80fd1202015-11-22 17:12:37 -08001566 if (e instanceof ServiceSpecificException) {
1567 writeInt(((ServiceSpecificException)e).errorCode);
1568 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001569 }
1570
1571 /**
1572 * Special function for writing information at the front of the Parcel
1573 * indicating that no exception occurred.
1574 *
1575 * @see #writeException
1576 * @see #readException
1577 */
1578 public final void writeNoException() {
Brad Fitzpatrick5b747192010-07-12 11:05:38 -07001579 // Despite the name of this function ("write no exception"),
1580 // it should instead be thought of as "write the RPC response
1581 // header", but because this function name is written out by
1582 // the AIDL compiler, we're not going to rename it.
1583 //
1584 // The response header, in the non-exception case (see also
1585 // writeException above, also called by the AIDL compiler), is
1586 // either a 0 (the default case), or EX_HAS_REPLY_HEADER if
1587 // StrictMode has gathered up violations that have occurred
1588 // during a Binder call, in which case we write out the number
1589 // of violations and their details, serialized, before the
1590 // actual RPC respons data. The receiving end of this is
1591 // readException(), below.
1592 if (StrictMode.hasGatheredViolations()) {
1593 writeInt(EX_HAS_REPLY_HEADER);
1594 final int sizePosition = dataPosition();
1595 writeInt(0); // total size of fat header, to be filled in later
1596 StrictMode.writeGatheredViolationsToParcel(this);
1597 final int payloadPosition = dataPosition();
1598 setDataPosition(sizePosition);
1599 writeInt(payloadPosition - sizePosition); // header size
1600 setDataPosition(payloadPosition);
1601 } else {
1602 writeInt(0);
1603 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001604 }
1605
1606 /**
1607 * Special function for reading an exception result from the header of
1608 * a parcel, to be used after receiving the result of a transaction. This
1609 * will throw the exception for you if it had been written to the Parcel,
1610 * otherwise return and let you read the normal result data from the Parcel.
1611 *
1612 * @see #writeException
1613 * @see #writeNoException
1614 */
1615 public final void readException() {
Brad Fitzpatrick5b747192010-07-12 11:05:38 -07001616 int code = readExceptionCode();
1617 if (code != 0) {
1618 String msg = readString();
1619 readException(code, msg);
1620 }
1621 }
1622
1623 /**
1624 * Parses the header of a Binder call's response Parcel and
1625 * returns the exception code. Deals with lite or fat headers.
1626 * In the common successful case, this header is generally zero.
1627 * In less common cases, it's a small negative number and will be
1628 * followed by an error string.
1629 *
1630 * This exists purely for android.database.DatabaseUtils and
1631 * insulating it from having to handle fat headers as returned by
1632 * e.g. StrictMode-induced RPC responses.
1633 *
1634 * @hide
1635 */
1636 public final int readExceptionCode() {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001637 int code = readInt();
Brad Fitzpatrick5b747192010-07-12 11:05:38 -07001638 if (code == EX_HAS_REPLY_HEADER) {
1639 int headerSize = readInt();
1640 if (headerSize == 0) {
1641 Log.e(TAG, "Unexpected zero-sized Parcel reply header.");
1642 } else {
1643 // Currently the only thing in the header is StrictMode stacks,
1644 // but discussions around event/RPC tracing suggest we might
1645 // put that here too. If so, switch on sub-header tags here.
1646 // But for now, just parse out the StrictMode stuff.
1647 StrictMode.readAndHandleBinderCallViolations(this);
1648 }
1649 // And fat response headers are currently only used when
1650 // there are no exceptions, so return no error:
1651 return 0;
1652 }
1653 return code;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001654 }
1655
1656 /**
Mark Doliner879ea452014-01-02 12:38:07 -08001657 * Throw an exception with the given message. Not intended for use
1658 * outside the Parcel class.
1659 *
1660 * @param code Used to determine which exception class to throw.
1661 * @param msg The exception message.
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001662 */
1663 public final void readException(int code, String msg) {
1664 switch (code) {
1665 case EX_SECURITY:
1666 throw new SecurityException(msg);
1667 case EX_BAD_PARCELABLE:
1668 throw new BadParcelableException(msg);
1669 case EX_ILLEGAL_ARGUMENT:
1670 throw new IllegalArgumentException(msg);
1671 case EX_NULL_POINTER:
1672 throw new NullPointerException(msg);
1673 case EX_ILLEGAL_STATE:
1674 throw new IllegalStateException(msg);
Dianne Hackborn7e714422013-09-13 17:32:57 -07001675 case EX_NETWORK_MAIN_THREAD:
1676 throw new NetworkOnMainThreadException();
Dianne Hackborn33d738a2014-09-12 14:23:58 -07001677 case EX_UNSUPPORTED_OPERATION:
1678 throw new UnsupportedOperationException(msg);
Christopher Wiley80fd1202015-11-22 17:12:37 -08001679 case EX_SERVICE_SPECIFIC:
1680 throw new ServiceSpecificException(readInt(), msg);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001681 }
1682 throw new RuntimeException("Unknown exception code: " + code
1683 + " msg " + msg);
1684 }
1685
1686 /**
1687 * Read an integer value from the parcel at the current dataPosition().
1688 */
Jeff Sharkey047238c2012-03-07 16:51:38 -08001689 public final int readInt() {
1690 return nativeReadInt(mNativePtr);
1691 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001692
1693 /**
1694 * Read a long integer value from the parcel at the current dataPosition().
1695 */
Jeff Sharkey047238c2012-03-07 16:51:38 -08001696 public final long readLong() {
1697 return nativeReadLong(mNativePtr);
1698 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001699
1700 /**
1701 * Read a floating point value from the parcel at the current
1702 * dataPosition().
1703 */
Jeff Sharkey047238c2012-03-07 16:51:38 -08001704 public final float readFloat() {
1705 return nativeReadFloat(mNativePtr);
1706 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001707
1708 /**
1709 * Read a double precision floating point value from the parcel at the
1710 * current dataPosition().
1711 */
Jeff Sharkey047238c2012-03-07 16:51:38 -08001712 public final double readDouble() {
1713 return nativeReadDouble(mNativePtr);
1714 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001715
1716 /**
1717 * Read a string value from the parcel at the current dataPosition().
1718 */
Jeff Sharkey047238c2012-03-07 16:51:38 -08001719 public final String readString() {
1720 return nativeReadString(mNativePtr);
1721 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001722
1723 /**
Bjorn Bringert08bbffb2010-02-25 11:16:22 +00001724 * Read a CharSequence value from the parcel at the current dataPosition().
1725 * @hide
1726 */
1727 public final CharSequence readCharSequence() {
1728 return TextUtils.CHAR_SEQUENCE_CREATOR.createFromParcel(this);
1729 }
1730
1731 /**
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001732 * Read an object from the parcel at the current dataPosition().
1733 */
Jeff Sharkey047238c2012-03-07 16:51:38 -08001734 public final IBinder readStrongBinder() {
1735 return nativeReadStrongBinder(mNativePtr);
1736 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001737
1738 /**
1739 * Read a FileDescriptor from the parcel at the current dataPosition().
1740 */
1741 public final ParcelFileDescriptor readFileDescriptor() {
Jeff Sharkey047238c2012-03-07 16:51:38 -08001742 FileDescriptor fd = nativeReadFileDescriptor(mNativePtr);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001743 return fd != null ? new ParcelFileDescriptor(fd) : null;
1744 }
1745
Jeff Sharkeyda5a3e12013-08-11 12:54:42 -07001746 /** {@hide} */
1747 public final FileDescriptor readRawFileDescriptor() {
1748 return nativeReadFileDescriptor(mNativePtr);
1749 }
1750
Casey Dahlin2f974b22015-11-05 12:19:13 -08001751 /**
1752 * {@hide}
1753 * Read and return a new array of FileDescriptors from the parcel.
1754 * @return the FileDescriptor array, or null if the array is null.
1755 **/
1756 public final FileDescriptor[] createRawFileDescriptorArray() {
1757 int N = readInt();
1758 if (N < 0) {
1759 return null;
1760 }
1761 FileDescriptor[] f = new FileDescriptor[N];
1762 for (int i = 0; i < N; i++) {
1763 f[i] = readRawFileDescriptor();
1764 }
1765 return f;
1766 }
1767
1768 /**
1769 * {@hide}
1770 * Read an array of FileDescriptors from a parcel.
1771 * The passed array must be exactly the length of the array in the parcel.
1772 * @return the FileDescriptor array, or null if the array is null.
1773 **/
1774 public final void readRawFileDescriptorArray(FileDescriptor[] val) {
1775 int N = readInt();
1776 if (N == val.length) {
1777 for (int i=0; i<N; i++) {
1778 val[i] = readRawFileDescriptor();
1779 }
1780 } else {
1781 throw new RuntimeException("bad array lengths");
1782 }
1783 }
1784
1785
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001786 /*package*/ static native FileDescriptor openFileDescriptor(String file,
1787 int mode) throws FileNotFoundException;
Dianne Hackborn9a849832011-04-07 15:11:57 -07001788 /*package*/ static native FileDescriptor dupFileDescriptor(FileDescriptor orig)
1789 throws IOException;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001790 /*package*/ static native void closeFileDescriptor(FileDescriptor desc)
1791 throws IOException;
Dianne Hackbornc9119f52011-02-28 18:03:26 -08001792 /*package*/ static native void clearFileDescriptor(FileDescriptor desc);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001793
1794 /**
1795 * Read a byte value from the parcel at the current dataPosition().
1796 */
1797 public final byte readByte() {
1798 return (byte)(readInt() & 0xff);
1799 }
1800
1801 /**
1802 * Please use {@link #readBundle(ClassLoader)} instead (whose data must have
1803 * been written with {@link #writeBundle}. Read into an existing Map object
1804 * from the parcel at the current dataPosition().
1805 */
1806 public final void readMap(Map outVal, ClassLoader loader) {
1807 int N = readInt();
1808 readMapInternal(outVal, N, loader);
1809 }
1810
1811 /**
1812 * Read into an existing List object from the parcel at the current
1813 * dataPosition(), using the given class loader to load any enclosed
1814 * Parcelables. If it is null, the default class loader is used.
1815 */
1816 public final void readList(List outVal, ClassLoader loader) {
1817 int N = readInt();
1818 readListInternal(outVal, N, loader);
1819 }
1820
1821 /**
1822 * Please use {@link #readBundle(ClassLoader)} instead (whose data must have
1823 * been written with {@link #writeBundle}. Read and return a new HashMap
1824 * object from the parcel at the current dataPosition(), using the given
1825 * class loader to load any enclosed Parcelables. Returns null if
1826 * the previously written map object was null.
1827 */
1828 public final HashMap readHashMap(ClassLoader loader)
1829 {
1830 int N = readInt();
1831 if (N < 0) {
1832 return null;
1833 }
1834 HashMap m = new HashMap(N);
1835 readMapInternal(m, N, loader);
1836 return m;
1837 }
1838
1839 /**
1840 * Read and return a new Bundle object from the parcel at the current
1841 * dataPosition(). Returns null if the previously written Bundle object was
1842 * null.
1843 */
1844 public final Bundle readBundle() {
1845 return readBundle(null);
1846 }
1847
1848 /**
1849 * Read and return a new Bundle object from the parcel at the current
1850 * dataPosition(), using the given class loader to initialize the class
1851 * loader of the Bundle for later retrieval of Parcelable objects.
1852 * Returns null if the previously written Bundle object was null.
1853 */
1854 public final Bundle readBundle(ClassLoader loader) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001855 int length = readInt();
1856 if (length < 0) {
Dianne Hackborn4a7d8242013-10-03 10:19:20 -07001857 if (Bundle.DEBUG) Log.d(TAG, "null bundle: length=" + length);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001858 return null;
1859 }
Samuel Tana8036662015-11-23 14:36:00 -08001860
Dianne Hackborn6aff9052009-05-22 13:20:23 -07001861 final Bundle bundle = new Bundle(this, length);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001862 if (loader != null) {
1863 bundle.setClassLoader(loader);
1864 }
1865 return bundle;
1866 }
1867
1868 /**
Craig Mautner719e6b12014-04-04 20:29:41 -07001869 * Read and return a new Bundle object from the parcel at the current
1870 * dataPosition(). Returns null if the previously written Bundle object was
1871 * null.
1872 */
1873 public final PersistableBundle readPersistableBundle() {
1874 return readPersistableBundle(null);
1875 }
1876
1877 /**
1878 * Read and return a new Bundle object from the parcel at the current
1879 * dataPosition(), using the given class loader to initialize the class
1880 * loader of the Bundle for later retrieval of Parcelable objects.
1881 * Returns null if the previously written Bundle object was null.
1882 */
1883 public final PersistableBundle readPersistableBundle(ClassLoader loader) {
1884 int length = readInt();
1885 if (length < 0) {
1886 if (Bundle.DEBUG) Log.d(TAG, "null bundle: length=" + length);
1887 return null;
1888 }
1889
1890 final PersistableBundle bundle = new PersistableBundle(this, length);
1891 if (loader != null) {
1892 bundle.setClassLoader(loader);
1893 }
1894 return bundle;
1895 }
1896
1897 /**
Jeff Sharkey5ef33982014-09-04 18:13:39 -07001898 * Read a Size from the parcel at the current dataPosition().
1899 */
1900 public final Size readSize() {
1901 final int width = readInt();
1902 final int height = readInt();
1903 return new Size(width, height);
1904 }
1905
1906 /**
1907 * Read a SizeF from the parcel at the current dataPosition().
1908 */
1909 public final SizeF readSizeF() {
1910 final float width = readFloat();
1911 final float height = readFloat();
1912 return new SizeF(width, height);
1913 }
1914
1915 /**
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001916 * Read and return a byte[] object from the parcel.
1917 */
Jeff Sharkey047238c2012-03-07 16:51:38 -08001918 public final byte[] createByteArray() {
1919 return nativeCreateByteArray(mNativePtr);
1920 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001921
1922 /**
1923 * Read a byte[] object from the parcel and copy it into the
1924 * given byte array.
1925 */
1926 public final void readByteArray(byte[] val) {
1927 // TODO: make this a native method to avoid the extra copy.
1928 byte[] ba = createByteArray();
1929 if (ba.length == val.length) {
1930 System.arraycopy(ba, 0, val, 0, ba.length);
1931 } else {
1932 throw new RuntimeException("bad array lengths");
1933 }
1934 }
1935
1936 /**
Sandeep Siddhartha90d7a3e2014-07-25 16:19:42 -07001937 * Read a blob of data from the parcel and return it as a byte array.
1938 * {@hide}
Sandeep Siddhartha39c12fa2014-07-25 18:37:29 -07001939 * {@SystemApi}
Sandeep Siddhartha90d7a3e2014-07-25 16:19:42 -07001940 */
1941 public final byte[] readBlob() {
1942 return nativeReadBlob(mNativePtr);
1943 }
1944
1945 /**
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001946 * Read and return a String[] object from the parcel.
1947 * {@hide}
1948 */
1949 public final String[] readStringArray() {
1950 String[] array = null;
1951
1952 int length = readInt();
1953 if (length >= 0)
1954 {
1955 array = new String[length];
1956
1957 for (int i = 0 ; i < length ; i++)
1958 {
1959 array[i] = readString();
1960 }
1961 }
1962
1963 return array;
1964 }
1965
1966 /**
Bjorn Bringert08bbffb2010-02-25 11:16:22 +00001967 * Read and return a CharSequence[] object from the parcel.
1968 * {@hide}
1969 */
1970 public final CharSequence[] readCharSequenceArray() {
1971 CharSequence[] array = null;
1972
1973 int length = readInt();
1974 if (length >= 0)
1975 {
1976 array = new CharSequence[length];
1977
1978 for (int i = 0 ; i < length ; i++)
1979 {
1980 array[i] = readCharSequence();
1981 }
1982 }
1983
1984 return array;
1985 }
1986
1987 /**
Dianne Hackborn3d07c942015-03-13 18:02:54 -07001988 * Read and return an ArrayList&lt;CharSequence&gt; object from the parcel.
1989 * {@hide}
1990 */
1991 public final ArrayList<CharSequence> readCharSequenceList() {
1992 ArrayList<CharSequence> array = null;
1993
1994 int length = readInt();
1995 if (length >= 0) {
1996 array = new ArrayList<CharSequence>(length);
1997
1998 for (int i = 0 ; i < length ; i++) {
1999 array.add(readCharSequence());
2000 }
2001 }
2002
2003 return array;
2004 }
2005
2006 /**
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002007 * Read and return a new ArrayList object from the parcel at the current
2008 * dataPosition(). Returns null if the previously written list object was
2009 * null. The given class loader will be used to load any enclosed
2010 * Parcelables.
2011 */
2012 public final ArrayList readArrayList(ClassLoader loader) {
2013 int N = readInt();
2014 if (N < 0) {
2015 return null;
2016 }
2017 ArrayList l = new ArrayList(N);
2018 readListInternal(l, N, loader);
2019 return l;
2020 }
2021
2022 /**
2023 * Read and return a new Object array from the parcel at the current
2024 * dataPosition(). Returns null if the previously written array was
2025 * null. The given class loader will be used to load any enclosed
2026 * Parcelables.
2027 */
2028 public final Object[] readArray(ClassLoader loader) {
2029 int N = readInt();
2030 if (N < 0) {
2031 return null;
2032 }
2033 Object[] l = new Object[N];
2034 readArrayInternal(l, N, loader);
2035 return l;
2036 }
2037
2038 /**
2039 * Read and return a new SparseArray object from the parcel at the current
2040 * dataPosition(). Returns null if the previously written list object was
2041 * null. The given class loader will be used to load any enclosed
2042 * Parcelables.
2043 */
2044 public final SparseArray readSparseArray(ClassLoader loader) {
2045 int N = readInt();
2046 if (N < 0) {
2047 return null;
2048 }
2049 SparseArray sa = new SparseArray(N);
2050 readSparseArrayInternal(sa, N, loader);
2051 return sa;
2052 }
2053
2054 /**
2055 * Read and return a new SparseBooleanArray object from the parcel at the current
2056 * dataPosition(). Returns null if the previously written list object was
2057 * null.
2058 */
2059 public final SparseBooleanArray readSparseBooleanArray() {
2060 int N = readInt();
2061 if (N < 0) {
2062 return null;
2063 }
2064 SparseBooleanArray sa = new SparseBooleanArray(N);
2065 readSparseBooleanArrayInternal(sa, N);
2066 return sa;
2067 }
2068
2069 /**
2070 * Read and return a new ArrayList containing a particular object type from
2071 * the parcel that was written with {@link #writeTypedList} at the
2072 * current dataPosition(). Returns null if the
2073 * previously written list object was null. The list <em>must</em> have
2074 * previously been written via {@link #writeTypedList} with the same object
2075 * type.
2076 *
2077 * @return A newly created ArrayList containing objects with the same data
2078 * as those that were previously written.
2079 *
2080 * @see #writeTypedList
2081 */
2082 public final <T> ArrayList<T> createTypedArrayList(Parcelable.Creator<T> c) {
2083 int N = readInt();
2084 if (N < 0) {
2085 return null;
2086 }
2087 ArrayList<T> l = new ArrayList<T>(N);
2088 while (N > 0) {
2089 if (readInt() != 0) {
2090 l.add(c.createFromParcel(this));
2091 } else {
2092 l.add(null);
2093 }
2094 N--;
2095 }
2096 return l;
2097 }
2098
2099 /**
2100 * Read into the given List items containing a particular object type
2101 * that were written with {@link #writeTypedList} at the
2102 * current dataPosition(). The list <em>must</em> have
2103 * previously been written via {@link #writeTypedList} with the same object
2104 * type.
2105 *
2106 * @return A newly created ArrayList containing objects with the same data
2107 * as those that were previously written.
2108 *
2109 * @see #writeTypedList
2110 */
2111 public final <T> void readTypedList(List<T> list, Parcelable.Creator<T> c) {
2112 int M = list.size();
2113 int N = readInt();
2114 int i = 0;
2115 for (; i < M && i < N; i++) {
2116 if (readInt() != 0) {
2117 list.set(i, c.createFromParcel(this));
2118 } else {
2119 list.set(i, null);
2120 }
2121 }
2122 for (; i<N; i++) {
2123 if (readInt() != 0) {
2124 list.add(c.createFromParcel(this));
2125 } else {
2126 list.add(null);
2127 }
2128 }
2129 for (; i<M; i++) {
2130 list.remove(N);
2131 }
2132 }
2133
2134 /**
2135 * Read and return a new ArrayList containing String objects from
2136 * the parcel that was written with {@link #writeStringList} at the
2137 * current dataPosition(). Returns null if the
2138 * previously written list object was null.
2139 *
2140 * @return A newly created ArrayList containing strings with the same data
2141 * as those that were previously written.
2142 *
2143 * @see #writeStringList
2144 */
2145 public final ArrayList<String> createStringArrayList() {
2146 int N = readInt();
2147 if (N < 0) {
2148 return null;
2149 }
2150 ArrayList<String> l = new ArrayList<String>(N);
2151 while (N > 0) {
2152 l.add(readString());
2153 N--;
2154 }
2155 return l;
2156 }
2157
2158 /**
2159 * Read and return a new ArrayList containing IBinder objects from
2160 * the parcel that was written with {@link #writeBinderList} at the
2161 * current dataPosition(). Returns null if the
2162 * previously written list object was null.
2163 *
2164 * @return A newly created ArrayList containing strings with the same data
2165 * as those that were previously written.
2166 *
2167 * @see #writeBinderList
2168 */
2169 public final ArrayList<IBinder> createBinderArrayList() {
2170 int N = readInt();
2171 if (N < 0) {
2172 return null;
2173 }
2174 ArrayList<IBinder> l = new ArrayList<IBinder>(N);
2175 while (N > 0) {
2176 l.add(readStrongBinder());
2177 N--;
2178 }
2179 return l;
2180 }
2181
2182 /**
2183 * Read into the given List items String objects that were written with
2184 * {@link #writeStringList} at the current dataPosition().
2185 *
2186 * @return A newly created ArrayList containing strings with the same data
2187 * as those that were previously written.
2188 *
2189 * @see #writeStringList
2190 */
2191 public final void readStringList(List<String> list) {
2192 int M = list.size();
2193 int N = readInt();
2194 int i = 0;
2195 for (; i < M && i < N; i++) {
2196 list.set(i, readString());
2197 }
2198 for (; i<N; i++) {
2199 list.add(readString());
2200 }
2201 for (; i<M; i++) {
2202 list.remove(N);
2203 }
2204 }
2205
2206 /**
2207 * Read into the given List items IBinder objects that were written with
2208 * {@link #writeBinderList} at the current dataPosition().
2209 *
2210 * @return A newly created ArrayList containing strings with the same data
2211 * as those that were previously written.
2212 *
2213 * @see #writeBinderList
2214 */
2215 public final void readBinderList(List<IBinder> list) {
2216 int M = list.size();
2217 int N = readInt();
2218 int i = 0;
2219 for (; i < M && i < N; i++) {
2220 list.set(i, readStrongBinder());
2221 }
2222 for (; i<N; i++) {
2223 list.add(readStrongBinder());
2224 }
2225 for (; i<M; i++) {
2226 list.remove(N);
2227 }
2228 }
2229
2230 /**
2231 * Read and return a new array containing a particular object type from
2232 * the parcel at the current dataPosition(). Returns null if the
2233 * previously written array was null. The array <em>must</em> have
2234 * previously been written via {@link #writeTypedArray} with the same
2235 * object type.
2236 *
2237 * @return A newly created array containing objects with the same data
2238 * as those that were previously written.
2239 *
2240 * @see #writeTypedArray
2241 */
2242 public final <T> T[] createTypedArray(Parcelable.Creator<T> c) {
2243 int N = readInt();
2244 if (N < 0) {
2245 return null;
2246 }
2247 T[] l = c.newArray(N);
2248 for (int i=0; i<N; i++) {
2249 if (readInt() != 0) {
2250 l[i] = c.createFromParcel(this);
2251 }
2252 }
2253 return l;
2254 }
2255
2256 public final <T> void readTypedArray(T[] val, Parcelable.Creator<T> c) {
2257 int N = readInt();
2258 if (N == val.length) {
2259 for (int i=0; i<N; i++) {
2260 if (readInt() != 0) {
2261 val[i] = c.createFromParcel(this);
2262 } else {
2263 val[i] = null;
2264 }
2265 }
2266 } else {
2267 throw new RuntimeException("bad array lengths");
2268 }
2269 }
2270
2271 /**
2272 * @deprecated
2273 * @hide
2274 */
2275 @Deprecated
2276 public final <T> T[] readTypedArray(Parcelable.Creator<T> c) {
2277 return createTypedArray(c);
2278 }
2279
2280 /**
Jens Ole Lauridsen8dea8742015-04-20 11:18:51 -07002281 * Read and return a typed Parcelable object from a parcel.
2282 * Returns null if the previous written object was null.
2283 * The object <em>must</em> have previous been written via
2284 * {@link #writeTypedObject} with the same object type.
2285 *
2286 * @return A newly created object of the type that was previously
2287 * written.
2288 *
2289 * @see #writeTypedObject
2290 */
2291 public final <T> T readTypedObject(Parcelable.Creator<T> c) {
2292 if (readInt() != 0) {
2293 return c.createFromParcel(this);
2294 } else {
2295 return null;
2296 }
2297 }
2298
2299 /**
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002300 * Write a heterogeneous array of Parcelable objects into the Parcel.
2301 * Each object in the array is written along with its class name, so
2302 * that the correct class can later be instantiated. As a result, this
2303 * has significantly more overhead than {@link #writeTypedArray}, but will
2304 * correctly handle an array containing more than one type of object.
2305 *
2306 * @param value The array of objects to be written.
2307 * @param parcelableFlags Contextual flags as per
2308 * {@link Parcelable#writeToParcel(Parcel, int) Parcelable.writeToParcel()}.
2309 *
2310 * @see #writeTypedArray
2311 */
2312 public final <T extends Parcelable> void writeParcelableArray(T[] value,
2313 int parcelableFlags) {
2314 if (value != null) {
2315 int N = value.length;
2316 writeInt(N);
2317 for (int i=0; i<N; i++) {
2318 writeParcelable(value[i], parcelableFlags);
2319 }
2320 } else {
2321 writeInt(-1);
2322 }
2323 }
2324
2325 /**
2326 * Read a typed object from a parcel. The given class loader will be
2327 * used to load any enclosed Parcelables. If it is null, the default class
2328 * loader will be used.
2329 */
2330 public final Object readValue(ClassLoader loader) {
2331 int type = readInt();
2332
2333 switch (type) {
2334 case VAL_NULL:
2335 return null;
2336
2337 case VAL_STRING:
2338 return readString();
2339
2340 case VAL_INTEGER:
2341 return readInt();
2342
2343 case VAL_MAP:
2344 return readHashMap(loader);
2345
2346 case VAL_PARCELABLE:
2347 return readParcelable(loader);
2348
2349 case VAL_SHORT:
2350 return (short) readInt();
2351
2352 case VAL_LONG:
2353 return readLong();
2354
2355 case VAL_FLOAT:
2356 return readFloat();
2357
2358 case VAL_DOUBLE:
2359 return readDouble();
2360
2361 case VAL_BOOLEAN:
2362 return readInt() == 1;
2363
2364 case VAL_CHARSEQUENCE:
Bjorn Bringert08bbffb2010-02-25 11:16:22 +00002365 return readCharSequence();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002366
2367 case VAL_LIST:
2368 return readArrayList(loader);
2369
2370 case VAL_BOOLEANARRAY:
Samuel Tana8036662015-11-23 14:36:00 -08002371 return createBooleanArray();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002372
2373 case VAL_BYTEARRAY:
2374 return createByteArray();
2375
2376 case VAL_STRINGARRAY:
2377 return readStringArray();
2378
Bjorn Bringert08bbffb2010-02-25 11:16:22 +00002379 case VAL_CHARSEQUENCEARRAY:
2380 return readCharSequenceArray();
2381
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002382 case VAL_IBINDER:
2383 return readStrongBinder();
2384
2385 case VAL_OBJECTARRAY:
2386 return readArray(loader);
2387
2388 case VAL_INTARRAY:
2389 return createIntArray();
2390
2391 case VAL_LONGARRAY:
2392 return createLongArray();
2393
2394 case VAL_BYTE:
2395 return readByte();
2396
2397 case VAL_SERIALIZABLE:
John Spurlock5002b8c2014-01-10 13:32:12 -05002398 return readSerializable(loader);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002399
2400 case VAL_PARCELABLEARRAY:
2401 return readParcelableArray(loader);
2402
2403 case VAL_SPARSEARRAY:
2404 return readSparseArray(loader);
2405
2406 case VAL_SPARSEBOOLEANARRAY:
2407 return readSparseBooleanArray();
2408
2409 case VAL_BUNDLE:
2410 return readBundle(loader); // loading will be deferred
2411
Craig Mautner719e6b12014-04-04 20:29:41 -07002412 case VAL_PERSISTABLEBUNDLE:
2413 return readPersistableBundle(loader);
2414
Jeff Sharkey5ef33982014-09-04 18:13:39 -07002415 case VAL_SIZE:
2416 return readSize();
2417
2418 case VAL_SIZEF:
2419 return readSizeF();
2420
Samuel Tana8036662015-11-23 14:36:00 -08002421 case VAL_DOUBLEARRAY:
2422 return createDoubleArray();
2423
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002424 default:
2425 int off = dataPosition() - 4;
2426 throw new RuntimeException(
2427 "Parcel " + this + ": Unmarshalling unknown type code " + type + " at offset " + off);
2428 }
2429 }
2430
2431 /**
2432 * Read and return a new Parcelable from the parcel. The given class loader
2433 * will be used to load any enclosed Parcelables. If it is null, the default
2434 * class loader will be used.
2435 * @param loader A ClassLoader from which to instantiate the Parcelable
2436 * object, or null for the default class loader.
2437 * @return Returns the newly created Parcelable, or null if a null
2438 * object has been written.
2439 * @throws BadParcelableException Throws BadParcelableException if there
2440 * was an error trying to instantiate the Parcelable.
2441 */
Neil Fuller44e440c2015-04-20 14:39:00 +01002442 @SuppressWarnings("unchecked")
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002443 public final <T extends Parcelable> T readParcelable(ClassLoader loader) {
Neil Fuller44e440c2015-04-20 14:39:00 +01002444 Parcelable.Creator<?> creator = readParcelableCreator(loader);
Dianne Hackbornd8e1dbb2013-01-17 17:47:37 -08002445 if (creator == null) {
2446 return null;
2447 }
2448 if (creator instanceof Parcelable.ClassLoaderCreator<?>) {
Neil Fuller44e440c2015-04-20 14:39:00 +01002449 Parcelable.ClassLoaderCreator<?> classLoaderCreator =
2450 (Parcelable.ClassLoaderCreator<?>) creator;
2451 return (T) classLoaderCreator.createFromParcel(this, loader);
Dianne Hackbornd8e1dbb2013-01-17 17:47:37 -08002452 }
Neil Fuller44e440c2015-04-20 14:39:00 +01002453 return (T) creator.createFromParcel(this);
Dianne Hackbornd8e1dbb2013-01-17 17:47:37 -08002454 }
2455
2456 /** @hide */
Neil Fuller44e440c2015-04-20 14:39:00 +01002457 @SuppressWarnings("unchecked")
2458 public final <T extends Parcelable> T readCreator(Parcelable.Creator<?> creator,
Dianne Hackbornd8e1dbb2013-01-17 17:47:37 -08002459 ClassLoader loader) {
2460 if (creator instanceof Parcelable.ClassLoaderCreator<?>) {
Neil Fuller44e440c2015-04-20 14:39:00 +01002461 Parcelable.ClassLoaderCreator<?> classLoaderCreator =
2462 (Parcelable.ClassLoaderCreator<?>) creator;
2463 return (T) classLoaderCreator.createFromParcel(this, loader);
Dianne Hackbornd8e1dbb2013-01-17 17:47:37 -08002464 }
Neil Fuller44e440c2015-04-20 14:39:00 +01002465 return (T) creator.createFromParcel(this);
Dianne Hackbornd8e1dbb2013-01-17 17:47:37 -08002466 }
2467
2468 /** @hide */
Neil Fuller44e440c2015-04-20 14:39:00 +01002469 public final Parcelable.Creator<?> readParcelableCreator(ClassLoader loader) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002470 String name = readString();
2471 if (name == null) {
2472 return null;
2473 }
Neil Fuller44e440c2015-04-20 14:39:00 +01002474 Parcelable.Creator<?> creator;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002475 synchronized (mCreators) {
Neil Fuller44e440c2015-04-20 14:39:00 +01002476 HashMap<String,Parcelable.Creator<?>> map = mCreators.get(loader);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002477 if (map == null) {
Neil Fuller44e440c2015-04-20 14:39:00 +01002478 map = new HashMap<>();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002479 mCreators.put(loader, map);
2480 }
2481 creator = map.get(name);
2482 if (creator == null) {
2483 try {
Neil Fuller44e440c2015-04-20 14:39:00 +01002484 // If loader == null, explicitly emulate Class.forName(String) "caller
2485 // classloader" behavior.
2486 ClassLoader parcelableClassLoader =
2487 (loader == null ? getClass().getClassLoader() : loader);
2488 // Avoid initializing the Parcelable class until we know it implements
2489 // Parcelable and has the necessary CREATOR field. http://b/1171613.
2490 Class<?> parcelableClass = Class.forName(name, false /* initialize */,
2491 parcelableClassLoader);
2492 if (!Parcelable.class.isAssignableFrom(parcelableClass)) {
2493 throw new BadParcelableException("Parcelable protocol requires that the "
2494 + "class implements Parcelable");
2495 }
2496 Field f = parcelableClass.getField("CREATOR");
2497 if ((f.getModifiers() & Modifier.STATIC) == 0) {
2498 throw new BadParcelableException("Parcelable protocol requires "
2499 + "the CREATOR object to be static on class " + name);
2500 }
2501 Class<?> creatorType = f.getType();
2502 if (!Parcelable.Creator.class.isAssignableFrom(creatorType)) {
2503 // Fail before calling Field.get(), not after, to avoid initializing
2504 // parcelableClass unnecessarily.
2505 throw new BadParcelableException("Parcelable protocol requires a "
2506 + "Parcelable.Creator object called "
2507 + "CREATOR on class " + name);
2508 }
2509 creator = (Parcelable.Creator<?>) f.get(null);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002510 }
2511 catch (IllegalAccessException e) {
Neil Fuller44e440c2015-04-20 14:39:00 +01002512 Log.e(TAG, "Illegal access when unmarshalling: " + name, e);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002513 throw new BadParcelableException(
2514 "IllegalAccessException when unmarshalling: " + name);
2515 }
2516 catch (ClassNotFoundException e) {
Neil Fuller44e440c2015-04-20 14:39:00 +01002517 Log.e(TAG, "Class not found when unmarshalling: " + name, e);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002518 throw new BadParcelableException(
2519 "ClassNotFoundException when unmarshalling: " + name);
2520 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002521 catch (NoSuchFieldException e) {
2522 throw new BadParcelableException("Parcelable protocol requires a "
Neil Fuller44e440c2015-04-20 14:39:00 +01002523 + "Parcelable.Creator object called "
2524 + "CREATOR on class " + name);
Irfan Sheriff97a72f62013-01-11 10:45:51 -08002525 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002526 if (creator == null) {
2527 throw new BadParcelableException("Parcelable protocol requires a "
Neil Fuller44e440c2015-04-20 14:39:00 +01002528 + "non-null Parcelable.Creator object called "
2529 + "CREATOR on class " + name);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002530 }
2531
2532 map.put(name, creator);
2533 }
2534 }
2535
Dianne Hackbornd8e1dbb2013-01-17 17:47:37 -08002536 return creator;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002537 }
2538
2539 /**
2540 * Read and return a new Parcelable array from the parcel.
2541 * The given class loader will be used to load any enclosed
2542 * Parcelables.
2543 * @return the Parcelable array, or null if the array is null
2544 */
2545 public final Parcelable[] readParcelableArray(ClassLoader loader) {
2546 int N = readInt();
2547 if (N < 0) {
2548 return null;
2549 }
2550 Parcelable[] p = new Parcelable[N];
2551 for (int i = 0; i < N; i++) {
Neil Fuller44e440c2015-04-20 14:39:00 +01002552 p[i] = readParcelable(loader);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002553 }
2554 return p;
2555 }
2556
2557 /**
2558 * Read and return a new Serializable object from the parcel.
2559 * @return the Serializable object, or null if the Serializable name
2560 * wasn't found in the parcel.
2561 */
2562 public final Serializable readSerializable() {
John Spurlock5002b8c2014-01-10 13:32:12 -05002563 return readSerializable(null);
2564 }
2565
2566 private final Serializable readSerializable(final ClassLoader loader) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002567 String name = readString();
2568 if (name == null) {
2569 // For some reason we were unable to read the name of the Serializable (either there
2570 // is nothing left in the Parcel to read, or the next value wasn't a String), so
2571 // return null, which indicates that the name wasn't found in the parcel.
2572 return null;
2573 }
2574
2575 byte[] serializedData = createByteArray();
2576 ByteArrayInputStream bais = new ByteArrayInputStream(serializedData);
2577 try {
John Spurlock5002b8c2014-01-10 13:32:12 -05002578 ObjectInputStream ois = new ObjectInputStream(bais) {
2579 @Override
2580 protected Class<?> resolveClass(ObjectStreamClass osClass)
2581 throws IOException, ClassNotFoundException {
2582 // try the custom classloader if provided
2583 if (loader != null) {
2584 Class<?> c = Class.forName(osClass.getName(), false, loader);
2585 if (c != null) {
2586 return c;
2587 }
2588 }
2589 return super.resolveClass(osClass);
2590 }
2591 };
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002592 return (Serializable) ois.readObject();
2593 } catch (IOException ioe) {
2594 throw new RuntimeException("Parcelable encountered " +
2595 "IOException reading a Serializable object (name = " + name +
2596 ")", ioe);
2597 } catch (ClassNotFoundException cnfe) {
John Spurlock5002b8c2014-01-10 13:32:12 -05002598 throw new RuntimeException("Parcelable encountered " +
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002599 "ClassNotFoundException reading a Serializable object (name = "
2600 + name + ")", cnfe);
2601 }
2602 }
2603
2604 // Cache of previously looked up CREATOR.createFromParcel() methods for
2605 // particular classes. Keys are the names of the classes, values are
2606 // Method objects.
Neil Fuller44e440c2015-04-20 14:39:00 +01002607 private static final HashMap<ClassLoader,HashMap<String,Parcelable.Creator<?>>>
2608 mCreators = new HashMap<>();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002609
Narayan Kamathb34a4612014-01-23 14:17:11 +00002610 /** @hide for internal use only. */
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002611 static protected final Parcel obtain(int obj) {
Ashok Bhat8ab665d2014-01-22 16:00:20 +00002612 throw new UnsupportedOperationException();
2613 }
2614
2615 /** @hide */
2616 static protected final Parcel obtain(long obj) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002617 final Parcel[] pool = sHolderPool;
2618 synchronized (pool) {
2619 Parcel p;
2620 for (int i=0; i<POOL_SIZE; i++) {
2621 p = pool[i];
2622 if (p != null) {
2623 pool[i] = null;
2624 if (DEBUG_RECYCLE) {
2625 p.mStack = new RuntimeException();
2626 }
2627 p.init(obj);
2628 return p;
2629 }
2630 }
2631 }
2632 return new Parcel(obj);
2633 }
2634
Ashok Bhat8ab665d2014-01-22 16:00:20 +00002635 private Parcel(long nativePtr) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002636 if (DEBUG_RECYCLE) {
2637 mStack = new RuntimeException();
2638 }
Brad Fitzpatrick5b747192010-07-12 11:05:38 -07002639 //Log.i(TAG, "Initializing obj=0x" + Integer.toHexString(obj), mStack);
Jeff Sharkey047238c2012-03-07 16:51:38 -08002640 init(nativePtr);
2641 }
2642
Ashok Bhat8ab665d2014-01-22 16:00:20 +00002643 private void init(long nativePtr) {
Jeff Sharkey047238c2012-03-07 16:51:38 -08002644 if (nativePtr != 0) {
2645 mNativePtr = nativePtr;
2646 mOwnsNativeParcelObject = false;
2647 } else {
2648 mNativePtr = nativeCreate();
2649 mOwnsNativeParcelObject = true;
2650 }
2651 }
2652
2653 private void freeBuffer() {
2654 if (mOwnsNativeParcelObject) {
Adrian Roos04505652015-10-22 16:12:01 -07002655 updateNativeSize(nativeFreeBuffer(mNativePtr));
Jeff Sharkey047238c2012-03-07 16:51:38 -08002656 }
2657 }
2658
2659 private void destroy() {
2660 if (mNativePtr != 0) {
2661 if (mOwnsNativeParcelObject) {
2662 nativeDestroy(mNativePtr);
Adrian Roos04505652015-10-22 16:12:01 -07002663 updateNativeSize(0);
Jeff Sharkey047238c2012-03-07 16:51:38 -08002664 }
2665 mNativePtr = 0;
2666 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002667 }
2668
2669 @Override
2670 protected void finalize() throws Throwable {
2671 if (DEBUG_RECYCLE) {
2672 if (mStack != null) {
Brad Fitzpatrick5b747192010-07-12 11:05:38 -07002673 Log.w(TAG, "Client did not call Parcel.recycle()", mStack);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002674 }
2675 }
2676 destroy();
2677 }
2678
Dianne Hackborn6aff9052009-05-22 13:20:23 -07002679 /* package */ void readMapInternal(Map outVal, int N,
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002680 ClassLoader loader) {
2681 while (N > 0) {
2682 Object key = readValue(loader);
2683 Object value = readValue(loader);
2684 outVal.put(key, value);
2685 N--;
2686 }
2687 }
2688
Dianne Hackbornb87655b2013-07-17 19:06:22 -07002689 /* package */ void readArrayMapInternal(ArrayMap outVal, int N,
2690 ClassLoader loader) {
Dianne Hackborne784d1e2013-09-20 18:13:52 -07002691 if (DEBUG_ARRAY_MAP) {
2692 RuntimeException here = new RuntimeException("here");
2693 here.fillInStackTrace();
2694 Log.d(TAG, "Reading " + N + " ArrayMap entries", here);
2695 }
Dianne Hackborn8aee64d2013-10-25 10:41:50 -07002696 int startPos;
Dianne Hackbornb87655b2013-07-17 19:06:22 -07002697 while (N > 0) {
Dianne Hackborn8aee64d2013-10-25 10:41:50 -07002698 if (DEBUG_ARRAY_MAP) startPos = dataPosition();
Dianne Hackborn9c3e74f2014-08-13 15:39:50 -07002699 String key = readString();
Dianne Hackbornb87655b2013-07-17 19:06:22 -07002700 Object value = readValue(loader);
Dianne Hackborn8aee64d2013-10-25 10:41:50 -07002701 if (DEBUG_ARRAY_MAP) Log.d(TAG, " Read #" + (N-1) + " "
2702 + (dataPosition()-startPos) + " bytes: key=0x"
2703 + Integer.toHexString((key != null ? key.hashCode() : 0)) + " " + key);
Dianne Hackbornb87655b2013-07-17 19:06:22 -07002704 outVal.append(key, value);
2705 N--;
2706 }
Dianne Hackborn9c3e74f2014-08-13 15:39:50 -07002707 outVal.validate();
Dianne Hackbornb87655b2013-07-17 19:06:22 -07002708 }
2709
Dianne Hackborne784d1e2013-09-20 18:13:52 -07002710 /* package */ void readArrayMapSafelyInternal(ArrayMap outVal, int N,
2711 ClassLoader loader) {
2712 if (DEBUG_ARRAY_MAP) {
2713 RuntimeException here = new RuntimeException("here");
2714 here.fillInStackTrace();
2715 Log.d(TAG, "Reading safely " + N + " ArrayMap entries", here);
2716 }
2717 while (N > 0) {
Dianne Hackborn9c3e74f2014-08-13 15:39:50 -07002718 String key = readString();
Dianne Hackborne784d1e2013-09-20 18:13:52 -07002719 if (DEBUG_ARRAY_MAP) Log.d(TAG, " Read safe #" + (N-1) + ": key=0x"
2720 + (key != null ? key.hashCode() : 0) + " " + key);
2721 Object value = readValue(loader);
2722 outVal.put(key, value);
2723 N--;
2724 }
2725 }
2726
Dianne Hackborn9c3e74f2014-08-13 15:39:50 -07002727 /**
2728 * @hide For testing only.
2729 */
2730 public void readArrayMap(ArrayMap outVal, ClassLoader loader) {
2731 final int N = readInt();
2732 if (N < 0) {
2733 return;
2734 }
2735 readArrayMapInternal(outVal, N, loader);
2736 }
2737
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002738 private void readListInternal(List outVal, int N,
2739 ClassLoader loader) {
2740 while (N > 0) {
2741 Object value = readValue(loader);
Brad Fitzpatrick5b747192010-07-12 11:05:38 -07002742 //Log.d(TAG, "Unmarshalling value=" + value);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002743 outVal.add(value);
2744 N--;
2745 }
2746 }
2747
2748 private void readArrayInternal(Object[] outVal, int N,
2749 ClassLoader loader) {
2750 for (int i = 0; i < N; i++) {
2751 Object value = readValue(loader);
Brad Fitzpatrick5b747192010-07-12 11:05:38 -07002752 //Log.d(TAG, "Unmarshalling value=" + value);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002753 outVal[i] = value;
2754 }
2755 }
2756
2757 private void readSparseArrayInternal(SparseArray outVal, int N,
2758 ClassLoader loader) {
2759 while (N > 0) {
2760 int key = readInt();
2761 Object value = readValue(loader);
Brad Fitzpatrick5b747192010-07-12 11:05:38 -07002762 //Log.i(TAG, "Unmarshalling key=" + key + " value=" + value);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002763 outVal.append(key, value);
2764 N--;
2765 }
2766 }
2767
2768
2769 private void readSparseBooleanArrayInternal(SparseBooleanArray outVal, int N) {
2770 while (N > 0) {
2771 int key = readInt();
2772 boolean value = this.readByte() == 1;
Brad Fitzpatrick5b747192010-07-12 11:05:38 -07002773 //Log.i(TAG, "Unmarshalling key=" + key + " value=" + value);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002774 outVal.append(key, value);
2775 N--;
2776 }
2777 }
Dan Sandler5ce04302015-04-09 23:50:15 -04002778
2779 /**
2780 * @hide For testing
2781 */
2782 public long getBlobAshmemSize() {
2783 return nativeGetBlobAshmemSize(mNativePtr);
2784 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002785}