Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 31fa5144 authored by Hao Ke's avatar Hao Ke
Browse files

Don't require T to extend Parcelable or Serializable in Parcel

This is because we want to support the use-case where the caller
enforces a specific class type that doesn't implement Parcelable
or Serializable but the child classes written on the payload implement them.

One such use-case that needs this before migrating is
https://cs.android.com/android/platform/superproject/+/master:frameworks/base/core/java/com/android/internal/infra/AndroidFuture.java;l=596;drc=2d6a545e3042d7cc91b54746e774681a05e0ff22:
we need to enforce Throwable class but it doesn't implement Parcelable itself,
while its children written on the wire are expected to.

Test: atest -d android.os.cts.ParcelTest
Bug: 195622897
Change-Id: I150416d0cfb0b87ddbaff1041d8d60aa205f6f39
parent 43981a85
Loading
Loading
Loading
Loading
+2 −2
Original line number Original line Diff line number Diff line
@@ -31590,7 +31590,7 @@ package android.os {
    method @Deprecated public void readMap(@NonNull java.util.Map, @Nullable ClassLoader);
    method @Deprecated public void readMap(@NonNull java.util.Map, @Nullable ClassLoader);
    method public <K, V> void readMap(@NonNull java.util.Map<? super K,? super V>, @Nullable ClassLoader, @NonNull Class<K>, @NonNull Class<V>);
    method public <K, V> void readMap(@NonNull java.util.Map<? super K,? super V>, @Nullable ClassLoader, @NonNull Class<K>, @NonNull Class<V>);
    method @Deprecated @Nullable public <T extends android.os.Parcelable> T readParcelable(@Nullable ClassLoader);
    method @Deprecated @Nullable public <T extends android.os.Parcelable> T readParcelable(@Nullable ClassLoader);
    method @Nullable public <T extends android.os.Parcelable> T readParcelable(@Nullable ClassLoader, @NonNull Class<T>);
    method @Nullable public <T> T readParcelable(@Nullable ClassLoader, @NonNull Class<T>);
    method @Deprecated @Nullable public android.os.Parcelable[] readParcelableArray(@Nullable ClassLoader);
    method @Deprecated @Nullable public android.os.Parcelable[] readParcelableArray(@Nullable ClassLoader);
    method @Nullable public <T> T[] readParcelableArray(@Nullable ClassLoader, @NonNull Class<T>);
    method @Nullable public <T> T[] readParcelableArray(@Nullable ClassLoader, @NonNull Class<T>);
    method @Deprecated @Nullable public android.os.Parcelable.Creator<?> readParcelableCreator(@Nullable ClassLoader);
    method @Deprecated @Nullable public android.os.Parcelable.Creator<?> readParcelableCreator(@Nullable ClassLoader);
@@ -31600,7 +31600,7 @@ package android.os {
    method @Nullable public android.os.PersistableBundle readPersistableBundle();
    method @Nullable public android.os.PersistableBundle readPersistableBundle();
    method @Nullable public android.os.PersistableBundle readPersistableBundle(@Nullable ClassLoader);
    method @Nullable public android.os.PersistableBundle readPersistableBundle(@Nullable ClassLoader);
    method @Deprecated @Nullable public java.io.Serializable readSerializable();
    method @Deprecated @Nullable public java.io.Serializable readSerializable();
    method @Nullable public <T extends java.io.Serializable> T readSerializable(@Nullable ClassLoader, @NonNull Class<T>);
    method @Nullable public <T> T readSerializable(@Nullable ClassLoader, @NonNull Class<T>);
    method @NonNull public android.util.Size readSize();
    method @NonNull public android.util.Size readSize();
    method @NonNull public android.util.SizeF readSizeF();
    method @NonNull public android.util.SizeF readSizeF();
    method @Deprecated @Nullable public <T> android.util.SparseArray<T> readSparseArray(@Nullable ClassLoader);
    method @Deprecated @Nullable public <T> android.util.SparseArray<T> readSparseArray(@Nullable ClassLoader);
+2 −13
Original line number Original line Diff line number Diff line
@@ -4210,8 +4210,7 @@ public final class Parcel {
     * trying to instantiate an element.
     * trying to instantiate an element.
     */
     */
    @Nullable
    @Nullable
    public <T extends Parcelable> T readParcelable(@Nullable ClassLoader loader,
    public <T> T readParcelable(@Nullable ClassLoader loader, @NonNull Class<T> clazz) {
            @NonNull Class<T> clazz) {
        Objects.requireNonNull(clazz);
        Objects.requireNonNull(clazz);
        return readParcelableInternal(loader, clazz);
        return readParcelableInternal(loader, clazz);
    }
    }
@@ -4222,10 +4221,6 @@ public final class Parcel {
    @SuppressWarnings("unchecked")
    @SuppressWarnings("unchecked")
    @Nullable
    @Nullable
    private <T> T readParcelableInternal(@Nullable ClassLoader loader, @Nullable Class<T> clazz) {
    private <T> T readParcelableInternal(@Nullable ClassLoader loader, @Nullable Class<T> clazz) {
        if (clazz != null && !Parcelable.class.isAssignableFrom(clazz)) {
            throw new BadParcelableException("About to unparcel a parcelable object "
                    + " but class required " + clazz.getName() + " is not Parcelable");
        }
        Parcelable.Creator<?> creator = readParcelableCreatorInternal(loader, clazz);
        Parcelable.Creator<?> creator = readParcelableCreatorInternal(loader, clazz);
        if (creator == null) {
        if (creator == null) {
            return null;
            return null;
@@ -4461,8 +4456,7 @@ public final class Parcel {
     * deserializing the object.
     * deserializing the object.
     */
     */
    @Nullable
    @Nullable
    public <T extends Serializable> T readSerializable(@Nullable ClassLoader loader,
    public <T> T readSerializable(@Nullable ClassLoader loader, @NonNull Class<T> clazz) {
            @NonNull Class<T> clazz) {
        Objects.requireNonNull(clazz);
        Objects.requireNonNull(clazz);
        return readSerializableInternal(
        return readSerializableInternal(
                loader == null ? getClass().getClassLoader() : loader, clazz);
                loader == null ? getClass().getClassLoader() : loader, clazz);
@@ -4474,11 +4468,6 @@ public final class Parcel {
    @Nullable
    @Nullable
    private <T> T readSerializableInternal(@Nullable final ClassLoader loader,
    private <T> T readSerializableInternal(@Nullable final ClassLoader loader,
            @Nullable Class<T> clazz) {
            @Nullable Class<T> clazz) {
        if (clazz != null && !Serializable.class.isAssignableFrom(clazz)) {
            throw new BadParcelableException("About to unparcel a serializable object "
                    + " but class required " + clazz.getName() + " is not Serializable");
        }

        String name = readString();
        String name = readString();
        if (name == null) {
        if (name == null) {
            // For some reason we were unable to read the name of the Serializable (either there
            // For some reason we were unable to read the name of the Serializable (either there