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