From 36cf3994ed6434f739126d7a1c5ae0fc1d399155 Mon Sep 17 00:00:00 2001 From: Bernardo Rufino Date: Fri, 12 Nov 2021 16:30:16 +0000 Subject: [PATCH] Deprecate unsafe parcel APIs Deprecate unsafe parcel APIs and point to the safer ones that take the expected type as parameter. Where applicable also mention the typed ones that take the creator as argument since those are also more performant. APIs deprecated here are: * readMap(Map, ClassLoader) * readList(List, ClassLoader) * readHashMap(ClassLoader) * readArrayList(ClassLoader) * readArray(ClassLoader) * readSparseArray(ClassLoader) * readParcelable(ClassLoader) * readParcelableCreator(ClassLoader) * readSerializable() Test: Builds Bug: 195622897 Bug: 199275680 Bug: 205985058 Change-Id: Ic41ae13e0d965b1fd346985c77c1eecc605285b2 --- core/api/current.txt | 18 +++++------ core/java/android/os/Parcel.java | 55 ++++++++++++++++++++++++++++++-- 2 files changed, 62 insertions(+), 11 deletions(-) diff --git a/core/api/current.txt b/core/api/current.txt index f21518c7f83d2..1f31faec7402e 100644 --- a/core/api/current.txt +++ b/core/api/current.txt @@ -31446,9 +31446,9 @@ package android.os { method public byte[] marshall(); method @NonNull public static android.os.Parcel obtain(); method @NonNull public static android.os.Parcel obtain(@NonNull android.os.IBinder); - method @Nullable public Object[] readArray(@Nullable ClassLoader); + method @Deprecated @Nullable public Object[] readArray(@Nullable ClassLoader); method @Nullable public T[] readArray(@Nullable ClassLoader, @NonNull Class); - method @Nullable public java.util.ArrayList readArrayList(@Nullable ClassLoader); + method @Deprecated @Nullable public java.util.ArrayList readArrayList(@Nullable ClassLoader); method @Nullable public java.util.ArrayList readArrayList(@Nullable ClassLoader, @NonNull Class); method public void readBinderArray(@NonNull android.os.IBinder[]); method public void readBinderList(@NonNull java.util.List); @@ -31466,32 +31466,32 @@ package android.os { method public android.os.ParcelFileDescriptor readFileDescriptor(); method public float readFloat(); method public void readFloatArray(@NonNull float[]); - method @Nullable public java.util.HashMap readHashMap(@Nullable ClassLoader); + method @Deprecated @Nullable public java.util.HashMap readHashMap(@Nullable ClassLoader); method @Nullable public java.util.HashMap readHashMap(@Nullable ClassLoader, @NonNull Class, @NonNull Class); method public int readInt(); method public void readIntArray(@NonNull int[]); method public void readInterfaceArray(@NonNull T[], @NonNull java.util.function.Function); method public void readInterfaceList(@NonNull java.util.List, @NonNull java.util.function.Function); - method public void readList(@NonNull java.util.List, @Nullable ClassLoader); + method @Deprecated public void readList(@NonNull java.util.List, @Nullable ClassLoader); method public void readList(@NonNull java.util.List, @Nullable ClassLoader, @NonNull Class); method public long readLong(); method public void readLongArray(@NonNull long[]); - method public void readMap(@NonNull java.util.Map, @Nullable ClassLoader); + method @Deprecated public void readMap(@NonNull java.util.Map, @Nullable ClassLoader); method public void readMap(@NonNull java.util.Map, @Nullable ClassLoader, @NonNull Class, @NonNull Class); - method @Nullable public T readParcelable(@Nullable ClassLoader); + method @Deprecated @Nullable public T readParcelable(@Nullable ClassLoader); method @Nullable public T readParcelable(@Nullable ClassLoader, @NonNull Class); method @Nullable public android.os.Parcelable[] readParcelableArray(@Nullable ClassLoader); method @Nullable public T[] readParcelableArray(@Nullable ClassLoader, @NonNull Class); - method @Nullable public android.os.Parcelable.Creator readParcelableCreator(@Nullable ClassLoader); + method @Deprecated @Nullable public android.os.Parcelable.Creator readParcelableCreator(@Nullable ClassLoader); method @Nullable public android.os.Parcelable.Creator readParcelableCreator(@Nullable ClassLoader, @NonNull Class); method @NonNull public java.util.List readParcelableList(@NonNull java.util.List, @Nullable ClassLoader); method @Nullable public android.os.PersistableBundle readPersistableBundle(); method @Nullable public android.os.PersistableBundle readPersistableBundle(@Nullable ClassLoader); - method @Nullable public java.io.Serializable readSerializable(); + method @Deprecated @Nullable public java.io.Serializable readSerializable(); method @Nullable public T readSerializable(@Nullable ClassLoader, @NonNull Class); method @NonNull public android.util.Size readSize(); method @NonNull public android.util.SizeF readSizeF(); - method @Nullable public android.util.SparseArray readSparseArray(@Nullable ClassLoader); + method @Deprecated @Nullable public android.util.SparseArray readSparseArray(@Nullable ClassLoader); method @Nullable public android.util.SparseArray readSparseArray(@Nullable ClassLoader, @NonNull Class); method @Nullable public android.util.SparseBooleanArray readSparseBooleanArray(); method @Nullable public String readString(); diff --git a/core/java/android/os/Parcel.java b/core/java/android/os/Parcel.java index 09e5a8f7382cb..7bdb6b90c07b8 100644 --- a/core/java/android/os/Parcel.java +++ b/core/java/android/os/Parcel.java @@ -2990,7 +2990,12 @@ public final class Parcel { * Please use {@link #readBundle(ClassLoader)} instead (whose data must have * been written with {@link #writeBundle}. Read into an existing Map object * from the parcel at the current dataPosition(). + * + * @deprecated Consider using {@link #readBundle(ClassLoader)} as stated above, in case this + * method is still preferred use the type-safer version {@link #readMap(Map, ClassLoader, + * Class, Class)} starting from Android {@link Build.VERSION_CODES#TIRAMISU}. */ + @Deprecated public final void readMap(@NonNull Map outVal, @Nullable ClassLoader loader) { int n = readInt(); readMapInternal(outVal, n, loader, /* clazzKey */ null, /* clazzValue */ null); @@ -3016,7 +3021,14 @@ public final class Parcel { * Read into an existing List object from the parcel at the current * dataPosition(), using the given class loader to load any enclosed * Parcelables. If it is null, the default class loader is used. + * + * @deprecated Use the type-safer version {@link #readList(List, ClassLoader, Class)} starting + * from Android {@link Build.VERSION_CODES#TIRAMISU}. Also consider changing the format to + * use {@link #readTypedList(List, Parcelable.Creator)} if possible (eg. if the items' + * class is final) since this is also more performant. Note that changing to the latter + * also requires changing the writes. */ + @Deprecated public final void readList(@NonNull List outVal, @Nullable ClassLoader loader) { int N = readInt(); readListInternal(outVal, N, loader, /* clazz */ null); @@ -3043,10 +3055,14 @@ public final class Parcel { * object from the parcel at the current dataPosition(), using the given * class loader to load any enclosed Parcelables. Returns null if * the previously written map object was null. + * + * @deprecated Consider using {@link #readBundle(ClassLoader)} as stated above, in case this + * method is still preferred use the type-safer version {@link #readHashMap(ClassLoader, + * Class, Class)} starting from Android {@link Build.VERSION_CODES#TIRAMISU}. */ + @Deprecated @Nullable - public final HashMap readHashMap(@Nullable ClassLoader loader) - { + public HashMap readHashMap(@Nullable ClassLoader loader) { int n = readInt(); if (n < 0) { return null; @@ -3247,7 +3263,14 @@ public final class Parcel { * dataPosition(). Returns null if the previously written list object was * null. The given class loader will be used to load any enclosed * Parcelables. + * + * @deprecated Use the type-safer version {@link #readArrayList(ClassLoader, Class)} starting + * from Android {@link Build.VERSION_CODES#TIRAMISU}. Also consider changing the format to + * use {@link #createTypedArrayList(Parcelable.Creator)} if possible (eg. if the items' + * class is final) since this is also more performant. Note that changing to the latter + * also requires changing the writes. */ + @Deprecated @Nullable public ArrayList readArrayList(@Nullable ClassLoader loader) { return readArrayListInternal(loader, /* clazz */ null); @@ -3274,7 +3297,14 @@ public final class Parcel { * dataPosition(). Returns null if the previously written array was * null. The given class loader will be used to load any enclosed * Parcelables. + * + * @deprecated Use the type-safer version {@link #readArray(ClassLoader, Class)} starting from + * Android {@link Build.VERSION_CODES#TIRAMISU}. Also consider changing the format to use + * {@link #createTypedArray(Parcelable.Creator)} if possible (eg. if the items' class is + * final) since this is also more performant. Note that changing to the latter also + * requires changing the writes. */ + @Deprecated @Nullable public Object[] readArray(@Nullable ClassLoader loader) { return readArrayInternal(loader, /* clazz */ null); @@ -3300,7 +3330,14 @@ public final class Parcel { * dataPosition(). Returns null if the previously written list object was * null. The given class loader will be used to load any enclosed * Parcelables. + * + * @deprecated Use the type-safer version {@link #readSparseArray(ClassLoader, Class)} starting + * from Android {@link Build.VERSION_CODES#TIRAMISU}. Also consider changing the format to + * use {@link #createTypedSparseArray(Parcelable.Creator)} if possible (eg. if the items' + * class is final) since this is also more performant. Note that changing to the latter + * also requires changing the writes. */ + @Deprecated @Nullable public SparseArray readSparseArray(@Nullable ClassLoader loader) { return readSparseArrayInternal(loader, /* clazz */ null); @@ -4107,7 +4144,13 @@ public final class Parcel { * object has been written. * @throws BadParcelableException Throws BadParcelableException if there * was an error trying to instantiate the Parcelable. + * + * @deprecated Use the type-safer version {@link #readParcelable(ClassLoader, Class)} starting + * from Android {@link Build.VERSION_CODES#TIRAMISU}. Also consider changing the format to + * use {@link Parcelable.Creator#createFromParcel(Parcel)} if possible since this is also + * more performant. Note that changing to the latter also requires changing the writes. */ + @Deprecated @Nullable public final T readParcelable(@Nullable ClassLoader loader) { return readParcelableInternal(loader, /* clazz */ null); @@ -4176,7 +4219,11 @@ public final class Parcel { * read the {@link Parcelable.Creator}. * * @see #writeParcelableCreator + * + * @deprecated Use the type-safer version {@link #readParcelableCreator(ClassLoader, Class)} + * starting from Android {@link Build.VERSION_CODES#TIRAMISU}. */ + @Deprecated @Nullable public final Parcelable.Creator readParcelableCreator(@Nullable ClassLoader loader) { return readParcelableCreatorInternal(loader, /* clazz */ null); @@ -4337,7 +4384,11 @@ public final class Parcel { * Read and return a new Serializable object from the parcel. * @return the Serializable object, or null if the Serializable name * wasn't found in the parcel. + * + * @deprecated Use the type-safer version {@link #readSerializable(ClassLoader, Class)} starting + * from Android {@link Build.VERSION_CODES#TIRAMISU}. */ + @Deprecated @Nullable public Serializable readSerializable() { return readSerializableInternal(/* loader */ null, /* clazz */ null);