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