Home | History | Annotate | Download | only in shadows
      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