xref: /aosp_15_r20/cts/tests/surfacecontrol/jni/android_view_cts_ASurfaceControlTest.cpp (revision b7c941bb3fa97aba169d73cee0bed2de8ac964bf)
1 /*
2  * Copyright 2018 The Android Open Source Project
3  *
4  * Licensed under the Apache License, Version 2.0 (the "License");
5  * you may not use this file except in compliance with the License.
6  * You may obtain a copy of the License at
7  *
8  *      http://www.apache.org/licenses/LICENSE-2.0
9  *
10  * Unless required by applicable law or agreed to in writing, software
11  * distributed under the License is distributed on an "AS IS" BASIS,
12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13  * See the License for the specific language governing permissions and
14  * limitations under the License.
15  */
16 
17 #define LOG_TAG "ASurfaceControlTest"
18 
19 #include <ChoreographerTestUtils.h>
20 #include <android/choreographer.h>
21 #include <android/data_space.h>
22 #include <android/display_luts.h>
23 #include <android/hardware_buffer.h>
24 #include <android/hardware_buffer_jni.h>
25 #include <android/log.h>
26 #include <android/looper.h>
27 #include <android/native_window_jni.h>
28 #include <android/surface_control.h>
29 #include <android/surface_control_jni.h>
30 #include <android/sync.h>
31 #include <android/trace.h>
32 #include <errno.h>
33 #include <jni.h>
34 #include <nativehelper/ScopedPrimitiveArray.h>
35 #include <poll.h>
36 #include <sys/time.h>
37 #include <sys/types.h>
38 #include <time.h>
39 #include <unistd.h>
40 
41 #include <array>
42 #include <cinttypes>
43 #include <string>
44 
45 #define ALOGE(...) __android_log_print(ANDROID_LOG_ERROR, LOG_TAG, __VA_ARGS__)
46 
47 namespace {
48 
49 struct {
50     jclass clazz;
51     jmethodID onTransactionComplete;
52     jmethodID shouldQueryTransactionStats;
53     jmethodID onTransactionStatsRead;
54 } gTransactionCompleteListenerClassInfo;
55 
56 struct {
57     jclass clazz;
58     jmethodID onBufferRelease;
59 } gBufferReleaseCallbackClassInfo;
60 
allocateBuffer(int32_t width,int32_t height)61 static AHardwareBuffer* allocateBuffer(int32_t width, int32_t height) {
62     AHardwareBuffer* buffer = nullptr;
63     AHardwareBuffer_Desc desc = {};
64     desc.width = width;
65     desc.height = height;
66     desc.layers = 1;
67     desc.usage = AHARDWAREBUFFER_USAGE_COMPOSER_OVERLAY | AHARDWAREBUFFER_USAGE_CPU_WRITE_OFTEN |
68             AHARDWAREBUFFER_USAGE_GPU_SAMPLED_IMAGE;
69     desc.format = AHARDWAREBUFFER_FORMAT_R8G8B8A8_UNORM;
70 
71     AHardwareBuffer_allocate(&desc, &buffer);
72 
73     return buffer;
74 }
75 
fillRegion(void * data,int32_t left,int32_t top,int32_t right,int32_t bottom,uint32_t color,uint32_t stride)76 static void fillRegion(void* data, int32_t left, int32_t top, int32_t right,
77                        int32_t bottom, uint32_t color, uint32_t stride) {
78     uint32_t* ptr = static_cast<uint32_t*>(data);
79 
80     ptr += stride * top;
81 
82     // Convert color from incoming ARGB format to ABGR
83     uint32_t alpha = (color >> 24);
84     uint32_t red = (color >> 16) & 0xff;
85     uint32_t green = (color >> 8) & 0xff;
86     uint32_t blue = color & 0xff;
87     color = (alpha << 24) | (blue << 16) | (green << 8) | red;
88 
89     for (uint32_t y = top; y < bottom; y++) {
90         for (uint32_t x = left; x < right; x++) {
91             ptr[x] = color;
92         }
93         ptr += stride;
94     }
95 }
96 
getSolidBuffer(int32_t width,int32_t height,uint32_t color,AHardwareBuffer ** outHardwareBuffer,int * outFence)97 static bool getSolidBuffer(int32_t width, int32_t height, uint32_t color,
98                            AHardwareBuffer** outHardwareBuffer,
99                            int* outFence) {
100     AHardwareBuffer* buffer = allocateBuffer(width, height);
101     if (!buffer) {
102         return true;
103     }
104 
105     AHardwareBuffer_Desc desc = {};
106     AHardwareBuffer_describe(buffer, &desc);
107 
108     void* data = nullptr;
109     const ARect rect{0, 0, width, height};
110     AHardwareBuffer_lock(buffer, AHARDWAREBUFFER_USAGE_CPU_WRITE_OFTEN, -1, &rect,
111                                              &data);
112     if (!data) {
113         AHardwareBuffer_release(buffer);
114         return true;
115     }
116 
117     fillRegion(data, 0, 0, width, height, color, desc.stride);
118 
119     AHardwareBuffer_unlock(buffer, outFence);
120 
121     *outHardwareBuffer = buffer;
122     return false;
123 }
124 
Utils_getSolidBuffer(JNIEnv * env,jobject,jint width,jint height,jint color)125 jobject Utils_getSolidBuffer(JNIEnv* env, jobject /*clazz*/, jint width, jint height, jint color) {
126     AHardwareBuffer* buffer;
127     if (getSolidBuffer(width, height, static_cast<uint32_t>(color), &buffer, nullptr)) {
128         return nullptr;
129     }
130     jobject result = AHardwareBuffer_toHardwareBuffer(env, buffer);
131     AHardwareBuffer_release(buffer);
132     return result;
133 }
134 
getQuadrantBuffer(int32_t width,int32_t height,jint colorTopLeft,jint colorTopRight,jint colorBottomRight,jint colorBottomLeft,AHardwareBuffer ** outHardwareBuffer,int * outFence)135 static bool getQuadrantBuffer(int32_t width, int32_t height, jint colorTopLeft,
136                               jint colorTopRight, jint colorBottomRight,
137                               jint colorBottomLeft,
138                               AHardwareBuffer** outHardwareBuffer,
139                               int* outFence) {
140     AHardwareBuffer* buffer = allocateBuffer(width, height);
141     if (!buffer) {
142         return true;
143     }
144 
145     AHardwareBuffer_Desc desc = {};
146     AHardwareBuffer_describe(buffer, &desc);
147 
148     void* data = nullptr;
149     const ARect rect{0, 0, width, height};
150     AHardwareBuffer_lock(buffer, AHARDWAREBUFFER_USAGE_CPU_WRITE_OFTEN, -1, &rect,
151                                              &data);
152     if (!data) {
153         return true;
154     }
155 
156     fillRegion(data, 0, 0, width / 2, height / 2, colorTopLeft, desc.stride);
157     fillRegion(data, width / 2, 0, width, height / 2, colorTopRight, desc.stride);
158     fillRegion(data, 0, height / 2, width / 2, height, colorBottomLeft,
159                          desc.stride);
160     fillRegion(data, width / 2, height / 2, width, height, colorBottomRight,
161                          desc.stride);
162 
163     AHardwareBuffer_unlock(buffer, outFence);
164 
165     *outHardwareBuffer = buffer;
166     return false;
167 }
168 
Utils_getQuadrantBuffer(JNIEnv * env,jobject,jint width,jint height,jint colorTopLeft,jint colorTopRight,jint colorBottomRight,jint colorBottomLeft)169 jobject Utils_getQuadrantBuffer(JNIEnv* env, jobject /*clazz*/, jint width, jint height,
170                                 jint colorTopLeft, jint colorTopRight, jint colorBottomRight,
171                                 jint colorBottomLeft) {
172     AHardwareBuffer* buffer;
173     if (getQuadrantBuffer(width, height, colorTopLeft, colorTopRight, colorBottomRight,
174                           colorBottomLeft, &buffer, nullptr)) {
175         return nullptr;
176     }
177     jobject result = AHardwareBuffer_toHardwareBuffer(env, buffer);
178     AHardwareBuffer_release(buffer);
179     return result;
180 }
181 
Utils_getBufferId(JNIEnv * env,jobject,jobject jHardwareBuffer)182 jlong Utils_getBufferId(JNIEnv* env, jobject /*clazz*/, jobject jHardwareBuffer) {
183     AHardwareBuffer* buffer = AHardwareBuffer_fromHardwareBuffer(env, jHardwareBuffer);
184     uint64_t id = 0;
185     AHardwareBuffer_getId(buffer, &id);
186     return id;
187 }
188 
SurfaceTransaction_create(JNIEnv *,jclass)189 jlong SurfaceTransaction_create(JNIEnv* /*env*/, jclass) {
190     return reinterpret_cast<jlong>(ASurfaceTransaction_create());
191 }
192 
SurfaceTransaction_delete(JNIEnv *,jclass,jlong surfaceTransaction)193 void SurfaceTransaction_delete(JNIEnv* /*env*/, jclass, jlong surfaceTransaction) {
194     ASurfaceTransaction_delete(
195             reinterpret_cast<ASurfaceTransaction*>(surfaceTransaction));
196 }
197 
SurfaceTransaction_fromJava(JNIEnv * env,jclass,jobject transactionObj)198 jlong SurfaceTransaction_fromJava(JNIEnv* env, jclass, jobject transactionObj) {
199     return reinterpret_cast<jlong>(ASurfaceTransaction_fromJava(env, transactionObj));
200 }
201 
SurfaceTransaction_apply(JNIEnv *,jclass,jlong surfaceTransaction)202 void SurfaceTransaction_apply(JNIEnv* /*env*/, jclass, jlong surfaceTransaction) {
203     ASurfaceTransaction_apply(
204             reinterpret_cast<ASurfaceTransaction*>(surfaceTransaction));
205 }
206 
SurfaceControl_createFromWindow(JNIEnv * env,jclass,jobject jSurface)207 long SurfaceControl_createFromWindow(JNIEnv* env, jclass, jobject jSurface) {
208     if (!jSurface) {
209         return 0;
210     }
211 
212     ANativeWindow* window = ANativeWindow_fromSurface(env, jSurface);
213     if (!window) {
214         return 0;
215     }
216 
217     const std::string debugName = "SurfaceControl_createFromWindowLayer";
218     ASurfaceControl* surfaceControl =
219             ASurfaceControl_createFromWindow(window, debugName.c_str());
220     if (!surfaceControl) {
221         return 0;
222     }
223 
224     ANativeWindow_release(window);
225 
226     return reinterpret_cast<jlong>(surfaceControl);
227 }
228 
SurfaceControl_create(JNIEnv *,jclass,jlong parentSurfaceControlId)229 jlong SurfaceControl_create(JNIEnv* /*env*/, jclass, jlong parentSurfaceControlId) {
230     ASurfaceControl* surfaceControl = nullptr;
231     const std::string debugName = "SurfaceControl_create";
232 
233     surfaceControl = ASurfaceControl_create(
234             reinterpret_cast<ASurfaceControl*>(parentSurfaceControlId),
235             debugName.c_str());
236 
237     return reinterpret_cast<jlong>(surfaceControl);
238 }
239 
SurfaceControl_acquire(JNIEnv *,jclass,jlong surfaceControl)240 void SurfaceControl_acquire(JNIEnv* /*env*/, jclass, jlong surfaceControl) {
241     ASurfaceControl_acquire(reinterpret_cast<ASurfaceControl*>(surfaceControl));
242 }
243 
SurfaceControl_fromJava(JNIEnv * env,jclass,jobject surfaceControlObj)244 jlong SurfaceControl_fromJava(JNIEnv* env, jclass, jobject surfaceControlObj) {
245     return reinterpret_cast<jlong>(ASurfaceControl_fromJava(env, surfaceControlObj));
246 }
247 
SurfaceControl_release(JNIEnv *,jclass,jlong surfaceControl)248 void SurfaceControl_release(JNIEnv* /*env*/, jclass, jlong surfaceControl) {
249     ASurfaceControl_release(reinterpret_cast<ASurfaceControl*>(surfaceControl));
250 }
251 
252 class ReleaseCallbackWrapper {
253 public:
ReleaseCallbackWrapper(JNIEnv * env,jobject jObject)254     explicit ReleaseCallbackWrapper(JNIEnv* env, jobject jObject) {
255         env->GetJavaVM(&mVm);
256         mJavaCallbackObject = env->NewGlobalRef(jObject);
257         if (!mJavaCallbackObject) {
258             ALOGE("Failed to make ReleaseCallbackWrapper global ref");
259         }
260     }
261 
~ReleaseCallbackWrapper()262     ~ReleaseCallbackWrapper() { getenv()->DeleteGlobalRef(mJavaCallbackObject); }
263 
callback()264     void callback() {
265         JNIEnv* env = getenv();
266         env->CallVoidMethod(mJavaCallbackObject, gBufferReleaseCallbackClassInfo.onBufferRelease);
267     }
268 
callbackThunk(void * context,int)269     static void callbackThunk(void* context, int /* release_fence_fd */) {
270         if (!context) {
271             ALOGE("Invalid context passed to callback");
272         }
273         ReleaseCallbackWrapper* listener = reinterpret_cast<ReleaseCallbackWrapper*>(context);
274         listener->callback();
275         delete listener;
276     }
277 
278 private:
279     jobject mJavaCallbackObject;
280     JavaVM* mVm;
281 
getenv()282     JNIEnv* getenv() {
283         JNIEnv* env;
284         int result = mVm->GetEnv(reinterpret_cast<void**>(&env), JNI_VERSION_1_6);
285         if (result == JNI_EDETACHED) {
286             if (mVm->AttachCurrentThreadAsDaemon(&env, nullptr) != JNI_OK) {
287                 ALOGE("Failed to AttachCurrentThread!");
288             }
289         } else if (result != JNI_OK) {
290             ALOGE("Failed to get JNIEnv for JavaVM: %p", mVm);
291         }
292 
293         return env;
294     }
295 };
296 
SurfaceTransaction_setSolidBufferWithRelease(JNIEnv * env,jclass,jlong surfaceControl,jlong surfaceTransaction,jint width,jint height,jint color,jobject jCallback)297 jlong SurfaceTransaction_setSolidBufferWithRelease(JNIEnv* env, jclass /* clazz */,
298                                                    jlong surfaceControl, jlong surfaceTransaction,
299                                                    jint width, jint height, jint color,
300                                                    jobject jCallback) {
301     AHardwareBuffer* buffer = nullptr;
302     int fence = -1;
303 
304     bool err = getSolidBuffer(width, height, color, &buffer, &fence);
305     if (err) {
306         return 0;
307     }
308 
309     if (jCallback == nullptr) {
310         ALOGE("jCallback is null!");
311     }
312     void* context = new ReleaseCallbackWrapper(env, jCallback);
313     ASurfaceTransaction_setBufferWithRelease(reinterpret_cast<ASurfaceTransaction*>(
314                                                      surfaceTransaction),
315                                              reinterpret_cast<ASurfaceControl*>(surfaceControl),
316                                              buffer, fence, context,
317                                              ReleaseCallbackWrapper::callbackThunk);
318 
319     ASurfaceTransaction_setBufferDataSpace(reinterpret_cast<ASurfaceTransaction*>(
320                                                    surfaceTransaction),
321                                            reinterpret_cast<ASurfaceControl*>(surfaceControl),
322                                            ADATASPACE_UNKNOWN);
323 
324     return reinterpret_cast<jlong>(buffer);
325 }
326 
SurfaceTransaction_setSolidBuffer(JNIEnv *,jclass,jlong surfaceControl,jlong surfaceTransaction,jint width,jint height,jint color)327 jlong SurfaceTransaction_setSolidBuffer(JNIEnv* /*env*/, jclass,
328                                         jlong surfaceControl,
329                                         jlong surfaceTransaction, jint width,
330                                         jint height, jint color) {
331     AHardwareBuffer* buffer = nullptr;
332     int fence = -1;
333 
334     bool err = getSolidBuffer(width, height, color, &buffer, &fence);
335     if (err) {
336         return 0;
337     }
338 
339     ASurfaceTransaction_setBuffer(
340             reinterpret_cast<ASurfaceTransaction*>(surfaceTransaction),
341             reinterpret_cast<ASurfaceControl*>(surfaceControl), buffer, fence);
342 
343     ASurfaceTransaction_setBufferDataSpace(
344             reinterpret_cast<ASurfaceTransaction*>(surfaceTransaction),
345             reinterpret_cast<ASurfaceControl*>(surfaceControl), ADATASPACE_UNKNOWN);
346 
347     return reinterpret_cast<jlong>(buffer);
348 }
349 
SurfaceTransaction_setBuffer(JNIEnv *,jclass,jlong surfaceControl,jlong surfaceTransaction,jlong buffer)350 void SurfaceTransaction_setBuffer(JNIEnv* /*env*/, jclass, jlong surfaceControl,
351                                   jlong surfaceTransaction, jlong buffer) {
352     ASurfaceTransaction_setBuffer(reinterpret_cast<ASurfaceTransaction*>(surfaceTransaction),
353                                   reinterpret_cast<ASurfaceControl*>(surfaceControl),
354                                   reinterpret_cast<AHardwareBuffer*>(buffer), -1 /* fence */);
355 
356     ASurfaceTransaction_setBufferDataSpace(reinterpret_cast<ASurfaceTransaction*>(
357                                                    surfaceTransaction),
358                                            reinterpret_cast<ASurfaceControl*>(surfaceControl),
359                                            ADATASPACE_UNKNOWN);
360 }
361 
SurfaceTransaction_setQuadrantBuffer(JNIEnv *,jclass,jlong surfaceControl,jlong surfaceTransaction,jint width,jint height,jint colorTopLeft,jint colorTopRight,jint colorBottomRight,jint colorBottomLeft)362 jlong SurfaceTransaction_setQuadrantBuffer(
363         JNIEnv* /*env*/, jclass, jlong surfaceControl, jlong surfaceTransaction,
364         jint width, jint height, jint colorTopLeft, jint colorTopRight,
365         jint colorBottomRight, jint colorBottomLeft) {
366     AHardwareBuffer* buffer = nullptr;
367     int fence = -1;
368 
369     bool err =
370             getQuadrantBuffer(width, height, colorTopLeft, colorTopRight,
371                               colorBottomRight, colorBottomLeft, &buffer, &fence);
372     if (err) {
373         return 0;
374     }
375 
376     ASurfaceTransaction_setBuffer(
377             reinterpret_cast<ASurfaceTransaction*>(surfaceTransaction),
378             reinterpret_cast<ASurfaceControl*>(surfaceControl), buffer, fence);
379 
380     ASurfaceTransaction_setBufferDataSpace(
381             reinterpret_cast<ASurfaceTransaction*>(surfaceTransaction),
382             reinterpret_cast<ASurfaceControl*>(surfaceControl), ADATASPACE_UNKNOWN);
383 
384     return reinterpret_cast<jlong>(buffer);
385 }
386 
SurfaceTransaction_releaseBuffer(JNIEnv *,jclass,jlong buffer)387 void SurfaceTransaction_releaseBuffer(JNIEnv* /*env*/, jclass, jlong buffer) {
388     AHardwareBuffer_release(reinterpret_cast<AHardwareBuffer*>(buffer));
389 }
390 
SurfaceTransaction_setVisibility(JNIEnv *,jclass,jlong surfaceControl,jlong surfaceTransaction,jboolean show)391 void SurfaceTransaction_setVisibility(JNIEnv* /*env*/, jclass,
392                                       jlong surfaceControl,
393                                       jlong surfaceTransaction, jboolean show) {
394     auto visibility = (show) ? ASURFACE_TRANSACTION_VISIBILITY_SHOW :
395                                ASURFACE_TRANSACTION_VISIBILITY_HIDE;
396     ASurfaceTransaction_setVisibility(
397             reinterpret_cast<ASurfaceTransaction*>(surfaceTransaction),
398             reinterpret_cast<ASurfaceControl*>(surfaceControl), visibility);
399 }
400 
SurfaceTransaction_setBufferOpaque(JNIEnv *,jclass,jlong surfaceControl,jlong surfaceTransaction,jboolean opaque)401 void SurfaceTransaction_setBufferOpaque(JNIEnv* /*env*/, jclass,
402                                         jlong surfaceControl,
403                                         jlong surfaceTransaction,
404                                         jboolean opaque) {
405     auto transparency = (opaque) ? ASURFACE_TRANSACTION_TRANSPARENCY_OPAQUE :
406                                    ASURFACE_TRANSACTION_TRANSPARENCY_TRANSPARENT;
407     ASurfaceTransaction_setBufferTransparency(
408             reinterpret_cast<ASurfaceTransaction*>(surfaceTransaction),
409             reinterpret_cast<ASurfaceControl*>(surfaceControl), transparency);
410 }
411 
SurfaceTransaction_setGeometry(JNIEnv *,jclass,jlong surfaceControl,jlong surfaceTransaction,jint srcLeft,jint srcTop,jint srcRight,jint srcBottom,jint dstLeft,jint dstTop,jint dstRight,jint dstBottom,jint transform)412 void SurfaceTransaction_setGeometry(JNIEnv* /*env*/, jclass,
413                                     jlong surfaceControl,
414                                     jlong surfaceTransaction,
415                                     jint srcLeft, jint srcTop, jint srcRight, jint srcBottom,
416                                     jint dstLeft, jint dstTop, jint dstRight, jint dstBottom,
417                                     jint transform) {
418     const ARect src{srcLeft, srcTop, srcRight, srcBottom};
419     const ARect dst{dstLeft, dstTop, dstRight, dstBottom};
420     ASurfaceTransaction_setGeometry(
421             reinterpret_cast<ASurfaceTransaction*>(surfaceTransaction),
422             reinterpret_cast<ASurfaceControl*>(surfaceControl), src, dst, transform);
423 }
424 
SurfaceTransaction_setCrop(JNIEnv *,jclass,jlong surfaceControl,jlong surfaceTransaction,jint left,jint top,jint right,jint bottom)425 void SurfaceTransaction_setCrop(JNIEnv* /*env*/, jclass, jlong surfaceControl,
426                                 jlong surfaceTransaction, jint left, jint top, jint right,
427                                 jint bottom) {
428     const ARect crop{left, top, right, bottom};
429     ASurfaceTransaction_setCrop(reinterpret_cast<ASurfaceTransaction*>(surfaceTransaction),
430                                 reinterpret_cast<ASurfaceControl*>(surfaceControl), crop);
431 }
432 
SurfaceTransaction_setPosition(JNIEnv *,jclass,jlong surfaceControl,jlong surfaceTransaction,jint x,jint y)433 void SurfaceTransaction_setPosition(JNIEnv* /*env*/, jclass, jlong surfaceControl,
434                                     jlong surfaceTransaction, jint x, jint y) {
435     ASurfaceTransaction_setPosition(reinterpret_cast<ASurfaceTransaction*>(surfaceTransaction),
436                                     reinterpret_cast<ASurfaceControl*>(surfaceControl), x, y);
437 }
438 
SurfaceTransaction_setBufferTransform(JNIEnv *,jclass,jlong surfaceControl,jlong surfaceTransaction,jint transform)439 void SurfaceTransaction_setBufferTransform(JNIEnv* /*env*/, jclass, jlong surfaceControl,
440                                            jlong surfaceTransaction, jint transform) {
441     ASurfaceTransaction_setBufferTransform(reinterpret_cast<ASurfaceTransaction*>(
442                                                    surfaceTransaction),
443                                            reinterpret_cast<ASurfaceControl*>(surfaceControl),
444                                            transform);
445 }
446 
SurfaceTransaction_setScale(JNIEnv *,jclass,jlong surfaceControl,jlong surfaceTransaction,jfloat xScale,jfloat yScale)447 void SurfaceTransaction_setScale(JNIEnv* /*env*/, jclass, jlong surfaceControl,
448                                  jlong surfaceTransaction, jfloat xScale, jfloat yScale) {
449     ASurfaceTransaction_setScale(reinterpret_cast<ASurfaceTransaction*>(surfaceTransaction),
450                                  reinterpret_cast<ASurfaceControl*>(surfaceControl), xScale,
451                                  yScale);
452 }
453 
SurfaceTransaction_setDamageRegion(JNIEnv *,jclass,jlong surfaceControl,jlong surfaceTransaction,jint left,jint top,jint right,jint bottom)454 void SurfaceTransaction_setDamageRegion(JNIEnv* /*env*/, jclass,
455                                         jlong surfaceControl,
456                                         jlong surfaceTransaction, jint left,
457                                         jint top, jint right, jint bottom) {
458     const ARect rect[] = {{left, top, right, bottom}};
459     ASurfaceTransaction_setDamageRegion(
460             reinterpret_cast<ASurfaceTransaction*>(surfaceTransaction),
461             reinterpret_cast<ASurfaceControl*>(surfaceControl), rect, 1);
462 }
463 
SurfaceTransaction_setZOrder(JNIEnv *,jclass,jlong surfaceControl,jlong surfaceTransaction,jint z)464 void SurfaceTransaction_setZOrder(JNIEnv* /*env*/, jclass, jlong surfaceControl,
465                                   jlong surfaceTransaction, jint z) {
466     ASurfaceTransaction_setZOrder(
467             reinterpret_cast<ASurfaceTransaction*>(surfaceTransaction),
468             reinterpret_cast<ASurfaceControl*>(surfaceControl), z);
469 }
470 
471 class CallbackListenerWrapper {
472 public:
CallbackListenerWrapper(JNIEnv * env,jobject object,bool waitForFence)473     explicit CallbackListenerWrapper(JNIEnv* env, jobject object, bool waitForFence) {
474         env->GetJavaVM(&mVm);
475         mCallbackListenerObject = env->NewGlobalRef(object);
476         mWaitForFence = waitForFence;
477         if (!mCallbackListenerObject) {
478             ALOGE("Failed to make global ref");
479         }
480     }
481 
~CallbackListenerWrapper()482     ~CallbackListenerWrapper() { getenv()->DeleteGlobalRef(mCallbackListenerObject); }
483 
484     /**
485      * This is duplicate code from sync.c, but the sync_wait function is not exposed to the ndk.
486      * The documentation recommends using poll instead of exposing sync_wait, but the sync_wait
487      * also handles errors and retries so copied the code here.
488      */
sync_wait(int fd,int timeout)489     static int sync_wait(int fd, int timeout) {
490         struct pollfd fds;
491         int ret;
492 
493         if (fd < 0) {
494             errno = EINVAL;
495             return -1;
496         }
497 
498         fds.fd = fd;
499         fds.events = POLLIN;
500 
501         do {
502             ret = poll(&fds, 1, timeout);
503             if (ret > 0) {
504                 if (fds.revents & (POLLERR | POLLNVAL)) {
505                     errno = EINVAL;
506                     return -1;
507                 }
508                 return 0;
509             } else if (ret == 0) {
510                 errno = ETIME;
511                 return -1;
512             }
513         } while (ret == -1 && (errno == EINTR || errno == EAGAIN));
514 
515         return ret;
516     }
517 
getSignalTime(int presentFence)518     static uint64_t getSignalTime(int presentFence) {
519         uint64_t presentTime = 0;
520         int error = sync_wait(presentFence, 500);
521         if (error < 0) {
522             ALOGE("Failed to sync fence error=%d", error);
523             return 0;
524         }
525 
526         struct sync_file_info* syncFileInfo = sync_file_info(presentFence);
527         if (!syncFileInfo) {
528             ALOGE("invalid fence");
529             sync_file_info_free(syncFileInfo);
530             return 0;
531         }
532 
533         if (syncFileInfo->status != 1) {
534             ALOGE("fence did not signal status=%d", syncFileInfo->status);
535             return 0;
536         }
537 
538         struct sync_fence_info* syncFenceInfo = sync_get_fence_info(syncFileInfo);
539         for (size_t i = 0; i < syncFileInfo->num_fences; i++) {
540             if (syncFenceInfo[i].timestamp_ns > presentTime) {
541                 presentTime = syncFenceInfo[i].timestamp_ns;
542             }
543         }
544 
545         sync_file_info_free(syncFileInfo);
546         close(presentFence);
547         return presentTime;
548     }
549 
callback(ASurfaceTransactionStats * stats)550     void callback(ASurfaceTransactionStats* stats) {
551         JNIEnv* env = getenv();
552         int64_t latchTime = ASurfaceTransactionStats_getLatchTime(stats);
553         uint64_t presentTime = systemTime();
554         if (mWaitForFence) {
555             int presentFence = ASurfaceTransactionStats_getPresentFenceFd(stats);
556             if (presentFence >= 0) {
557                 presentTime = getSignalTime(presentFence);
558             }
559         }
560 
561         jlong aSurfaceControlPtr = env->CallLongMethod(mCallbackListenerObject,
562                                                        gTransactionCompleteListenerClassInfo
563                                                                .shouldQueryTransactionStats);
564         ASurfaceControl* targetSurfaceControl =
565                 reinterpret_cast<ASurfaceControl*>(aSurfaceControlPtr);
566         if (targetSurfaceControl) {
567             ASurfaceControl** surfaceControls = nullptr;
568             size_t surfaceControlsSize = 0;
569             ASurfaceTransactionStats_getASurfaceControls(stats, &surfaceControls,
570                                                          &surfaceControlsSize);
571             bool surfaceControlFound = false;
572             bool releaseFenceQueried = false;
573             bool acquireTimeQueried = false;
574             for (int i = 0; i < surfaceControlsSize; i++) {
575                 ASurfaceControl* surfaceControl = surfaceControls[i];
576                 if (targetSurfaceControl == surfaceControl) {
577                     surfaceControlFound = true;
578                     // Call the API, but ignore the result since the API is deprecated.
579                     ASurfaceTransactionStats_getAcquireTime(stats, targetSurfaceControl);
580                     acquireTimeQueried = true;
581                     if (mWaitForFence) {
582                         int previousReleaseFence =
583                                 ASurfaceTransactionStats_getPreviousReleaseFenceFd(
584                                         stats, targetSurfaceControl);
585                         if (previousReleaseFence >= 0) {
586                             getSignalTime(previousReleaseFence);
587                         }
588                         releaseFenceQueried = true;
589                     }
590                 }
591             }
592             ASurfaceTransactionStats_releaseASurfaceControls(surfaceControls);
593             env->CallVoidMethod(mCallbackListenerObject,
594                                 gTransactionCompleteListenerClassInfo.onTransactionStatsRead,
595                                 surfaceControlFound, releaseFenceQueried, acquireTimeQueried);
596         }
597 
598         env->CallVoidMethod(mCallbackListenerObject,
599                             gTransactionCompleteListenerClassInfo.onTransactionComplete, latchTime,
600                             presentTime);
601     }
602 
transactionCallbackThunk(void * context,ASurfaceTransactionStats * stats)603     static void transactionCallbackThunk(void* context, ASurfaceTransactionStats* stats) {
604         CallbackListenerWrapper* listener = reinterpret_cast<CallbackListenerWrapper*>(context);
605         listener->callback(stats);
606         delete listener;
607     }
608 
609 private:
610     jobject mCallbackListenerObject;
611     JavaVM* mVm;
612     bool mWaitForFence;
613 
getenv()614     JNIEnv* getenv() {
615         JNIEnv* env;
616         mVm->GetEnv(reinterpret_cast<void**>(&env), JNI_VERSION_1_6);
617         return env;
618     }
619 };
620 
SurfaceTransaction_setDesiredPresentTime(JNIEnv *,jclass,jlong surfaceTransaction,jlong desiredPresentTimeOffset)621 jlong SurfaceTransaction_setDesiredPresentTime(JNIEnv* /*env*/, jclass, jlong surfaceTransaction,
622                                               jlong desiredPresentTimeOffset) {
623     struct timespec t;
624     t.tv_sec = t.tv_nsec = 0;
625     clock_gettime(CLOCK_MONOTONIC, &t);
626     int64_t currentTime = ((int64_t) t.tv_sec)*1000000000LL + t.tv_nsec;
627 
628     int64_t desiredPresentTime = currentTime + desiredPresentTimeOffset;
629 
630     ASurfaceTransaction_setDesiredPresentTime(
631             reinterpret_cast<ASurfaceTransaction*>(surfaceTransaction), desiredPresentTime);
632 
633     return desiredPresentTime;
634 }
635 
SurfaceTransaction_setBufferAlpha(JNIEnv *,jclass,jlong surfaceControl,jlong surfaceTransaction,jdouble alpha)636 void SurfaceTransaction_setBufferAlpha(JNIEnv* /*env*/, jclass,
637                                       jlong surfaceControl,
638                                       jlong surfaceTransaction, jdouble alpha) {
639     ASurfaceTransaction_setBufferAlpha(
640             reinterpret_cast<ASurfaceTransaction*>(surfaceTransaction),
641             reinterpret_cast<ASurfaceControl*>(surfaceControl), alpha);
642 }
643 
SurfaceTransaction_reparent(JNIEnv *,jclass,jlong surfaceControl,jlong newParentSurfaceControl,jlong surfaceTransaction)644 void SurfaceTransaction_reparent(JNIEnv* /*env*/, jclass, jlong surfaceControl,
645                                  jlong newParentSurfaceControl, jlong surfaceTransaction) {
646     ASurfaceTransaction_reparent(
647             reinterpret_cast<ASurfaceTransaction*>(surfaceTransaction),
648             reinterpret_cast<ASurfaceControl*>(surfaceControl),
649             reinterpret_cast<ASurfaceControl*>(newParentSurfaceControl));
650 }
651 
SurfaceTransaction_setColor(JNIEnv *,jclass,jlong surfaceControl,jlong surfaceTransaction,jfloat r,jfloat g,jfloat b,jfloat alpha)652 void SurfaceTransaction_setColor(JNIEnv* /*env*/, jclass, jlong surfaceControl,
653                                  jlong surfaceTransaction, jfloat r,
654                                  jfloat g, jfloat b, jfloat alpha) {
655     ASurfaceTransaction_setColor(
656             reinterpret_cast<ASurfaceTransaction*>(surfaceTransaction),
657             reinterpret_cast<ASurfaceControl*>(surfaceControl),
658             r, g, b, alpha, ADATASPACE_UNKNOWN);
659 }
660 
SurfaceTransaction_setEnableBackPressure(JNIEnv * env,jclass,jobject javaTransaction,jobject javaSurfaceControl,jboolean enableBackPressure)661 void SurfaceTransaction_setEnableBackPressure(JNIEnv* env, jclass, jobject javaTransaction,
662                                               jobject javaSurfaceControl,
663                                               jboolean enableBackPressure) {
664     ASurfaceTransaction* transaction = ASurfaceTransaction_fromJava(env, javaTransaction);
665     ASurfaceControl* surfaceControl = ASurfaceControl_fromJava(env, javaSurfaceControl);
666     ASurfaceTransaction_setEnableBackPressure(transaction, surfaceControl, enableBackPressure);
667 }
668 
SurfaceTransaction_setOnCompleteCallback(JNIEnv * env,jclass,jlong surfaceTransaction,jboolean waitForFence,jobject callback)669 void SurfaceTransaction_setOnCompleteCallback(JNIEnv* env, jclass, jlong surfaceTransaction,
670                                               jboolean waitForFence, jobject callback) {
671     void* context = new CallbackListenerWrapper(env, callback, waitForFence);
672     ASurfaceTransaction_setOnComplete(reinterpret_cast<ASurfaceTransaction*>(surfaceTransaction),
673                                       reinterpret_cast<void*>(context),
674                                       CallbackListenerWrapper::transactionCallbackThunk);
675 }
676 
SurfaceTransaction_setOnCommitCallback(JNIEnv * env,jclass,jlong surfaceTransaction,jobject callback)677 void SurfaceTransaction_setOnCommitCallback(JNIEnv* env, jclass, jlong surfaceTransaction,
678                                             jobject callback) {
679     void* context = new CallbackListenerWrapper(env, callback, false /* waitForFence */);
680     ASurfaceTransaction_setOnCommit(reinterpret_cast<ASurfaceTransaction*>(surfaceTransaction),
681                                     reinterpret_cast<void*>(context),
682                                     CallbackListenerWrapper::transactionCallbackThunk);
683 }
684 
685 // Save context so we can test callbacks without a context provided.
686 static CallbackListenerWrapper* listener = nullptr;
transactionCallbackWithoutContextThunk(void *,ASurfaceTransactionStats * stats)687 static void transactionCallbackWithoutContextThunk(void* /* context */,
688                                                    ASurfaceTransactionStats* stats) {
689     CallbackListenerWrapper::transactionCallbackThunk(listener, stats);
690     listener = nullptr;
691 }
692 
SurfaceTransaction_setOnCompleteCallbackWithoutContext(JNIEnv * env,jclass,jlong surfaceTransaction,jboolean waitForFence,jobject callback)693 void SurfaceTransaction_setOnCompleteCallbackWithoutContext(JNIEnv* env, jclass,
694                                                             jlong surfaceTransaction,
695                                                             jboolean waitForFence,
696                                                             jobject callback) {
697     listener = new CallbackListenerWrapper(env, callback, waitForFence);
698     ASurfaceTransaction_setOnComplete(reinterpret_cast<ASurfaceTransaction*>(surfaceTransaction),
699                                       nullptr, transactionCallbackWithoutContextThunk);
700 }
701 
SurfaceTransaction_setOnCommitCallbackWithoutContext(JNIEnv * env,jclass,jlong surfaceTransaction,jobject callback)702 void SurfaceTransaction_setOnCommitCallbackWithoutContext(JNIEnv* env, jclass,
703                                                           jlong surfaceTransaction,
704                                                           jobject callback) {
705     listener = new CallbackListenerWrapper(env, callback, false /* waitForFence */);
706     ASurfaceTransaction_setOnCommit(reinterpret_cast<ASurfaceTransaction*>(surfaceTransaction),
707                                     nullptr, transactionCallbackWithoutContextThunk);
708 }
709 
SurfaceTransaction_setFrameTimeline(JNIEnv *,jclass,jlong surfaceTransaction,jlong vsyncId)710 void SurfaceTransaction_setFrameTimeline(JNIEnv* /*env*/, jclass, jlong surfaceTransaction,
711                                          jlong vsyncId) {
712     ASurfaceTransaction_setFrameTimeline(reinterpret_cast<ASurfaceTransaction*>(surfaceTransaction),
713                                          vsyncId);
714 }
715 
SurfaceTransaction_setExtendedRangeBrightness(JNIEnv *,jclass,jlong surfaceControl,jlong surfaceTransaction,jfloat currentRatio,jfloat desiredRatio)716 void SurfaceTransaction_setExtendedRangeBrightness(JNIEnv* /*env*/, jclass, jlong surfaceControl,
717                                                    jlong surfaceTransaction, jfloat currentRatio,
718                                                    jfloat desiredRatio) {
719     ASurfaceTransaction_setExtendedRangeBrightness(reinterpret_cast<ASurfaceTransaction*>(
720                                                            surfaceTransaction),
721                                                    reinterpret_cast<ASurfaceControl*>(
722                                                            surfaceControl),
723                                                    currentRatio, desiredRatio);
724 }
725 
SurfaceTransaction_setDesiredHdrHeadroom(JNIEnv *,jclass,jlong surfaceControl,jlong surfaceTransaction,jfloat desiredRatio)726 void SurfaceTransaction_setDesiredHdrHeadroom(JNIEnv* /*env*/, jclass, jlong surfaceControl,
727                                                    jlong surfaceTransaction, jfloat desiredRatio) {
728     ASurfaceTransaction_setDesiredHdrHeadroom(reinterpret_cast<ASurfaceTransaction*>(
729                                                            surfaceTransaction),
730                                                    reinterpret_cast<ASurfaceControl*>(
731                                                            surfaceControl),
732                                                    desiredRatio);
733 }
734 
SurfaceTransaction_setDataSpace(JNIEnv *,jclass,jlong surfaceControl,jlong surfaceTransaction,jint dataspace)735 void SurfaceTransaction_setDataSpace(JNIEnv* /*env*/, jclass, jlong surfaceControl,
736                                      jlong surfaceTransaction, jint dataspace) {
737     ASurfaceTransaction_setBufferDataSpace(reinterpret_cast<ASurfaceTransaction*>(
738                                                    surfaceTransaction),
739                                            reinterpret_cast<ASurfaceControl*>(surfaceControl),
740                                            static_cast<ADataSpace>(dataspace));
741 }
742 
SurfaceTransaction_setLuts(JNIEnv * env,jclass,jlong surfaceControl,jlong surfaceTransaction,jfloatArray jbufferArray,jintArray joffsetArray,jintArray jdimensionArray,jintArray jsizeArray,jintArray jsamplingKeyArray)743 void SurfaceTransaction_setLuts(JNIEnv* env, jclass, jlong surfaceControl, jlong surfaceTransaction,
744                                 jfloatArray jbufferArray, jintArray joffsetArray,
745                                 jintArray jdimensionArray, jintArray jsizeArray,
746                                 jintArray jsamplingKeyArray) {
747     ADisplayLuts* luts = ADisplayLuts_create();
748     if (jdimensionArray) {
749         jsize numLuts = env->GetArrayLength(jdimensionArray);
750         ScopedIntArrayRW joffsets(env, joffsetArray);
751         if (joffsets.get() == nullptr) {
752             jniThrowRuntimeException(env, "Failed to get ScopedIntArrayRW from joffsetArray");
753             return;
754         }
755         ScopedIntArrayRW jdimensions(env, jdimensionArray);
756         if (jdimensions.get() == nullptr) {
757             jniThrowRuntimeException(env, "Failed to get ScopedIntArrayRW from jdimensionArray");
758             return;
759         }
760         ScopedIntArrayRW jsizes(env, jsizeArray);
761         if (jsizes.get() == nullptr) {
762             jniThrowRuntimeException(env, "Failed to get ScopedIntArrayRW from jsizeArray");
763             return;
764         }
765         ScopedIntArrayRW jsamplingKeys(env, jsamplingKeyArray);
766         if (jsamplingKeys.get() == nullptr) {
767             jniThrowRuntimeException(env, "Failed to get ScopedIntArrayRW from jsamplingKeyArray");
768             return;
769         }
770 
771         if (numLuts > 0) {
772             ScopedFloatArrayRW jbuffers(env, jbufferArray);
773             if (jbuffers.get() == nullptr) {
774                 jniThrowRuntimeException(env, "Failed to get ScopedFloatArrayRW from jbufferArray");
775                 return;
776             }
777             int32_t bufferSize = (int32_t)env->GetArrayLength(jbufferArray);
778             std::vector<ADisplayLutsEntry*> entries;
779             entries.reserve(numLuts);
780             for (int32_t i = 0; i < numLuts; i++) {
781                 int32_t bufferSizePerLut = (i + 1 == numLuts) ? bufferSize - joffsets[i]
782                                                               : joffsets[i + 1] - joffsets[i];
783                 ADisplayLutsEntry* entry =
784                         ADisplayLutsEntry_createEntry(jbuffers.get() + joffsets[i], bufferSizePerLut,
785                                         static_cast<ADisplayLuts_Dimension>(jdimensions[i]),
786                                         static_cast<ADisplayLuts_SamplingKey>(jsamplingKeys[i]));
787                 entries.emplace_back(entry);
788             }
789             ADisplayLuts_setEntries(luts, entries.data(), numLuts);
790             for (int32_t i = 0; i < numLuts; i++) {
791                 ADisplayLutsEntry_destroy(entries[i]);
792             }
793         }
794     }
795 
796     ASurfaceTransaction_setLuts(reinterpret_cast<ASurfaceTransaction*>(surfaceTransaction),
797                                 reinterpret_cast<ASurfaceControl*>(surfaceControl), luts);
798     ADisplayLuts_destroy(luts);
799 }
800 
801 static struct {
802     jclass clazz;
803     jmethodID constructor;
804 } gFrameTimelineClassInfo;
805 
806 static struct {
807     jclass clazz;
808     jmethodID constructor;
809 } gFrameCallbackDataClassInfo;
810 
verifyChoreographer(JNIEnv * env,AChoreographer * choreographer)811 static void verifyChoreographer(JNIEnv* env, AChoreographer* choreographer) {
812     ASSERT(choreographer != nullptr, "Choreographer setup unsuccessful");
813 }
814 
verifyPollCallback(JNIEnv * env,int result)815 static void verifyPollCallback(JNIEnv* env, int result) {
816     ASSERT(result == ALOOPER_POLL_CALLBACK, "Callback failed with error: %d", result);
817 }
818 
819 /** Gets VSync information from Choreographer, including a collection of frame timelines and
820  * platform-preferred index using Choreographer. */
SurfaceControlTest_getFrameTimelines(JNIEnv * env,jclass)821 jobject SurfaceControlTest_getFrameTimelines(JNIEnv* env, jclass) {
822     ALooper_prepare(0);
823     ATrace_beginSection("Getting Choreographer instance");
824     AChoreographer* choreographer = AChoreographer_getInstance();
825     ATrace_endSection();
826     verifyChoreographer(env, choreographer);
827 
828     VsyncCallback cb1("cb1", env);
829     auto start = now();
830     ATrace_beginSection("postVsyncCallback");
831     AChoreographer_postVsyncCallback(choreographer, vsyncCallback, &cb1);
832     ATrace_endSection();
833     auto delayPeriod = std::chrono::duration_cast<std::chrono::milliseconds>(DELAY_PERIOD).count();
834     ATrace_beginSection("ALooper_pollOnce");
835     int result = ALooper_pollOnce(delayPeriod * 5, nullptr, nullptr, nullptr);
836     ATrace_endSection();
837     verifyPollCallback(env, result);
838     verifyCallback(env, cb1, 1, start, NOMINAL_VSYNC_PERIOD * 3);
839 
840     jobjectArray frameTimelineObjs =
841             env->NewObjectArray(cb1.getTimeline().size(), gFrameTimelineClassInfo.clazz,
842                                 /*initial element*/ NULL);
843     if (env->ExceptionCheck()) {
844         env->ExceptionDescribe();
845         env->ExceptionClear();
846         return NULL;
847     }
848     if (frameTimelineObjs == NULL) {
849         jniThrowRuntimeException(env, "Failed to create FrameTimeline array");
850         return NULL;
851     }
852     for (int i = 0; i < cb1.getTimeline().size(); i++) {
853         VsyncCallback::FrameTime frameTimeline = cb1.getTimeline()[i];
854         jobject frameTimelineObj =
855                 env->NewObject(gFrameTimelineClassInfo.clazz, gFrameTimelineClassInfo.constructor,
856                                frameTimeline.vsyncId, frameTimeline.expectedPresentTime,
857                                frameTimeline.deadline);
858         env->SetObjectArrayElement(frameTimelineObjs, i, frameTimelineObj);
859     }
860 
861     return env->NewObject(gFrameCallbackDataClassInfo.clazz,
862                           gFrameCallbackDataClassInfo.constructor, frameTimelineObjs,
863                           cb1.getPreferredFrameTimelineIndex());
864 }
865 
866 static const JNINativeMethod JNI_METHODS[] = {
867         {"nSurfaceTransaction_create", "()J", (void*)SurfaceTransaction_create},
868         {"nSurfaceTransaction_delete", "(J)V", (void*)SurfaceTransaction_delete},
869         {"nSurfaceTransaction_fromJava", "(Landroid/view/SurfaceControl$Transaction;)J",
870          (void*)SurfaceTransaction_fromJava},
871         {"nSurfaceTransaction_apply", "(J)V", (void*)SurfaceTransaction_apply},
872         {"nSurfaceControl_createFromWindow", "(Landroid/view/Surface;)J",
873          (void*)SurfaceControl_createFromWindow},
874         {"nSurfaceControl_create", "(J)J", (void*)SurfaceControl_create},
875         {"nSurfaceControl_acquire", "(J)V", (void*)SurfaceControl_acquire},
876         {"nSurfaceControl_release", "(J)V", (void*)SurfaceControl_release},
877         {"nSurfaceControl_fromJava", "(Landroid/view/SurfaceControl;)J",
878          (void*)SurfaceControl_fromJava},
879         {"nSurfaceTransaction_setSolidBuffer", "(JJIII)J",
880          (void*)SurfaceTransaction_setSolidBuffer},
881         {"nSurfaceTransaction_setSolidBufferWithRelease",
882          "(JJIIILandroid/view/cts/util/ASurfaceControlTestUtils$BufferReleaseCallback;)J",
883          (void*)SurfaceTransaction_setSolidBufferWithRelease},
884         {"nSurfaceTransaction_setBuffer", "(JJJ)V", (void*)SurfaceTransaction_setBuffer},
885         {"nSurfaceTransaction_setQuadrantBuffer", "(JJIIIIII)J",
886          (void*)SurfaceTransaction_setQuadrantBuffer},
887         {"nSurfaceTransaction_releaseBuffer", "(J)V", (void*)SurfaceTransaction_releaseBuffer},
888         {"nSurfaceTransaction_setVisibility", "(JJZ)V", (void*)SurfaceTransaction_setVisibility},
889         {"nSurfaceTransaction_setBufferOpaque", "(JJZ)V",
890          (void*)SurfaceTransaction_setBufferOpaque},
891         {"nSurfaceTransaction_setGeometry", "(JJIIIIIIIII)V",
892          (void*)SurfaceTransaction_setGeometry},
893         {"nSurfaceTransaction_setDamageRegion", "(JJIIII)V",
894          (void*)SurfaceTransaction_setDamageRegion},
895         {"nSurfaceTransaction_setZOrder", "(JJI)V", (void*)SurfaceTransaction_setZOrder},
896         {"nSurfaceTransaction_setDesiredPresentTime", "(JJ)J",
897          (void*)SurfaceTransaction_setDesiredPresentTime},
898         {"nSurfaceTransaction_setBufferAlpha", "(JJD)V", (void*)SurfaceTransaction_setBufferAlpha},
899         {"nSurfaceTransaction_reparent", "(JJJ)V", (void*)SurfaceTransaction_reparent},
900         {"nSurfaceTransaction_setColor", "(JJFFFF)V", (void*)SurfaceTransaction_setColor},
901         {"nSurfaceTransaction_setEnableBackPressure",
902          "(Landroid/view/SurfaceControl$Transaction;Landroid/view/SurfaceControl;Z)V",
903          (void*)SurfaceTransaction_setEnableBackPressure},
904         {"nSurfaceTransaction_setOnCompleteCallback",
905          "(JZLandroid/view/cts/util/ASurfaceControlTestUtils$TransactionCompleteListener;)V",
906          (void*)SurfaceTransaction_setOnCompleteCallback},
907         {"nSurfaceTransaction_setOnCommitCallback",
908          "(JLandroid/view/cts/util/ASurfaceControlTestUtils$TransactionCompleteListener;)V",
909          (void*)SurfaceTransaction_setOnCommitCallback},
910         {"nSurfaceTransaction_setCrop", "(JJIIII)V", (void*)SurfaceTransaction_setCrop},
911         {"nSurfaceTransaction_setPosition", "(JJII)V", (void*)SurfaceTransaction_setPosition},
912         {"nSurfaceTransaction_setBufferTransform", "(JJI)V",
913          (void*)SurfaceTransaction_setBufferTransform},
914         {"nSurfaceTransaction_setScale", "(JJFF)V", (void*)SurfaceTransaction_setScale},
915         {"nSurfaceTransaction_setOnCompleteCallbackWithoutContext",
916          "(JZLandroid/view/cts/util/ASurfaceControlTestUtils$TransactionCompleteListener;)V",
917          (void*)SurfaceTransaction_setOnCompleteCallbackWithoutContext},
918         {"nSurfaceTransaction_setOnCommitCallbackWithoutContext",
919          "(JLandroid/view/cts/util/ASurfaceControlTestUtils$TransactionCompleteListener;)V",
920          (void*)SurfaceTransaction_setOnCommitCallbackWithoutContext},
921         {"nSurfaceTransaction_setFrameTimeline", "(JJ)V",
922          (void*)SurfaceTransaction_setFrameTimeline},
923         {"nSurfaceTransaction_setExtendedRangeBrightness", "(JJFF)V",
924          (void*)SurfaceTransaction_setExtendedRangeBrightness},
925         {"nSurfaceTransaction_setDesiredHdrHeadroom", "(JJF)V",
926          (void*)SurfaceTransaction_setDesiredHdrHeadroom},
927         {"nSurfaceTransaction_setLuts", "(JJ[F[I[I[I[I)V", (void*)SurfaceTransaction_setLuts},
928         {"nSurfaceTransaction_setDataSpace", "(JJI)V", (void*)SurfaceTransaction_setDataSpace},
929         {"getSolidBuffer", "(III)Landroid/hardware/HardwareBuffer;", (void*)Utils_getSolidBuffer},
930         {"getQuadrantBuffer", "(IIIIII)Landroid/hardware/HardwareBuffer;",
931          (void*)Utils_getQuadrantBuffer},
932         {"getBufferId", "(Landroid/hardware/HardwareBuffer;)J", (void*)Utils_getBufferId},
933 };
934 
935 static const JNINativeMethod FRAME_TIMELINE_JNI_METHODS[] = {
936         {"nGetFrameTimelines", "()Landroid/view/cts/util/FrameCallbackData;",
937          (void*)SurfaceControlTest_getFrameTimelines},
938 };
939 
940 }  // anonymous namespace
941 
register_android_view_cts_ASurfaceControlTest(JNIEnv * env)942 jint register_android_view_cts_ASurfaceControlTest(JNIEnv* env) {
943     jclass transactionCompleteListenerClazz = env->FindClass(
944             "android/view/cts/util/ASurfaceControlTestUtils$TransactionCompleteListener");
945     gTransactionCompleteListenerClassInfo.clazz =
946             static_cast<jclass>(env->NewGlobalRef(transactionCompleteListenerClazz));
947     gTransactionCompleteListenerClassInfo.onTransactionComplete =
948             env->GetMethodID(transactionCompleteListenerClazz, "onTransactionComplete", "(JJ)V");
949     gTransactionCompleteListenerClassInfo.shouldQueryTransactionStats =
950             env->GetMethodID(transactionCompleteListenerClazz, "shouldQueryTransactionStats",
951                              "()J");
952     gTransactionCompleteListenerClassInfo.onTransactionStatsRead =
953             env->GetMethodID(transactionCompleteListenerClazz, "onTransactionStatsRead", "(ZZZ)V");
954 
955     jclass bufferReleaseCallbackClazz =
956             env->FindClass("android/view/cts/util/ASurfaceControlTestUtils$BufferReleaseCallback");
957     gBufferReleaseCallbackClassInfo.clazz =
958             static_cast<jclass>(env->NewGlobalRef(bufferReleaseCallbackClazz));
959     gBufferReleaseCallbackClassInfo.onBufferRelease =
960             env->GetMethodID(bufferReleaseCallbackClazz, "onBufferRelease", "()V");
961 
962     gFrameTimelineClassInfo.clazz = static_cast<jclass>(env->NewGlobalRef(
963             env->FindClass("android/view/cts/util/FrameCallbackData$FrameTimeline")));
964     gFrameTimelineClassInfo.constructor =
965             env->GetMethodID(gFrameTimelineClassInfo.clazz, "<init>", "(JJJ)V");
966 
967     gFrameCallbackDataClassInfo.clazz = static_cast<jclass>(
968             env->NewGlobalRef(env->FindClass("android/view/cts/util/FrameCallbackData")));
969     gFrameCallbackDataClassInfo.constructor =
970             env->GetMethodID(gFrameCallbackDataClassInfo.clazz, "<init>",
971                              "([Landroid/view/cts/util/FrameCallbackData$FrameTimeline;I)V");
972 
973     jclass frameCallbackDataClass = env->FindClass("android/view/cts/util/FrameCallbackData");
974     env->RegisterNatives(frameCallbackDataClass, FRAME_TIMELINE_JNI_METHODS,
975                          sizeof(FRAME_TIMELINE_JNI_METHODS) / sizeof(JNINativeMethod));
976 
977     jclass clazz = env->FindClass("android/view/cts/util/ASurfaceControlTestUtils");
978     return env->RegisterNatives(clazz, JNI_METHODS, sizeof(JNI_METHODS) / sizeof(JNINativeMethod));
979 }
980