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