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

Commit 31fb142c authored by Bart Sears's avatar Bart Sears Committed by Android (Google) Code Review
Browse files

Merge "Revert "Fix LazyValue ClassLoader issue"" into main

parents c7d6dda4 2fd48af4
Loading
Loading
Loading
Loading
+3 −8
Original line number Diff line number Diff line
@@ -45,8 +45,7 @@ import java.util.function.BiFunction;
 * {@link PersistableBundle} subclass.
 */
@android.ravenwood.annotation.RavenwoodKeepWholeClass
@SuppressWarnings("HiddenSuperclass")
public class BaseBundle implements Parcel.ClassLoaderProvider {
public class BaseBundle {
    /** @hide */
    protected static final String TAG = "Bundle";
    static final boolean DEBUG = false;
@@ -300,9 +299,8 @@ public class BaseBundle implements Parcel.ClassLoaderProvider {

    /**
     * Return the ClassLoader currently associated with this Bundle.
     * @hide
     */
    public ClassLoader getClassLoader() {
    ClassLoader getClassLoader() {
        return mClassLoader;
    }

@@ -416,9 +414,6 @@ public class BaseBundle implements Parcel.ClassLoaderProvider {
            if ((mFlags & Bundle.FLAG_VERIFY_TOKENS_PRESENT) != 0) {
                Intent.maybeMarkAsMissingCreatorToken(object);
            }
        } else if (object instanceof Bundle) {
            Bundle bundle = (Bundle) object;
            bundle.setClassLoaderSameAsContainerBundleWhenRetrievedFirstTime(this);
        }
        return (clazz != null) ? clazz.cast(object) : (T) object;
    }
@@ -492,7 +487,7 @@ public class BaseBundle implements Parcel.ClassLoaderProvider {
        int[] numLazyValues = new int[]{0};
        try {
            parcelledData.readArrayMap(map, count, !parcelledByNative,
                    /* lazy */ ownsParcel, this, numLazyValues);
                    /* lazy */ ownsParcel, mClassLoader, numLazyValues);
        } catch (BadParcelableException e) {
            if (sShouldDefuse) {
                Log.w(TAG, "Failed to parse Bundle, but defusing quietly", e);
+1 −20
Original line number Diff line number Diff line
@@ -141,8 +141,6 @@ public final class Bundle extends BaseBundle implements Cloneable, Parcelable {
        STRIPPED.putInt("STRIPPED", 1);
    }

    private boolean isFirstRetrievedFromABundle = false;

    /**
     * Constructs a new, empty Bundle.
     */
@@ -1022,30 +1020,13 @@ public final class Bundle extends BaseBundle implements Cloneable, Parcelable {
            return null;
        }
        try {
            Bundle bundle = (Bundle) o;
            bundle.setClassLoaderSameAsContainerBundleWhenRetrievedFirstTime(this);
            return bundle;
            return (Bundle) o;
        } catch (ClassCastException e) {
            typeWarning(key, o, "Bundle", e);
            return null;
        }
    }

    /**
     * Set the ClassLoader of a bundle to its container bundle. This is necessary so that when a
     * bundle's ClassLoader is changed, it can be propagated to its children. Do this only when it
     * is retrieved from the container bundle first time though. Once it is accessed outside of its
     * container, its ClassLoader should no longer be changed by its container anymore.
     *
     * @param containerBundle the bundle this bundle is retrieved from.
     */
    void setClassLoaderSameAsContainerBundleWhenRetrievedFirstTime(BaseBundle containerBundle) {
        if (!isFirstRetrievedFromABundle) {
            setClassLoader(containerBundle.getClassLoader());
            isFirstRetrievedFromABundle = true;
        }
    }

    /**
     * Returns the value associated with the given key, or {@code null} if
     * no mapping of the desired type exists for the given key or a {@code null}
+15 −43
Original line number Diff line number Diff line
@@ -4661,7 +4661,7 @@ public final class Parcel {
     * @hide
     */
    @Nullable
    private Object readLazyValue(@Nullable ClassLoaderProvider loaderProvider) {
    public Object readLazyValue(@Nullable ClassLoader loader) {
        int start = dataPosition();
        int type = readInt();
        if (isLengthPrefixed(type)) {
@@ -4672,17 +4672,12 @@ public final class Parcel {
            int end = MathUtils.addOrThrow(dataPosition(), objectLength);
            int valueLength = end - start;
            setDataPosition(end);
            return new LazyValue(this, start, valueLength, type, loaderProvider);
            return new LazyValue(this, start, valueLength, type, loader);
        } else {
            return readValue(type, getClassLoader(loaderProvider), /* clazz */ null);
            return readValue(type, loader, /* clazz */ null);
        }
    }

    @Nullable
    private static ClassLoader getClassLoader(@Nullable ClassLoaderProvider loaderProvider) {
        return loaderProvider == null ? null : loaderProvider.getClassLoader();
    }


    private static final class LazyValue implements BiFunction<Class<?>, Class<?>[], Object> {
        /**
@@ -4696,12 +4691,7 @@ public final class Parcel {
        private final int mPosition;
        private final int mLength;
        private final int mType;
        // this member is set when a bundle that includes a LazyValue is unparceled. But it is used
        // when apply method is called. Between these 2 events, the bundle's ClassLoader could have
        // changed. Let the bundle be a ClassLoaderProvider allows the bundle provides its current
        // ClassLoader at the time apply method is called.
        @NonNull
        private final ClassLoaderProvider mLoaderProvider;
        @Nullable private final ClassLoader mLoader;
        @Nullable private Object mObject;

        /**
@@ -4712,13 +4702,12 @@ public final class Parcel {
         */
        @Nullable private volatile Parcel mSource;

        LazyValue(Parcel source, int position, int length, int type,
                @NonNull ClassLoaderProvider loaderProvider) {
        LazyValue(Parcel source, int position, int length, int type, @Nullable ClassLoader loader) {
            mSource = requireNonNull(source);
            mPosition = position;
            mLength = length;
            mType = type;
            mLoaderProvider = loaderProvider;
            mLoader = loader;
        }

        @Override
@@ -4731,8 +4720,7 @@ public final class Parcel {
                        int restore = source.dataPosition();
                        try {
                            source.setDataPosition(mPosition);
                            mObject = source.readValue(mLoaderProvider.getClassLoader(), clazz,
                                    itemTypes);
                            mObject = source.readValue(mLoader, clazz, itemTypes);
                        } finally {
                            source.setDataPosition(restore);
                        }
@@ -4805,8 +4793,7 @@ public final class Parcel {
                return Objects.equals(mObject, value.mObject);
            }
            // Better safely fail here since this could mean we get different objects.
            if (!Objects.equals(mLoaderProvider.getClassLoader(),
                    value.mLoaderProvider.getClassLoader())) {
            if (!Objects.equals(mLoader, value.mLoader)) {
                return false;
            }
            // Otherwise compare metadata prior to comparing payload.
@@ -4820,24 +4807,10 @@ public final class Parcel {
        @Override
        public int hashCode() {
            // Accessing mSource first to provide memory barrier for mObject
            return Objects.hash(mSource == null, mObject, mLoaderProvider.getClassLoader(), mType,
                    mLength);
            return Objects.hash(mSource == null, mObject, mLoader, mType, mLength);
        }
    }

    /**
     * Provides a ClassLoader.
     * @hide
     */
    public interface ClassLoaderProvider {
        /**
         * Returns a ClassLoader.
         *
         * @return ClassLoader
         */
        ClassLoader getClassLoader();
    }

    /** Same as {@link #readValue(ClassLoader, Class, Class[])} without any item types. */
    private <T> T readValue(int type, @Nullable ClassLoader loader, @Nullable Class<T> clazz) {
        // Avoids allocating Class[0] array
@@ -5578,8 +5551,8 @@ public final class Parcel {
    }

    private void readArrayMapInternal(@NonNull ArrayMap<? super String, Object> outVal,
            int size, @Nullable ClassLoaderProvider loaderProvider) {
        readArrayMap(outVal, size, /* sorted */ true, /* lazy */ false, loaderProvider, null);
            int size, @Nullable ClassLoader loader) {
        readArrayMap(outVal, size, /* sorted */ true, /* lazy */ false, loader, null);
    }

    /**
@@ -5593,12 +5566,11 @@ public final class Parcel {
     * @hide
     */
    void readArrayMap(ArrayMap<? super String, Object> map, int size, boolean sorted,
            boolean lazy, @Nullable ClassLoaderProvider loaderProvider, int[] lazyValueCount) {
            boolean lazy, @Nullable ClassLoader loader, int[] lazyValueCount) {
        ensureWithinMemoryLimit(SIZE_COMPLEX_TYPE, size);
        while (size > 0) {
            String key = readString();
            Object value = (lazy) ? readLazyValue(loaderProvider) : readValue(
                    getClassLoader(loaderProvider));
            Object value = (lazy) ? readLazyValue(loader) : readValue(loader);
            if (value instanceof LazyValue) {
                lazyValueCount[0]++;
            }
@@ -5619,12 +5591,12 @@ public final class Parcel {
     */
    @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.R, trackingBug = 170729553)
    public void readArrayMap(@NonNull ArrayMap<? super String, Object> outVal,
            @Nullable ClassLoaderProvider loaderProvider) {
            @Nullable ClassLoader loader) {
        final int N = readInt();
        if (N < 0) {
            return;
        }
        readArrayMapInternal(outVal, N, loaderProvider);
        readArrayMapInternal(outVal, N, loader);
    }

    /**