1 package org.robolectric.shadows; 2 3 import static android.os.Build.VERSION_CODES.JELLY_BEAN_MR2; 4 import static android.os.Build.VERSION_CODES.N_MR1; 5 import static android.os.Build.VERSION_CODES.O; 6 import static android.os.Build.VERSION_CODES.P; 7 import static android.os.Build.VERSION_CODES.Q; 8 9 import android.os.Parcel; 10 import android.view.SurfaceControl; 11 import android.view.SurfaceSession; 12 import dalvik.system.CloseGuard; 13 import java.util.concurrent.atomic.AtomicInteger; 14 import org.robolectric.RuntimeEnvironment; 15 import org.robolectric.annotation.Implementation; 16 import org.robolectric.annotation.Implements; 17 import org.robolectric.annotation.ReflectorObject; 18 import org.robolectric.annotation.Resetter; 19 import org.robolectric.util.reflector.Accessor; 20 import org.robolectric.util.reflector.Direct; 21 import org.robolectric.util.reflector.ForType; 22 import org.robolectric.versioning.AndroidVersions.U; 23 24 /** Shadow for {@link android.view.SurfaceControl} */ 25 @Implements(value = SurfaceControl.class, isInAndroidSdk = false, minSdk = JELLY_BEAN_MR2) 26 public class ShadowSurfaceControl { 27 private static final AtomicInteger nativeObject = new AtomicInteger(); 28 29 @ReflectorObject private SurfaceControlReflector surfaceControlReflector; 30 31 @Resetter reset()32 public static void reset() { 33 nativeObject.set(0); 34 } 35 36 @Implementation finalize()37 protected void finalize() throws Throwable { 38 // Suppress noisy CloseGuard errors. 39 CloseGuard closeGuard = surfaceControlReflector.getCloseGuard(); 40 if (closeGuard != null) { 41 closeGuard.close(); 42 } 43 surfaceControlReflector.finalize(); 44 } 45 46 @Implementation(maxSdk = N_MR1) nativeCreate( SurfaceSession session, String name, int w, int h, int format, int flags)47 protected static Number nativeCreate( 48 SurfaceSession session, String name, int w, int h, int format, int flags) { 49 // Return a non-zero value otherwise constructing a SurfaceControl fails with 50 // OutOfResourcesException. 51 return nativeObject.incrementAndGet(); 52 } 53 54 @Implementation(minSdk = O, maxSdk = P) nativeCreate( SurfaceSession session, String name, int w, int h, int format, int flags, long parentObject, int windowType, int ownerUid)55 protected static long nativeCreate( 56 SurfaceSession session, 57 String name, 58 int w, 59 int h, 60 int format, 61 int flags, 62 long parentObject, 63 int windowType, 64 int ownerUid) { 65 // Return a non-zero value otherwise constructing a SurfaceControl fails with 66 // OutOfResourcesException. 67 return nativeObject.incrementAndGet(); 68 } 69 70 @Implementation(minSdk = Q) nativeCreate( SurfaceSession session, String name, int w, int h, int format, int flags, long parentObject, Parcel metadata)71 protected static long nativeCreate( 72 SurfaceSession session, 73 String name, 74 int w, 75 int h, 76 int format, 77 int flags, 78 long parentObject, 79 Parcel metadata) { 80 // Return a non-zero value otherwise constructing a SurfaceControl fails with 81 // OutOfResourcesException. 82 return nativeObject.incrementAndGet(); 83 } 84 initializeNativeObject()85 void initializeNativeObject() { 86 surfaceControlReflector.setNativeObject(nativeObject.incrementAndGet()); 87 if (RuntimeEnvironment.getApiLevel() >= U.SDK_INT) { 88 surfaceControlReflector.setFreeNativeResources(() -> {}); 89 } 90 } 91 92 @ForType(SurfaceControl.class) 93 interface SurfaceControlReflector { 94 @Accessor("mCloseGuard") getCloseGuard()95 CloseGuard getCloseGuard(); 96 97 @Accessor("mNativeObject") setNativeObject(long nativeObject)98 void setNativeObject(long nativeObject); 99 100 @Direct finalize()101 void finalize(); 102 103 @Accessor("mFreeNativeResources") setFreeNativeResources(Runnable runnable)104 void setFreeNativeResources(Runnable runnable); 105 } 106 } 107