Merge "Parcel.java: Fix bug where non-nested creators threw NullPointer" am: 97211945a8 am: 715e417609 am: d74c99a05f

Original change: https://android-review.googlesource.com/c/platform/frameworks/base/+/2139755

Change-Id: Ic1f763d19b50cd914398dd46b01746f82f46f547
Signed-off-by: Automerger Merge Worker <android-build-automerger-merge-worker@system.gserviceaccount.com>
This commit is contained in:
Hani Kazmi
2022-07-05 12:01:53 +00:00
committed by Automerger Merge Worker

View File

@@ -33,6 +33,7 @@ import android.util.ArraySet;
import android.util.ExceptionUtils; import android.util.ExceptionUtils;
import android.util.Log; import android.util.Log;
import android.util.MathUtils; import android.util.MathUtils;
import android.util.Pair;
import android.util.Size; import android.util.Size;
import android.util.SizeF; import android.util.SizeF;
import android.util.Slog; import android.util.Slog;
@@ -4865,28 +4866,36 @@ public final class Parcel {
if (name == null) { if (name == null) {
return null; return null;
} }
Parcelable.Creator<?> creator;
HashMap<String, Parcelable.Creator<?>> map; Pair<Parcelable.Creator<?>, Class<?>> creatorAndParcelableClass;
synchronized (mCreators) { synchronized (sPairedCreators) {
map = mCreators.get(loader); HashMap<String, Pair<Parcelable.Creator<?>, Class<?>>> map =
sPairedCreators.get(loader);
if (map == null) { if (map == null) {
map = new HashMap<>(); sPairedCreators.put(loader, new HashMap<>());
mCreators.put(loader, map); mCreators.put(loader, new HashMap<>());
creatorAndParcelableClass = null;
} else {
creatorAndParcelableClass = map.get(name);
} }
creator = map.get(name);
} }
if (creator != null) {
if (creatorAndParcelableClass != null) {
Parcelable.Creator<?> creator = creatorAndParcelableClass.first;
Class<?> parcelableClass = creatorAndParcelableClass.second;
if (clazz != null) { if (clazz != null) {
Class<?> parcelableClass = creator.getClass().getEnclosingClass();
if (!clazz.isAssignableFrom(parcelableClass)) { if (!clazz.isAssignableFrom(parcelableClass)) {
throw new BadTypeParcelableException("Parcelable creator " + name + " is not " throw new BadTypeParcelableException("Parcelable creator " + name + " is not "
+ "a subclass of required class " + clazz.getName() + "a subclass of required class " + clazz.getName()
+ " provided in the parameter"); + " provided in the parameter");
} }
} }
return (Parcelable.Creator<T>) creator; return (Parcelable.Creator<T>) creator;
} }
Parcelable.Creator<?> creator;
Class<?> parcelableClass;
try { try {
// If loader == null, explicitly emulate Class.forName(String) "caller // If loader == null, explicitly emulate Class.forName(String) "caller
// classloader" behavior. // classloader" behavior.
@@ -4894,7 +4903,7 @@ public final class Parcel {
(loader == null ? getClass().getClassLoader() : loader); (loader == null ? getClass().getClassLoader() : loader);
// Avoid initializing the Parcelable class until we know it implements // Avoid initializing the Parcelable class until we know it implements
// Parcelable and has the necessary CREATOR field. http://b/1171613. // Parcelable and has the necessary CREATOR field. http://b/1171613.
Class<?> parcelableClass = Class.forName(name, false /* initialize */, parcelableClass = Class.forName(name, false /* initialize */,
parcelableClassLoader); parcelableClassLoader);
if (!Parcelable.class.isAssignableFrom(parcelableClass)) { if (!Parcelable.class.isAssignableFrom(parcelableClass)) {
throw new BadParcelableException("Parcelable protocol requires subclassing " throw new BadParcelableException("Parcelable protocol requires subclassing "
@@ -4941,8 +4950,9 @@ public final class Parcel {
+ "CREATOR on class " + name); + "CREATOR on class " + name);
} }
synchronized (mCreators) { synchronized (sPairedCreators) {
map.put(name, creator); sPairedCreators.get(loader).put(name, Pair.create(creator, parcelableClass));
mCreators.get(loader).put(name, creator);
} }
return (Parcelable.Creator<T>) creator; return (Parcelable.Creator<T>) creator;
@@ -5093,12 +5103,17 @@ public final class Parcel {
} }
} }
// Cache of previously looked up CREATOR.createFromParcel() methods for
// particular classes. Keys are the names of the classes, values are // Left due to the UnsupportedAppUsage. Do not use anymore - use sPairedCreators instead
// Method objects.
@UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.P) @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.P)
private static final HashMap<ClassLoader,HashMap<String,Parcelable.Creator<?>>> private static final HashMap<ClassLoader, HashMap<String, Parcelable.Creator<?>>>
mCreators = new HashMap<>(); mCreators = new HashMap<>();
// Cache of previously looked up CREATOR.createFromParcel() methods for particular classes.
// Keys are the names of the classes, values are a pair consisting of a parcelable creator,
// and the class of the parcelable type for the object.
private static final HashMap<ClassLoader, HashMap<String,
Pair<Parcelable.Creator<?>, Class<?>>>> sPairedCreators = new HashMap<>();
/** @hide for internal use only. */ /** @hide for internal use only. */
static protected final Parcel obtain(int obj) { static protected final Parcel obtain(int obj) {