Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Use a ConcurrentHashMap in ShadowParcel. #5193

Merged
merged 1 commit into from Aug 6, 2019
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
Expand Up @@ -144,6 +144,23 @@ public synchronized T getNativeObject(long nativeId) {
}
}

/**
* Updates the native object for the given id.
*
* @throws IllegalStateException if no object was registered with the given id before
*/
public synchronized void update(long nativeId, T o) {
T previous = nativeObjToIdMap.get(nativeId);
if (previous == null) {
throw new IllegalStateException("Native id " + nativeId + " was never registered");
}
if (debug) {
System.out.printf("NativeObjRegistry %s: update %d -> %s%n", name, nativeId, o);
idToDebugInfoMap.put(nativeId, new DebugInfo(new Trace(o)));
}
nativeObjToIdMap.put(nativeId, o);
}

/**
* Similar to {@link #getNativeObject(long)} but returns null if object with given id cannot be
* found.
Expand Down
Expand Up @@ -27,15 +27,14 @@
import java.lang.reflect.Modifier;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.LinkedHashMap;
import java.util.List;
import java.util.Locale;
import java.util.Map;
import java.util.Objects;
import org.robolectric.annotation.HiddenApi;
import org.robolectric.annotation.Implementation;
import org.robolectric.annotation.Implements;
import org.robolectric.annotation.RealObject;
import org.robolectric.res.android.NativeObjRegistry;
import org.robolectric.util.ReflectionHelpers;

/**
Expand All @@ -50,8 +49,8 @@ public class ShadowParcel {
private static final String TAG = "Parcel";

@RealObject private Parcel realObject;
private static final Map<Long, ByteBuffer> NATIVE_PTR_TO_PARCEL = new LinkedHashMap<>();
private static long nextNativePtr = 1; // this needs to start above 0, which is a magic number to Parcel
private static final NativeObjRegistry<ByteBuffer> NATIVE_BYTE_BUFFER_REGISTRY =
new NativeObjRegistry<>(ByteBuffer.class);

@Implementation(maxSdk = JELLY_BEAN_MR1)
@SuppressWarnings("TypeParameterUnusedInFormals")
Expand Down Expand Up @@ -153,7 +152,7 @@ public static int nativeDataSize(int nativePtr) {

@Implementation(minSdk = LOLLIPOP)
protected static int nativeDataSize(long nativePtr) {
return NATIVE_PTR_TO_PARCEL.get(nativePtr).dataSize();
return NATIVE_BYTE_BUFFER_REGISTRY.getNativeObject(nativePtr).dataSize();
}

@HiddenApi
Expand All @@ -164,7 +163,7 @@ public static int nativeDataAvail(int nativePtr) {

@Implementation(minSdk = LOLLIPOP)
protected static int nativeDataAvail(long nativePtr) {
return NATIVE_PTR_TO_PARCEL.get(nativePtr).dataAvailable();
return NATIVE_BYTE_BUFFER_REGISTRY.getNativeObject(nativePtr).dataAvailable();
}

@HiddenApi
Expand All @@ -175,7 +174,7 @@ public static int nativeDataPosition(int nativePtr) {

@Implementation(minSdk = LOLLIPOP)
protected static int nativeDataPosition(long nativePtr) {
return NATIVE_PTR_TO_PARCEL.get(nativePtr).dataPosition();
return NATIVE_BYTE_BUFFER_REGISTRY.getNativeObject(nativePtr).dataPosition();
}

@HiddenApi
Expand All @@ -186,7 +185,7 @@ public static int nativeDataCapacity(int nativePtr) {

@Implementation(minSdk = LOLLIPOP)
protected static int nativeDataCapacity(long nativePtr) {
return NATIVE_PTR_TO_PARCEL.get(nativePtr).dataCapacity();
return NATIVE_BYTE_BUFFER_REGISTRY.getNativeObject(nativePtr).dataCapacity();
}

@HiddenApi
Expand All @@ -198,7 +197,7 @@ public static void nativeSetDataSize(int nativePtr, int size) {
@Implementation(minSdk = LOLLIPOP)
@SuppressWarnings("robolectric.ShadowReturnTypeMismatch")
protected static void nativeSetDataSize(long nativePtr, int size) {
NATIVE_PTR_TO_PARCEL.get(nativePtr).setDataSize(size);
NATIVE_BYTE_BUFFER_REGISTRY.getNativeObject(nativePtr).setDataSize(size);
}

@HiddenApi
Expand All @@ -209,7 +208,7 @@ public static void nativeSetDataPosition(int nativePtr, int pos) {

@Implementation(minSdk = LOLLIPOP)
protected static void nativeSetDataPosition(long nativePtr, int pos) {
NATIVE_PTR_TO_PARCEL.get(nativePtr).setDataPosition(pos);
NATIVE_BYTE_BUFFER_REGISTRY.getNativeObject(nativePtr).setDataPosition(pos);
}

@HiddenApi
Expand All @@ -220,7 +219,7 @@ public static void nativeSetDataCapacity(int nativePtr, int size) {

@Implementation(minSdk = LOLLIPOP)
protected static void nativeSetDataCapacity(long nativePtr, int size) {
NATIVE_PTR_TO_PARCEL.get(nativePtr).setDataCapacityAtLeast(size);
NATIVE_BYTE_BUFFER_REGISTRY.getNativeObject(nativePtr).setDataCapacityAtLeast(size);
}

@HiddenApi
Expand All @@ -231,7 +230,7 @@ public static void nativeWriteByteArray(int nativePtr, byte[] b, int offset, int

@Implementation(minSdk = LOLLIPOP)
protected static void nativeWriteByteArray(long nativePtr, byte[] b, int offset, int len) {
NATIVE_PTR_TO_PARCEL.get(nativePtr).writeByteArray(b, offset, len);
NATIVE_BYTE_BUFFER_REGISTRY.getNativeObject(nativePtr).writeByteArray(b, offset, len);
}

// duplicate the writeBlob implementation from latest android, to avoid referencing the
Expand Down Expand Up @@ -271,7 +270,7 @@ public static void nativeWriteInt(int nativePtr, int val) {

@Implementation(minSdk = LOLLIPOP)
protected static void nativeWriteInt(long nativePtr, int val) {
NATIVE_PTR_TO_PARCEL.get(nativePtr).writeInt(val);
NATIVE_BYTE_BUFFER_REGISTRY.getNativeObject(nativePtr).writeInt(val);
}

@HiddenApi
Expand All @@ -282,7 +281,7 @@ public static void nativeWriteLong(int nativePtr, long val) {

@Implementation(minSdk = LOLLIPOP)
protected static void nativeWriteLong(long nativePtr, long val) {
NATIVE_PTR_TO_PARCEL.get(nativePtr).writeLong(val);
NATIVE_BYTE_BUFFER_REGISTRY.getNativeObject(nativePtr).writeLong(val);
}

@HiddenApi
Expand All @@ -293,7 +292,7 @@ public static void nativeWriteFloat(int nativePtr, float val) {

@Implementation(minSdk = LOLLIPOP)
protected static void nativeWriteFloat(long nativePtr, float val) {
NATIVE_PTR_TO_PARCEL.get(nativePtr).writeFloat(val);
NATIVE_BYTE_BUFFER_REGISTRY.getNativeObject(nativePtr).writeFloat(val);
}

@HiddenApi
Expand All @@ -304,7 +303,7 @@ public static void nativeWriteDouble(int nativePtr, double val) {

@Implementation(minSdk = LOLLIPOP)
protected static void nativeWriteDouble(long nativePtr, double val) {
NATIVE_PTR_TO_PARCEL.get(nativePtr).writeDouble(val);
NATIVE_BYTE_BUFFER_REGISTRY.getNativeObject(nativePtr).writeDouble(val);
}

@HiddenApi
Expand All @@ -315,7 +314,7 @@ public static void nativeWriteString(int nativePtr, String val) {

@Implementation(minSdk = LOLLIPOP)
protected static void nativeWriteString(long nativePtr, String val) {
NATIVE_PTR_TO_PARCEL.get(nativePtr).writeString(val);
NATIVE_BYTE_BUFFER_REGISTRY.getNativeObject(nativePtr).writeString(val);
}

@HiddenApi
Expand All @@ -326,7 +325,7 @@ protected static void nativeWriteStrongBinder(int nativePtr, IBinder val) {

@Implementation(minSdk = LOLLIPOP)
protected static void nativeWriteStrongBinder(long nativePtr, IBinder val) {
NATIVE_PTR_TO_PARCEL.get(nativePtr).writeStrongBinder(val);
NATIVE_BYTE_BUFFER_REGISTRY.getNativeObject(nativePtr).writeStrongBinder(val);
}

@HiddenApi
Expand All @@ -337,7 +336,7 @@ public static byte[] nativeCreateByteArray(int nativePtr) {

@Implementation(minSdk = LOLLIPOP)
protected static byte[] nativeCreateByteArray(long nativePtr) {
return NATIVE_PTR_TO_PARCEL.get(nativePtr).createByteArray();
return NATIVE_BYTE_BUFFER_REGISTRY.getNativeObject(nativePtr).createByteArray();
}

// nativeReadBlob was introduced in lollipop, thus no need for a int nativePtr variant
Expand All @@ -348,7 +347,7 @@ protected static byte[] nativeReadBlob(long nativePtr) {

@Implementation(minSdk = O_MR1)
protected static boolean nativeReadByteArray(long nativePtr, byte[] dest, int destLen) {
return NATIVE_PTR_TO_PARCEL.get(nativePtr).readByteArray(dest, destLen);
return NATIVE_BYTE_BUFFER_REGISTRY.getNativeObject(nativePtr).readByteArray(dest, destLen);
}

@HiddenApi
Expand All @@ -359,7 +358,7 @@ public static int nativeReadInt(int nativePtr) {

@Implementation(minSdk = LOLLIPOP)
protected static int nativeReadInt(long nativePtr) {
return NATIVE_PTR_TO_PARCEL.get(nativePtr).readInt();
return NATIVE_BYTE_BUFFER_REGISTRY.getNativeObject(nativePtr).readInt();
}

@HiddenApi
Expand All @@ -370,7 +369,7 @@ public static long nativeReadLong(int nativePtr) {

@Implementation(minSdk = LOLLIPOP)
protected static long nativeReadLong(long nativePtr) {
return NATIVE_PTR_TO_PARCEL.get(nativePtr).readLong();
return NATIVE_BYTE_BUFFER_REGISTRY.getNativeObject(nativePtr).readLong();
}

@HiddenApi
Expand All @@ -381,7 +380,7 @@ public static float nativeReadFloat(int nativePtr) {

@Implementation(minSdk = LOLLIPOP)
protected static float nativeReadFloat(long nativePtr) {
return NATIVE_PTR_TO_PARCEL.get(nativePtr).readFloat();
return NATIVE_BYTE_BUFFER_REGISTRY.getNativeObject(nativePtr).readFloat();
}

@HiddenApi
Expand All @@ -392,7 +391,7 @@ public static double nativeReadDouble(int nativePtr) {

@Implementation(minSdk = LOLLIPOP)
protected static double nativeReadDouble(long nativePtr) {
return NATIVE_PTR_TO_PARCEL.get(nativePtr).readDouble();
return NATIVE_BYTE_BUFFER_REGISTRY.getNativeObject(nativePtr).readDouble();
}

@HiddenApi
Expand All @@ -403,7 +402,7 @@ public static String nativeReadString(int nativePtr) {

@Implementation(minSdk = LOLLIPOP)
protected static String nativeReadString(long nativePtr) {
return NATIVE_PTR_TO_PARCEL.get(nativePtr).readString();
return NATIVE_BYTE_BUFFER_REGISTRY.getNativeObject(nativePtr).readString();
}

@HiddenApi
Expand All @@ -414,14 +413,13 @@ protected static IBinder nativeReadStrongBinder(int nativePtr) {

@Implementation(minSdk = LOLLIPOP)
protected static IBinder nativeReadStrongBinder(long nativePtr) {
return NATIVE_PTR_TO_PARCEL.get(nativePtr).readStrongBinder();
return NATIVE_BYTE_BUFFER_REGISTRY.getNativeObject(nativePtr).readStrongBinder();
}

@Implementation @HiddenApi
synchronized public static Number nativeCreate() {
long nativePtr = nextNativePtr++;
NATIVE_PTR_TO_PARCEL.put(nativePtr, new ByteBuffer());
return castNativePtr(nativePtr);
@Implementation
@HiddenApi
public static Number nativeCreate() {
return castNativePtr(NATIVE_BYTE_BUFFER_REGISTRY.register(new ByteBuffer()));
}

@HiddenApi
Expand All @@ -433,7 +431,7 @@ public static void nativeFreeBuffer(int nativePtr) {
@Implementation(minSdk = LOLLIPOP)
@SuppressWarnings("robolectric.ShadowReturnTypeMismatch")
protected static void nativeFreeBuffer(long nativePtr) {
NATIVE_PTR_TO_PARCEL.get(nativePtr).clear();
NATIVE_BYTE_BUFFER_REGISTRY.getNativeObject(nativePtr).clear();
}

@HiddenApi
Expand All @@ -444,7 +442,7 @@ public static void nativeDestroy(int nativePtr) {

@Implementation(minSdk = LOLLIPOP)
protected static void nativeDestroy(long nativePtr) {
NATIVE_PTR_TO_PARCEL.remove(nativePtr);
NATIVE_BYTE_BUFFER_REGISTRY.unregister(nativePtr);
}

@HiddenApi
Expand All @@ -455,7 +453,7 @@ public static byte[] nativeMarshall(int nativePtr) {

@Implementation(minSdk = LOLLIPOP)
protected static byte[] nativeMarshall(long nativePtr) {
return NATIVE_PTR_TO_PARCEL.get(nativePtr).toByteArray();
return NATIVE_BYTE_BUFFER_REGISTRY.getNativeObject(nativePtr).toByteArray();
}

@HiddenApi
Expand All @@ -467,21 +465,22 @@ public static void nativeUnmarshall(int nativePtr, byte[] data, int offset, int
@Implementation(minSdk = LOLLIPOP)
@SuppressWarnings("robolectric.ShadowReturnTypeMismatch")
protected static void nativeUnmarshall(long nativePtr, byte[] data, int offset, int length) {
NATIVE_PTR_TO_PARCEL.put(nativePtr, ByteBuffer.fromByteArray(data, offset, length));
NATIVE_BYTE_BUFFER_REGISTRY.update(nativePtr, ByteBuffer.fromByteArray(data, offset, length));
}

@HiddenApi
@Implementation(maxSdk = KITKAT_WATCH)
public static void nativeAppendFrom(int thisNativePtr, int otherNativePtr, int offset, int length) {
public static void nativeAppendFrom(
int thisNativePtr, int otherNativePtr, int offset, int length) {
nativeAppendFrom((long) thisNativePtr, otherNativePtr, offset, length);
}

@Implementation(minSdk = LOLLIPOP)
@SuppressWarnings("robolectric.ShadowReturnTypeMismatch")
protected static void nativeAppendFrom(
long thisNativePtr, long otherNativePtr, int offset, int length) {
ByteBuffer thisByteBuffer = NATIVE_PTR_TO_PARCEL.get(thisNativePtr);
ByteBuffer otherByteBuffer = NATIVE_PTR_TO_PARCEL.get(otherNativePtr);
ByteBuffer thisByteBuffer = NATIVE_BYTE_BUFFER_REGISTRY.getNativeObject(thisNativePtr);
ByteBuffer otherByteBuffer = NATIVE_BYTE_BUFFER_REGISTRY.getNativeObject(otherNativePtr);
thisByteBuffer.appendFrom(otherByteBuffer, offset, length);
}

Expand Down