1 package org.robolectric.shadows; 2 3 import static android.os.Build.VERSION_CODES.LOLLIPOP; 4 5 import com.android.internal.util.VirtualRefBasePtr; 6 import java.util.HashMap; 7 import java.util.Map; 8 import org.robolectric.annotation.Implementation; 9 import org.robolectric.annotation.Implements; 10 11 @Implements(value = VirtualRefBasePtr.class, isInAndroidSdk = false) 12 public class ShadowVirtualRefBasePtr { 13 private static final Map<Long, RefHolder> POINTERS = new HashMap<>(); 14 private static long nextNativeObj = 10000; 15 16 synchronized public static <T> long put(T object) { 17 long nativePtr = nextNativeObj++; 18 POINTERS.put(nativePtr, new RefHolder<T>(object)); 19 return nativePtr; 20 } 21 22 synchronized public static <T> T get(long nativePtr, Class<T> clazz) { 23 return clazz.cast(POINTERS.get(nativePtr).nativeThing); 24 } 25 26 @Implementation(minSdk = LOLLIPOP) 27 synchronized public static void nIncStrong(long ptr) { 28 if (ptr == 0) return; 29 POINTERS.get(ptr).incr(); 30 } 31 32 @Implementation(minSdk = LOLLIPOP) 33 synchronized public static void nDecStrong(long ptr) { 34 if (ptr == 0) return; 35 if (POINTERS.get(ptr).decr()) { 36 POINTERS.remove(ptr); 37 } 38 } 39 40 private static class RefHolder<T> { 41 T nativeThing; 42 int refCount; 43 44 public RefHolder(T object) { 45 this.nativeThing = object; 46 } 47 48 synchronized public void incr() { 49 refCount++; 50 } 51 52 synchronized public boolean decr() { 53 refCount--; 54 return refCount == 0; 55 } 56 } 57 } 58