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