• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (C) 2013 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 "SurfaceControl"
18 #define LOG_NDEBUG 0
19 
20 #include "android_os_Parcel.h"
21 #include "android_util_Binder.h"
22 #include "android_hardware_input_InputWindowHandle.h"
23 #include "core_jni_helpers.h"
24 
25 #include <memory>
26 
27 #include <aidl/android/hardware/graphics/common/PixelFormat.h>
28 #include <android-base/chrono_utils.h>
29 #include <android/graphics/properties.h>
30 #include <android/graphics/region.h>
31 #include <android/gui/BnScreenCaptureListener.h>
32 #include <android/hardware/display/IDeviceProductInfoConstants.h>
33 #include <android/os/IInputConstants.h>
34 #include <android_runtime/AndroidRuntime.h>
35 #include <android_runtime/android_graphics_GraphicBuffer.h>
36 #include <android_runtime/android_hardware_HardwareBuffer.h>
37 #include <android_runtime/android_view_Surface.h>
38 #include <android_runtime/android_view_SurfaceSession.h>
39 #include <gui/ISurfaceComposer.h>
40 #include <gui/Surface.h>
41 #include <gui/SurfaceComposerClient.h>
42 #include <jni.h>
43 #include <nativehelper/JNIHelp.h>
44 #include <nativehelper/ScopedUtfChars.h>
45 #include <private/gui/ComposerService.h>
46 #include <stdio.h>
47 #include <system/graphics.h>
48 #include <ui/BlurRegion.h>
49 #include <ui/ConfigStoreTypes.h>
50 #include <ui/DeviceProductInfo.h>
51 #include <ui/DisplayMode.h>
52 #include <ui/DisplayedFrameStats.h>
53 #include <ui/DynamicDisplayInfo.h>
54 #include <ui/FrameStats.h>
55 #include <ui/GraphicTypes.h>
56 #include <ui/HdrCapabilities.h>
57 #include <ui/Rect.h>
58 #include <ui/Region.h>
59 #include <ui/StaticDisplayInfo.h>
60 #include <utils/LightRefBase.h>
61 #include <utils/Log.h>
62 
63 // ----------------------------------------------------------------------------
64 
65 namespace android {
66 
67 using gui::CaptureArgs;
68 using gui::FocusRequest;
69 
doThrowNPE(JNIEnv * env)70 static void doThrowNPE(JNIEnv* env) {
71     jniThrowNullPointerException(env, NULL);
72 }
73 
doThrowIAE(JNIEnv * env,const char * msg=nullptr)74 static void doThrowIAE(JNIEnv* env, const char* msg = nullptr) {
75     jniThrowException(env, "java/lang/IllegalArgumentException", msg);
76 }
77 
78 static const char* const OutOfResourcesException =
79     "android/view/Surface$OutOfResourcesException";
80 
81 static struct {
82     jclass clazz;
83     jmethodID ctor;
84 } gIntegerClassInfo;
85 
toInteger(JNIEnv * env,int32_t i)86 static jobject toInteger(JNIEnv* env, int32_t i) {
87     return env->NewObject(gIntegerClassInfo.clazz, gIntegerClassInfo.ctor, i);
88 }
89 
90 static struct {
91     jclass clazz;
92     jmethodID ctor;
93     jfieldID isInternal;
94     jfieldID density;
95     jfieldID secure;
96     jfieldID deviceProductInfo;
97     jfieldID installOrientation;
98 } gStaticDisplayInfoClassInfo;
99 
100 static struct {
101     jclass clazz;
102     jmethodID ctor;
103     jfieldID supportedDisplayModes;
104     jfieldID activeDisplayModeId;
105     jfieldID supportedColorModes;
106     jfieldID activeColorMode;
107     jfieldID hdrCapabilities;
108     jfieldID autoLowLatencyModeSupported;
109     jfieldID gameContentTypeSupported;
110     jfieldID preferredBootDisplayMode;
111 } gDynamicDisplayInfoClassInfo;
112 
113 static struct {
114     jclass clazz;
115     jmethodID ctor;
116     jfieldID id;
117     jfieldID width;
118     jfieldID height;
119     jfieldID xDpi;
120     jfieldID yDpi;
121     jfieldID refreshRate;
122     jfieldID appVsyncOffsetNanos;
123     jfieldID presentationDeadlineNanos;
124     jfieldID group;
125 } gDisplayModeClassInfo;
126 
127 static struct {
128     jfieldID bottom;
129     jfieldID left;
130     jfieldID right;
131     jfieldID top;
132 } gRectClassInfo;
133 
134 static struct {
135     jfieldID pixelFormat;
136     jfieldID sourceCrop;
137     jfieldID frameScaleX;
138     jfieldID frameScaleY;
139     jfieldID captureSecureLayers;
140     jfieldID allowProtected;
141     jfieldID uid;
142     jfieldID grayscale;
143 } gCaptureArgsClassInfo;
144 
145 static struct {
146     jfieldID displayToken;
147     jfieldID width;
148     jfieldID height;
149     jfieldID useIdentityTransform;
150 } gDisplayCaptureArgsClassInfo;
151 
152 static struct {
153     jfieldID layer;
154     jfieldID excludeLayers;
155     jfieldID childrenOnly;
156 } gLayerCaptureArgsClassInfo;
157 
158 // Implements SkMallocPixelRef::ReleaseProc, to delete the screenshot on unref.
DeleteScreenshot(void * addr,void * context)159 void DeleteScreenshot(void* addr, void* context) {
160     delete ((ScreenshotClient*) context);
161 }
162 
163 static struct {
164     nsecs_t UNDEFINED_TIME_NANO;
165     jmethodID init;
166 } gWindowContentFrameStatsClassInfo;
167 
168 static struct {
169     nsecs_t UNDEFINED_TIME_NANO;
170     jmethodID init;
171 } gWindowAnimationFrameStatsClassInfo;
172 
173 static struct {
174     jclass clazz;
175     jmethodID ctor;
176 } gHdrCapabilitiesClassInfo;
177 
178 static struct {
179     jclass clazz;
180     jmethodID ctor;
181 } gDeviceProductInfoClassInfo;
182 
183 static struct {
184     jclass clazz;
185     jmethodID ctor;
186 } gDeviceProductInfoManufactureDateClassInfo;
187 
188 static struct {
189     jclass clazz;
190     jmethodID ctor;
191 } gDisplayedContentSampleClassInfo;
192 
193 static struct {
194     jclass clazz;
195     jmethodID ctor;
196 } gDisplayedContentSamplingAttributesClassInfo;
197 
198 static struct {
199     jclass clazz;
200     jmethodID ctor;
201     jfieldID X;
202     jfieldID Y;
203     jfieldID Z;
204 } gCieXyzClassInfo;
205 
206 static struct {
207     jclass clazz;
208     jmethodID ctor;
209     jfieldID red;
210     jfieldID green;
211     jfieldID blue;
212     jfieldID white;
213 } gDisplayPrimariesClassInfo;
214 
215 static struct {
216     jclass clazz;
217     jmethodID builder;
218 } gScreenshotHardwareBufferClassInfo;
219 
220 static struct {
221     jclass clazz;
222     jmethodID onScreenCaptureComplete;
223 } gScreenCaptureListenerClassInfo;
224 
225 static struct {
226     jclass clazz;
227     jmethodID ctor;
228     jfieldID defaultMode;
229     jfieldID allowGroupSwitching;
230     jfieldID primaryRefreshRateMin;
231     jfieldID primaryRefreshRateMax;
232     jfieldID appRequestRefreshRateMin;
233     jfieldID appRequestRefreshRateMax;
234 } gDesiredDisplayModeSpecsClassInfo;
235 
236 static struct {
237     jclass clazz;
238     jmethodID onJankDataAvailable;
239 } gJankDataListenerClassInfo;
240 
241 static struct {
242     jclass clazz;
243     jmethodID ctor;
244 } gJankDataClassInfo;
245 
246 static struct {
247     jclass clazz;
248     jmethodID onTransactionCommitted;
249 } gTransactionCommittedListenerClassInfo;
250 
251 static struct {
252     jclass clazz;
253     jmethodID ctor;
254     jfieldID format;
255     jfieldID alphaInterpretation;
256 } gDisplayDecorationSupportInfo;
257 
258 static struct {
259     jclass clazz;
260     jmethodID invokeReleaseCallback;
261 } gInvokeReleaseCallback;
262 
263 class JNamedColorSpace {
264 public:
265     // ColorSpace.Named.SRGB.ordinal() = 0;
266     static constexpr jint SRGB = 0;
267 
268     // ColorSpace.Named.DISPLAY_P3.ordinal() = 7;
269     static constexpr jint DISPLAY_P3 = 7;
270 };
271 
fromDataspaceToNamedColorSpaceValue(const ui::Dataspace dataspace)272 constexpr jint fromDataspaceToNamedColorSpaceValue(const ui::Dataspace dataspace) {
273     switch (dataspace) {
274         case ui::Dataspace::DISPLAY_P3:
275             return JNamedColorSpace::DISPLAY_P3;
276         default:
277             return JNamedColorSpace::SRGB;
278     }
279 }
280 
pickDataspaceFromColorMode(const ui::ColorMode colorMode)281 constexpr ui::Dataspace pickDataspaceFromColorMode(const ui::ColorMode colorMode) {
282     switch (colorMode) {
283         case ui::ColorMode::DISPLAY_P3:
284         case ui::ColorMode::BT2100_PQ:
285         case ui::ColorMode::BT2100_HLG:
286         case ui::ColorMode::DISPLAY_BT2020:
287             return ui::Dataspace::DISPLAY_P3;
288         default:
289             return ui::Dataspace::V0_SRGB;
290     }
291 }
292 
293 class ScreenCaptureListenerWrapper : public gui::BnScreenCaptureListener {
294 public:
ScreenCaptureListenerWrapper(JNIEnv * env,jobject jobject)295     explicit ScreenCaptureListenerWrapper(JNIEnv* env, jobject jobject) {
296         env->GetJavaVM(&mVm);
297         screenCaptureListenerObject = env->NewGlobalRef(jobject);
298         LOG_ALWAYS_FATAL_IF(!screenCaptureListenerObject, "Failed to make global ref");
299     }
300 
~ScreenCaptureListenerWrapper()301     ~ScreenCaptureListenerWrapper() {
302         if (screenCaptureListenerObject) {
303             getenv()->DeleteGlobalRef(screenCaptureListenerObject);
304             screenCaptureListenerObject = nullptr;
305         }
306     }
307 
onScreenCaptureCompleted(const gui::ScreenCaptureResults & captureResults)308     binder::Status onScreenCaptureCompleted(
309             const gui::ScreenCaptureResults& captureResults) override {
310         JNIEnv* env = getenv();
311         if (captureResults.result != NO_ERROR || captureResults.buffer == nullptr) {
312             env->CallVoidMethod(screenCaptureListenerObject,
313                                 gScreenCaptureListenerClassInfo.onScreenCaptureComplete, nullptr);
314             return binder::Status::ok();
315         }
316         captureResults.fence->waitForever("");
317         jobject jhardwareBuffer = android_hardware_HardwareBuffer_createFromAHardwareBuffer(
318                 env, captureResults.buffer->toAHardwareBuffer());
319         const jint namedColorSpace =
320                 fromDataspaceToNamedColorSpaceValue(captureResults.capturedDataspace);
321         jobject screenshotHardwareBuffer =
322                 env->CallStaticObjectMethod(gScreenshotHardwareBufferClassInfo.clazz,
323                                             gScreenshotHardwareBufferClassInfo.builder,
324                                             jhardwareBuffer, namedColorSpace,
325                                             captureResults.capturedSecureLayers,
326                                             captureResults.capturedHdrLayers);
327         env->CallVoidMethod(screenCaptureListenerObject,
328                             gScreenCaptureListenerClassInfo.onScreenCaptureComplete,
329                             screenshotHardwareBuffer);
330         env->DeleteLocalRef(jhardwareBuffer);
331         env->DeleteLocalRef(screenshotHardwareBuffer);
332         return binder::Status::ok();
333     }
334 
335 private:
336     jobject screenCaptureListenerObject;
337     JavaVM* mVm;
338 
getenv()339     JNIEnv* getenv() {
340         JNIEnv* env;
341         mVm->GetEnv(reinterpret_cast<void**>(&env), JNI_VERSION_1_6);
342         return env;
343     }
344 };
345 
346 class TransactionCommittedListenerWrapper {
347 public:
TransactionCommittedListenerWrapper(JNIEnv * env,jobject object)348     explicit TransactionCommittedListenerWrapper(JNIEnv* env, jobject object) {
349         env->GetJavaVM(&mVm);
350         mTransactionCommittedListenerObject = env->NewGlobalRef(object);
351         LOG_ALWAYS_FATAL_IF(!mTransactionCommittedListenerObject, "Failed to make global ref");
352     }
353 
~TransactionCommittedListenerWrapper()354     ~TransactionCommittedListenerWrapper() {
355         getenv()->DeleteGlobalRef(mTransactionCommittedListenerObject);
356     }
357 
callback()358     void callback() {
359         JNIEnv* env = getenv();
360         env->CallVoidMethod(mTransactionCommittedListenerObject,
361                             gTransactionCommittedListenerClassInfo.onTransactionCommitted);
362     }
363 
transactionCallbackThunk(void * context,nsecs_t,const sp<Fence> &,const std::vector<SurfaceControlStats> &)364     static void transactionCallbackThunk(void* context, nsecs_t /*latchTime*/,
365                                          const sp<Fence>& /*presentFence*/,
366                                          const std::vector<SurfaceControlStats>& /*stats*/) {
367         TransactionCommittedListenerWrapper* listener =
368                 reinterpret_cast<TransactionCommittedListenerWrapper*>(context);
369         listener->callback();
370         delete listener;
371     }
372 
373 private:
374     jobject mTransactionCommittedListenerObject;
375     JavaVM* mVm;
376 
getenv()377     JNIEnv* getenv() {
378         JNIEnv* env;
379         mVm->GetEnv(reinterpret_cast<void**>(&env), JNI_VERSION_1_6);
380         return env;
381     }
382 };
383 
384 // ----------------------------------------------------------------------------
385 
nativeCreateTransaction(JNIEnv * env,jclass clazz)386 static jlong nativeCreateTransaction(JNIEnv* env, jclass clazz) {
387     return reinterpret_cast<jlong>(new SurfaceComposerClient::Transaction);
388 }
389 
releaseTransaction(SurfaceComposerClient::Transaction * t)390 static void releaseTransaction(SurfaceComposerClient::Transaction* t) {
391     delete t;
392 }
393 
nativeGetNativeTransactionFinalizer(JNIEnv * env,jclass clazz)394 static jlong nativeGetNativeTransactionFinalizer(JNIEnv* env, jclass clazz) {
395     return static_cast<jlong>(reinterpret_cast<uintptr_t>(&releaseTransaction));
396 }
397 
nativeCreate(JNIEnv * env,jclass clazz,jobject sessionObj,jstring nameStr,jint w,jint h,jint format,jint flags,jlong parentObject,jobject metadataParcel)398 static jlong nativeCreate(JNIEnv* env, jclass clazz, jobject sessionObj,
399         jstring nameStr, jint w, jint h, jint format, jint flags, jlong parentObject,
400         jobject metadataParcel) {
401     ScopedUtfChars name(env, nameStr);
402     sp<SurfaceComposerClient> client;
403     if (sessionObj != NULL) {
404         client = android_view_SurfaceSession_getClient(env, sessionObj);
405     } else {
406         client = SurfaceComposerClient::getDefault();
407     }
408     SurfaceControl *parent = reinterpret_cast<SurfaceControl*>(parentObject);
409     sp<SurfaceControl> surface;
410     LayerMetadata metadata;
411     Parcel* parcel = parcelForJavaObject(env, metadataParcel);
412     if (parcel && !parcel->objectsCount()) {
413         status_t err = metadata.readFromParcel(parcel);
414         if (err != NO_ERROR) {
415           jniThrowException(env, "java/lang/IllegalArgumentException",
416                             "Metadata parcel has wrong format");
417         }
418     }
419 
420     sp<IBinder> parentHandle;
421     if (parent != nullptr) {
422         parentHandle = parent->getHandle();
423     }
424 
425     status_t err = client->createSurfaceChecked(String8(name.c_str()), w, h, format, &surface,
426                                                 flags, parentHandle, std::move(metadata));
427     if (err == NAME_NOT_FOUND) {
428         jniThrowException(env, "java/lang/IllegalArgumentException", NULL);
429         return 0;
430     } else if (err != NO_ERROR) {
431         jniThrowException(env, OutOfResourcesException, statusToString(err).c_str());
432         return 0;
433     }
434 
435     surface->incStrong((void *)nativeCreate);
436     return reinterpret_cast<jlong>(surface.get());
437 }
438 
nativeRelease(JNIEnv * env,jclass clazz,jlong nativeObject)439 static void nativeRelease(JNIEnv* env, jclass clazz, jlong nativeObject) {
440     sp<SurfaceControl> ctrl(reinterpret_cast<SurfaceControl *>(nativeObject));
441     ctrl->decStrong((void *)nativeCreate);
442 }
443 
nativeDisconnect(JNIEnv * env,jclass clazz,jlong nativeObject)444 static void nativeDisconnect(JNIEnv* env, jclass clazz, jlong nativeObject) {
445     SurfaceControl* const ctrl = reinterpret_cast<SurfaceControl *>(nativeObject);
446     if (ctrl != NULL) {
447         ctrl->disconnect();
448     }
449 }
450 
nativeSetDefaultBufferSize(JNIEnv * env,jclass clazz,jlong nativeObject,jint width,jint height)451 static void nativeSetDefaultBufferSize(JNIEnv* env, jclass clazz, jlong nativeObject,
452                                        jint width, jint height) {
453     SurfaceControl* const ctrl = reinterpret_cast<SurfaceControl *>(nativeObject);
454     if (ctrl != NULL) {
455         ctrl->updateDefaultBufferSize(width, height);
456     }
457 }
458 
rectFromObj(JNIEnv * env,jobject rectObj)459 static Rect rectFromObj(JNIEnv* env, jobject rectObj) {
460     int left = env->GetIntField(rectObj, gRectClassInfo.left);
461     int top = env->GetIntField(rectObj, gRectClassInfo.top);
462     int right = env->GetIntField(rectObj, gRectClassInfo.right);
463     int bottom = env->GetIntField(rectObj, gRectClassInfo.bottom);
464     return Rect(left, top, right, bottom);
465 }
466 
getCaptureArgs(JNIEnv * env,jobject captureArgsObject,CaptureArgs & captureArgs)467 static void getCaptureArgs(JNIEnv* env, jobject captureArgsObject, CaptureArgs& captureArgs) {
468     captureArgs.pixelFormat = static_cast<ui::PixelFormat>(
469             env->GetIntField(captureArgsObject, gCaptureArgsClassInfo.pixelFormat));
470     captureArgs.sourceCrop =
471             rectFromObj(env,
472                         env->GetObjectField(captureArgsObject, gCaptureArgsClassInfo.sourceCrop));
473     captureArgs.frameScaleX =
474             env->GetFloatField(captureArgsObject, gCaptureArgsClassInfo.frameScaleX);
475     captureArgs.frameScaleY =
476             env->GetFloatField(captureArgsObject, gCaptureArgsClassInfo.frameScaleY);
477     captureArgs.captureSecureLayers =
478             env->GetBooleanField(captureArgsObject, gCaptureArgsClassInfo.captureSecureLayers);
479     captureArgs.allowProtected =
480             env->GetBooleanField(captureArgsObject, gCaptureArgsClassInfo.allowProtected);
481     captureArgs.uid = env->GetLongField(captureArgsObject, gCaptureArgsClassInfo.uid);
482     captureArgs.grayscale =
483             env->GetBooleanField(captureArgsObject, gCaptureArgsClassInfo.grayscale);
484 }
485 
displayCaptureArgsFromObject(JNIEnv * env,jobject displayCaptureArgsObject)486 static DisplayCaptureArgs displayCaptureArgsFromObject(JNIEnv* env,
487                                                        jobject displayCaptureArgsObject) {
488     DisplayCaptureArgs captureArgs;
489     getCaptureArgs(env, displayCaptureArgsObject, captureArgs);
490 
491     captureArgs.displayToken =
492             ibinderForJavaObject(env,
493                                  env->GetObjectField(displayCaptureArgsObject,
494                                                      gDisplayCaptureArgsClassInfo.displayToken));
495     captureArgs.width =
496             env->GetIntField(displayCaptureArgsObject, gDisplayCaptureArgsClassInfo.width);
497     captureArgs.height =
498             env->GetIntField(displayCaptureArgsObject, gDisplayCaptureArgsClassInfo.height);
499     captureArgs.useIdentityTransform =
500             env->GetBooleanField(displayCaptureArgsObject,
501                                  gDisplayCaptureArgsClassInfo.useIdentityTransform);
502     return captureArgs;
503 }
504 
nativeCaptureDisplay(JNIEnv * env,jclass clazz,jobject displayCaptureArgsObject,jobject screenCaptureListenerObject)505 static jint nativeCaptureDisplay(JNIEnv* env, jclass clazz, jobject displayCaptureArgsObject,
506                                  jobject screenCaptureListenerObject) {
507     const DisplayCaptureArgs captureArgs =
508             displayCaptureArgsFromObject(env, displayCaptureArgsObject);
509 
510     if (captureArgs.displayToken == NULL) {
511         return BAD_VALUE;
512     }
513 
514     sp<IScreenCaptureListener> captureListener =
515             new ScreenCaptureListenerWrapper(env, screenCaptureListenerObject);
516     return ScreenshotClient::captureDisplay(captureArgs, captureListener);
517 }
518 
nativeCaptureLayers(JNIEnv * env,jclass clazz,jobject layerCaptureArgsObject,jobject screenCaptureListenerObject)519 static jint nativeCaptureLayers(JNIEnv* env, jclass clazz, jobject layerCaptureArgsObject,
520                                 jobject screenCaptureListenerObject) {
521     LayerCaptureArgs captureArgs;
522     getCaptureArgs(env, layerCaptureArgsObject, captureArgs);
523     SurfaceControl* layer = reinterpret_cast<SurfaceControl*>(
524             env->GetLongField(layerCaptureArgsObject, gLayerCaptureArgsClassInfo.layer));
525     if (layer == nullptr) {
526         return BAD_VALUE;
527     }
528 
529     captureArgs.layerHandle = layer->getHandle();
530     captureArgs.childrenOnly =
531             env->GetBooleanField(layerCaptureArgsObject, gLayerCaptureArgsClassInfo.childrenOnly);
532     jlongArray excludeObjectArray = reinterpret_cast<jlongArray>(
533             env->GetObjectField(layerCaptureArgsObject, gLayerCaptureArgsClassInfo.excludeLayers));
534     if (excludeObjectArray != NULL) {
535         const jsize len = env->GetArrayLength(excludeObjectArray);
536         captureArgs.excludeHandles.reserve(len);
537 
538         const jlong* objects = env->GetLongArrayElements(excludeObjectArray, nullptr);
539         for (jsize i = 0; i < len; i++) {
540             auto excludeObject = reinterpret_cast<SurfaceControl *>(objects[i]);
541             if (excludeObject == nullptr) {
542                 jniThrowNullPointerException(env, "Exclude layer is null");
543                 return NULL;
544             }
545             captureArgs.excludeHandles.emplace(excludeObject->getHandle());
546         }
547         env->ReleaseLongArrayElements(excludeObjectArray, const_cast<jlong*>(objects), JNI_ABORT);
548     }
549 
550     sp<IScreenCaptureListener> captureListener =
551             new ScreenCaptureListenerWrapper(env, screenCaptureListenerObject);
552     return ScreenshotClient::captureLayers(captureArgs, captureListener);
553 }
554 
nativeApplyTransaction(JNIEnv * env,jclass clazz,jlong transactionObj,jboolean sync)555 static void nativeApplyTransaction(JNIEnv* env, jclass clazz, jlong transactionObj, jboolean sync) {
556     auto transaction = reinterpret_cast<SurfaceComposerClient::Transaction*>(transactionObj);
557     transaction->apply(sync);
558 }
559 
nativeMergeTransaction(JNIEnv * env,jclass clazz,jlong transactionObj,jlong otherTransactionObj)560 static void nativeMergeTransaction(JNIEnv* env, jclass clazz,
561         jlong transactionObj, jlong otherTransactionObj) {
562     auto transaction = reinterpret_cast<SurfaceComposerClient::Transaction*>(transactionObj);
563     auto otherTransaction = reinterpret_cast<SurfaceComposerClient::Transaction*>(
564             otherTransactionObj);
565     transaction->merge(std::move(*otherTransaction));
566 }
567 
nativeSetAnimationTransaction(JNIEnv * env,jclass clazz,jlong transactionObj)568 static void nativeSetAnimationTransaction(JNIEnv* env, jclass clazz, jlong transactionObj) {
569     auto transaction = reinterpret_cast<SurfaceComposerClient::Transaction*>(transactionObj);
570     transaction->setAnimationTransaction();
571 }
572 
nativeSetEarlyWakeupStart(JNIEnv * env,jclass clazz,jlong transactionObj)573 static void nativeSetEarlyWakeupStart(JNIEnv* env, jclass clazz, jlong transactionObj) {
574     auto transaction = reinterpret_cast<SurfaceComposerClient::Transaction*>(transactionObj);
575     transaction->setEarlyWakeupStart();
576 }
577 
nativeSetEarlyWakeupEnd(JNIEnv * env,jclass clazz,jlong transactionObj)578 static void nativeSetEarlyWakeupEnd(JNIEnv* env, jclass clazz, jlong transactionObj) {
579     auto transaction = reinterpret_cast<SurfaceComposerClient::Transaction*>(transactionObj);
580     transaction->setEarlyWakeupEnd();
581 }
582 
nativeGetTransactionId(JNIEnv * env,jclass clazz,jlong transactionObj)583 static jlong nativeGetTransactionId(JNIEnv* env, jclass clazz, jlong transactionObj) {
584     auto transaction = reinterpret_cast<SurfaceComposerClient::Transaction*>(transactionObj);
585     return transaction->getId();
586 }
587 
nativeSetLayer(JNIEnv * env,jclass clazz,jlong transactionObj,jlong nativeObject,jint zorder)588 static void nativeSetLayer(JNIEnv* env, jclass clazz, jlong transactionObj,
589         jlong nativeObject, jint zorder) {
590     auto transaction = reinterpret_cast<SurfaceComposerClient::Transaction*>(transactionObj);
591 
592     SurfaceControl* const ctrl = reinterpret_cast<SurfaceControl *>(nativeObject);
593     transaction->setLayer(ctrl, zorder);
594 }
595 
nativeSetRelativeLayer(JNIEnv * env,jclass clazz,jlong transactionObj,jlong nativeObject,jlong relativeToObject,jint zorder)596 static void nativeSetRelativeLayer(JNIEnv* env, jclass clazz, jlong transactionObj,
597         jlong nativeObject,
598         jlong relativeToObject, jint zorder) {
599 
600     auto ctrl = reinterpret_cast<SurfaceControl *>(nativeObject);
601     auto relative = reinterpret_cast<SurfaceControl *>(relativeToObject);
602     auto transaction = reinterpret_cast<SurfaceComposerClient::Transaction*>(transactionObj);
603     transaction->setRelativeLayer(ctrl, relative, zorder);
604 }
605 
nativeSetPosition(JNIEnv * env,jclass clazz,jlong transactionObj,jlong nativeObject,jfloat x,jfloat y)606 static void nativeSetPosition(JNIEnv* env, jclass clazz, jlong transactionObj,
607         jlong nativeObject, jfloat x, jfloat y) {
608     auto transaction = reinterpret_cast<SurfaceComposerClient::Transaction*>(transactionObj);
609 
610     SurfaceControl* const ctrl = reinterpret_cast<SurfaceControl *>(nativeObject);
611     transaction->setPosition(ctrl, x, y);
612 }
613 
nativeSetScale(JNIEnv * env,jclass clazz,jlong transactionObj,jlong nativeObject,jfloat xScale,jfloat yScale)614 static void nativeSetScale(JNIEnv* env, jclass clazz, jlong transactionObj, jlong nativeObject,
615                            jfloat xScale, jfloat yScale) {
616     auto transaction = reinterpret_cast<SurfaceComposerClient::Transaction*>(transactionObj);
617 
618     SurfaceControl* const ctrl = reinterpret_cast<SurfaceControl*>(nativeObject);
619     transaction->setMatrix(ctrl, xScale, 0, 0, yScale);
620 }
621 
nativeSetGeometry(JNIEnv * env,jclass clazz,jlong transactionObj,jlong nativeObject,jobject sourceObj,jobject dstObj,jlong orientation)622 static void nativeSetGeometry(JNIEnv* env, jclass clazz, jlong transactionObj, jlong nativeObject,
623         jobject sourceObj, jobject dstObj, jlong orientation) {
624     auto transaction = reinterpret_cast<SurfaceComposerClient::Transaction*>(transactionObj);
625     SurfaceControl* const ctrl = reinterpret_cast<SurfaceControl *>(nativeObject);
626 
627     Rect source, dst;
628     if (sourceObj != NULL) {
629         source = rectFromObj(env, sourceObj);
630     } else {
631         source.makeInvalid();
632     }
633     if (dstObj != NULL) {
634         dst = rectFromObj(env, dstObj);
635     } else {
636         dst.makeInvalid();
637     }
638     transaction->setGeometry(ctrl, source, dst, orientation);
639 }
640 
641 class JGlobalRefHolder {
642 public:
JGlobalRefHolder(JavaVM * vm,jobject object)643     JGlobalRefHolder(JavaVM* vm, jobject object) : mVm(vm), mObject(object) {}
644 
~JGlobalRefHolder()645     virtual ~JGlobalRefHolder() {
646         env()->DeleteGlobalRef(mObject);
647         mObject = nullptr;
648     }
649 
object()650     jobject object() { return mObject; }
vm()651     JavaVM* vm() { return mVm; }
652 
env()653     JNIEnv* env() {
654         JNIEnv* env = nullptr;
655         if (mVm->GetEnv(reinterpret_cast<void**>(&env), JNI_VERSION_1_6) != JNI_OK) {
656             if (mVm->AttachCurrentThreadAsDaemon(&env, nullptr) != JNI_OK) {
657                 LOG_ALWAYS_FATAL("Failed to AttachCurrentThread!");
658             }
659         }
660         return env;
661     }
662 
663 private:
664     JGlobalRefHolder(const JGlobalRefHolder&) = delete;
665     void operator=(const JGlobalRefHolder&) = delete;
666 
667     JavaVM* mVm;
668     jobject mObject;
669 };
670 
genReleaseCallback(JNIEnv * env,jobject releaseCallback)671 static ReleaseBufferCallback genReleaseCallback(JNIEnv* env, jobject releaseCallback) {
672     if (releaseCallback == nullptr) return nullptr;
673 
674     JavaVM* vm = nullptr;
675     LOG_ALWAYS_FATAL_IF(env->GetJavaVM(&vm) != JNI_OK, "Unable to get Java VM");
676     auto globalCallbackRef =
677             std::make_shared<JGlobalRefHolder>(vm, env->NewGlobalRef(releaseCallback));
678     return [globalCallbackRef](const ReleaseCallbackId&, const sp<Fence>& releaseFence,
679                                std::optional<uint32_t> currentMaxAcquiredBufferCount) {
680         Fence* fenceCopy = releaseFence.get();
681         // We need to grab an extra ref as Java's SyncFence takes ownership
682         if (fenceCopy) {
683             fenceCopy->incStrong(0);
684         }
685         globalCallbackRef->env()->CallStaticVoidMethod(gInvokeReleaseCallback.clazz,
686                                                        gInvokeReleaseCallback.invokeReleaseCallback,
687                                                        globalCallbackRef->object(),
688                                                        reinterpret_cast<jlong>(fenceCopy));
689     };
690 }
691 
nativeSetBuffer(JNIEnv * env,jclass clazz,jlong transactionObj,jlong nativeObject,jobject bufferObject,jlong fencePtr,jobject releaseCallback)692 static void nativeSetBuffer(JNIEnv* env, jclass clazz, jlong transactionObj, jlong nativeObject,
693                             jobject bufferObject, jlong fencePtr, jobject releaseCallback) {
694     auto transaction = reinterpret_cast<SurfaceComposerClient::Transaction*>(transactionObj);
695     SurfaceControl* const ctrl = reinterpret_cast<SurfaceControl*>(nativeObject);
696     sp<GraphicBuffer> graphicBuffer;
697     if (bufferObject != nullptr) {
698         graphicBuffer = GraphicBuffer::fromAHardwareBuffer(
699                 android_hardware_HardwareBuffer_getNativeHardwareBuffer(env, bufferObject));
700     }
701     std::optional<sp<Fence>> optFence = std::nullopt;
702     if (fencePtr != 0) {
703         optFence = sp<Fence>{reinterpret_cast<Fence*>(fencePtr)};
704     }
705     transaction->setBuffer(ctrl, graphicBuffer, optFence, std::nullopt,
706                            genReleaseCallback(env, releaseCallback));
707 }
708 
nativeSetBufferTransform(JNIEnv * env,jclass clazz,jlong transactionObj,jlong nativeObject,jint transform)709 static void nativeSetBufferTransform(JNIEnv* env, jclass clazz, jlong transactionObj,
710                                      jlong nativeObject, jint transform) {
711     auto transaction = reinterpret_cast<SurfaceComposerClient::Transaction*>(transactionObj);
712     SurfaceControl* const ctrl = reinterpret_cast<SurfaceControl*>(nativeObject);
713     transaction->setTransform(ctrl, transform);
714     bool transformToInverseDisplay = (NATIVE_WINDOW_TRANSFORM_INVERSE_DISPLAY & transform) ==
715             NATIVE_WINDOW_TRANSFORM_INVERSE_DISPLAY;
716     transaction->setTransformToDisplayInverse(ctrl, transformToInverseDisplay);
717 }
718 
nativeSetDataSpace(JNIEnv * env,jclass clazz,jlong transactionObj,jlong nativeObject,jint dataSpace)719 static void nativeSetDataSpace(JNIEnv* env, jclass clazz, jlong transactionObj, jlong nativeObject,
720                                jint dataSpace) {
721     auto transaction = reinterpret_cast<SurfaceComposerClient::Transaction*>(transactionObj);
722     SurfaceControl* const ctrl = reinterpret_cast<SurfaceControl*>(nativeObject);
723     ui::Dataspace dataspace = static_cast<ui::Dataspace>(dataSpace);
724     transaction->setDataspace(ctrl, dataspace);
725 }
726 
nativeSetBlurRegions(JNIEnv * env,jclass clazz,jlong transactionObj,jlong nativeObject,jobjectArray regions,jint regionsLength)727 static void nativeSetBlurRegions(JNIEnv* env, jclass clazz, jlong transactionObj,
728                                  jlong nativeObject, jobjectArray regions, jint regionsLength) {
729     auto transaction = reinterpret_cast<SurfaceComposerClient::Transaction*>(transactionObj);
730     SurfaceControl* const ctrl = reinterpret_cast<SurfaceControl*>(nativeObject);
731 
732     std::vector<BlurRegion> blurRegionVector;
733     const int size = regionsLength;
734     float region[10];
735     for (int i = 0; i < size; i++) {
736         jfloatArray regionArray = (jfloatArray)env->GetObjectArrayElement(regions, i);
737         env->GetFloatArrayRegion(regionArray, 0, 10, region);
738         float blurRadius = region[0];
739         float alpha = region[1];
740         float left = region[2];
741         float top = region[3];
742         float right = region[4];
743         float bottom = region[5];
744         float cornerRadiusTL = region[6];
745         float cornerRadiusTR = region[7];
746         float cornerRadiusBL = region[8];
747         float cornerRadiusBR = region[9];
748 
749         blurRegionVector.push_back(BlurRegion{.blurRadius = static_cast<uint32_t>(blurRadius),
750                                               .cornerRadiusTL = cornerRadiusTL,
751                                               .cornerRadiusTR = cornerRadiusTR,
752                                               .cornerRadiusBL = cornerRadiusBL,
753                                               .cornerRadiusBR = cornerRadiusBR,
754                                               .alpha = alpha,
755                                               .left = static_cast<int>(left),
756                                               .top = static_cast<int>(top),
757                                               .right = static_cast<int>(right),
758                                               .bottom = static_cast<int>(bottom)});
759     }
760 
761     transaction->setBlurRegions(ctrl, blurRegionVector);
762 }
763 
nativeSetStretchEffect(JNIEnv * env,jclass clazz,jlong transactionObj,jlong nativeObject,jfloat width,jfloat height,jfloat vecX,jfloat vecY,jfloat maxStretchAmountX,jfloat maxStretchAmountY,jfloat childRelativeLeft,jfloat childRelativeTop,jfloat childRelativeRight,jfloat childRelativeBottom)764 static void nativeSetStretchEffect(JNIEnv* env, jclass clazz, jlong transactionObj,
765                                    jlong nativeObject, jfloat width, jfloat height,
766                                    jfloat vecX, jfloat vecY,
767                                    jfloat maxStretchAmountX, jfloat maxStretchAmountY,
768                                    jfloat childRelativeLeft, jfloat childRelativeTop,
769                                    jfloat childRelativeRight, jfloat childRelativeBottom) {
770     auto transaction = reinterpret_cast<SurfaceComposerClient::Transaction*>(transactionObj);
771     auto* const ctrl = reinterpret_cast<SurfaceControl*>(nativeObject);
772     auto stretch = StretchEffect{
773       .width = width,
774       .height = height,
775       .vectorX = vecX,
776       .vectorY = vecY,
777       .maxAmountX = maxStretchAmountX,
778       .maxAmountY = maxStretchAmountY,
779       .mappedChildBounds = FloatRect(
780           childRelativeLeft, childRelativeTop, childRelativeRight, childRelativeBottom)
781     };
782     transaction->setStretchEffect(ctrl, stretch);
783 }
784 
nativeSetSize(JNIEnv * env,jclass clazz,jlong transactionObj,jlong nativeObject,jint w,jint h)785 static void nativeSetSize(JNIEnv* env, jclass clazz, jlong transactionObj,
786         jlong nativeObject, jint w, jint h) {
787     auto transaction = reinterpret_cast<SurfaceComposerClient::Transaction*>(transactionObj);
788 
789     SurfaceControl* const ctrl = reinterpret_cast<SurfaceControl *>(nativeObject);
790     transaction->setSize(ctrl, w, h);
791 }
792 
nativeSetFlags(JNIEnv * env,jclass clazz,jlong transactionObj,jlong nativeObject,jint flags,jint mask)793 static void nativeSetFlags(JNIEnv* env, jclass clazz, jlong transactionObj,
794         jlong nativeObject, jint flags, jint mask) {
795     auto transaction = reinterpret_cast<SurfaceComposerClient::Transaction*>(transactionObj);
796 
797     SurfaceControl* const ctrl = reinterpret_cast<SurfaceControl *>(nativeObject);
798     transaction->setFlags(ctrl, flags, mask);
799 }
800 
nativeSetFrameRateSelectionPriority(JNIEnv * env,jclass clazz,jlong transactionObj,jlong nativeObject,jint priority)801 static void nativeSetFrameRateSelectionPriority(JNIEnv* env, jclass clazz, jlong transactionObj,
802         jlong nativeObject, jint priority) {
803     auto transaction = reinterpret_cast<SurfaceComposerClient::Transaction*>(transactionObj);
804 
805     SurfaceControl* const ctrl = reinterpret_cast<SurfaceControl *>(nativeObject);
806     transaction->setFrameRateSelectionPriority(ctrl, priority);
807 }
808 
nativeSetTransparentRegionHint(JNIEnv * env,jclass clazz,jlong transactionObj,jlong nativeObject,jobject regionObj)809 static void nativeSetTransparentRegionHint(JNIEnv* env, jclass clazz, jlong transactionObj,
810         jlong nativeObject, jobject regionObj) {
811     SurfaceControl* const ctrl = reinterpret_cast<SurfaceControl *>(nativeObject);
812     graphics::RegionIterator iterator(env, regionObj);
813     if (!iterator.isValid()) {
814         doThrowIAE(env);
815         return;
816     }
817 
818     ARect bounds = iterator.getTotalBounds();
819     Region reg({bounds.left, bounds.top, bounds.right, bounds.bottom});
820     if (iterator.isComplex()) {
821         while (!iterator.isDone()) {
822             ARect rect = iterator.getRect();
823             reg.addRectUnchecked(rect.left, rect.top, rect.right, rect.bottom);
824             iterator.next();
825         }
826     }
827 
828     {
829         auto transaction = reinterpret_cast<SurfaceComposerClient::Transaction*>(transactionObj);
830         transaction->setTransparentRegionHint(ctrl, reg);
831     }
832 }
833 
nativeSetDamageRegion(JNIEnv * env,jclass clazz,jlong transactionObj,jlong nativeObject,jobject regionObj)834 static void nativeSetDamageRegion(JNIEnv* env, jclass clazz, jlong transactionObj,
835                                   jlong nativeObject, jobject regionObj) {
836     SurfaceControl* const surfaceControl = reinterpret_cast<SurfaceControl*>(nativeObject);
837     auto transaction = reinterpret_cast<SurfaceComposerClient::Transaction*>(transactionObj);
838 
839     if (regionObj == nullptr) {
840         transaction->setSurfaceDamageRegion(surfaceControl, Region::INVALID_REGION);
841         return;
842     }
843 
844     graphics::RegionIterator iterator(env, regionObj);
845     if (!iterator.isValid()) {
846         transaction->setSurfaceDamageRegion(surfaceControl, Region::INVALID_REGION);
847         return;
848     }
849 
850     Region region;
851     while (!iterator.isDone()) {
852         ARect rect = iterator.getRect();
853         region.orSelf(static_cast<const Rect&>(rect));
854         iterator.next();
855     }
856 
857     if (region.getBounds().isEmpty()) {
858         transaction->setSurfaceDamageRegion(surfaceControl, Region::INVALID_REGION);
859         return;
860     }
861 
862     transaction->setSurfaceDamageRegion(surfaceControl, region);
863 }
864 
nativeSetDimmingEnabled(JNIEnv * env,jclass clazz,jlong transactionObj,jlong nativeObject,jboolean dimmingEnabled)865 static void nativeSetDimmingEnabled(JNIEnv* env, jclass clazz, jlong transactionObj,
866                                     jlong nativeObject, jboolean dimmingEnabled) {
867     auto transaction = reinterpret_cast<SurfaceComposerClient::Transaction*>(transactionObj);
868 
869     SurfaceControl* const ctrl = reinterpret_cast<SurfaceControl*>(nativeObject);
870     transaction->setDimmingEnabled(ctrl, dimmingEnabled);
871 }
872 
nativeSetAlpha(JNIEnv * env,jclass clazz,jlong transactionObj,jlong nativeObject,jfloat alpha)873 static void nativeSetAlpha(JNIEnv* env, jclass clazz, jlong transactionObj,
874         jlong nativeObject, jfloat alpha) {
875     auto transaction = reinterpret_cast<SurfaceComposerClient::Transaction*>(transactionObj);
876 
877     SurfaceControl* const ctrl = reinterpret_cast<SurfaceControl *>(nativeObject);
878     transaction->setAlpha(ctrl, alpha);
879 }
880 
nativeSetInputWindowInfo(JNIEnv * env,jclass clazz,jlong transactionObj,jlong nativeObject,jobject inputWindow)881 static void nativeSetInputWindowInfo(JNIEnv* env, jclass clazz, jlong transactionObj,
882         jlong nativeObject, jobject inputWindow) {
883     auto transaction = reinterpret_cast<SurfaceComposerClient::Transaction*>(transactionObj);
884 
885     sp<NativeInputWindowHandle> handle = android_view_InputWindowHandle_getHandle(
886             env, inputWindow);
887     handle->updateInfo();
888 
889     auto ctrl = reinterpret_cast<SurfaceControl *>(nativeObject);
890     transaction->setInputWindowInfo(ctrl, *handle->getInfo());
891 }
892 
nativeSyncInputWindows(JNIEnv * env,jclass clazz,jlong transactionObj)893 static void nativeSyncInputWindows(JNIEnv* env, jclass clazz, jlong transactionObj) {
894     auto transaction = reinterpret_cast<SurfaceComposerClient::Transaction*>(transactionObj);
895     transaction->syncInputWindows();
896 }
897 
nativeSetMetadata(JNIEnv * env,jclass clazz,jlong transactionObj,jlong nativeObject,jint id,jobject parcelObj)898 static void nativeSetMetadata(JNIEnv* env, jclass clazz, jlong transactionObj,
899         jlong nativeObject, jint id, jobject parcelObj) {
900     Parcel* parcel = parcelForJavaObject(env, parcelObj);
901     if (!parcel) {
902         jniThrowNullPointerException(env, "attribute data");
903         return;
904     }
905     if (parcel->objectsCount()) {
906         jniThrowException(env, "java/lang/RuntimeException",
907                 "Tried to marshall a Parcel that contained Binder objects.");
908         return;
909     }
910 
911     auto transaction = reinterpret_cast<SurfaceComposerClient::Transaction*>(transactionObj);
912 
913     SurfaceControl* const ctrl = reinterpret_cast<SurfaceControl*>(nativeObject);
914     transaction->setMetadata(ctrl, id, *parcel);
915 }
916 
nativeSetColor(JNIEnv * env,jclass clazz,jlong transactionObj,jlong nativeObject,jfloatArray fColor)917 static void nativeSetColor(JNIEnv* env, jclass clazz, jlong transactionObj,
918         jlong nativeObject, jfloatArray fColor) {
919     auto transaction = reinterpret_cast<SurfaceComposerClient::Transaction*>(transactionObj);
920     SurfaceControl* const ctrl = reinterpret_cast<SurfaceControl *>(nativeObject);
921 
922     float* floatColors = env->GetFloatArrayElements(fColor, 0);
923     half3 color(floatColors[0], floatColors[1], floatColors[2]);
924     transaction->setColor(ctrl, color);
925     env->ReleaseFloatArrayElements(fColor, floatColors, 0);
926 }
927 
nativeSetMatrix(JNIEnv * env,jclass clazz,jlong transactionObj,jlong nativeObject,jfloat dsdx,jfloat dtdx,jfloat dtdy,jfloat dsdy)928 static void nativeSetMatrix(JNIEnv* env, jclass clazz, jlong transactionObj,
929         jlong nativeObject,
930         jfloat dsdx, jfloat dtdx, jfloat dtdy, jfloat dsdy) {
931     auto transaction = reinterpret_cast<SurfaceComposerClient::Transaction*>(transactionObj);
932 
933     SurfaceControl* const ctrl = reinterpret_cast<SurfaceControl *>(nativeObject);
934     transaction->setMatrix(ctrl, dsdx, dtdx, dtdy, dsdy);
935 }
936 
nativeSetColorTransform(JNIEnv * env,jclass clazz,jlong transactionObj,jlong nativeObject,jfloatArray fMatrix,jfloatArray fTranslation)937 static void nativeSetColorTransform(JNIEnv* env, jclass clazz, jlong transactionObj,
938         jlong nativeObject, jfloatArray fMatrix, jfloatArray fTranslation) {
939     auto transaction = reinterpret_cast<SurfaceComposerClient::Transaction*>(transactionObj);
940     SurfaceControl* const surfaceControl = reinterpret_cast<SurfaceControl*>(nativeObject);
941     float* floatMatrix = env->GetFloatArrayElements(fMatrix, 0);
942     mat3 matrix(static_cast<float const*>(floatMatrix));
943     env->ReleaseFloatArrayElements(fMatrix, floatMatrix, 0);
944 
945     float* floatTranslation = env->GetFloatArrayElements(fTranslation, 0);
946     vec3 translation(floatTranslation[0], floatTranslation[1], floatTranslation[2]);
947     env->ReleaseFloatArrayElements(fTranslation, floatTranslation, 0);
948 
949     transaction->setColorTransform(surfaceControl, matrix, translation);
950 }
951 
nativeSetColorSpaceAgnostic(JNIEnv * env,jclass clazz,jlong transactionObj,jlong nativeObject,jboolean agnostic)952 static void nativeSetColorSpaceAgnostic(JNIEnv* env, jclass clazz, jlong transactionObj,
953         jlong nativeObject, jboolean agnostic) {
954     auto transaction = reinterpret_cast<SurfaceComposerClient::Transaction*>(transactionObj);
955     SurfaceControl* const surfaceControl = reinterpret_cast<SurfaceControl*>(nativeObject);
956     transaction->setColorSpaceAgnostic(surfaceControl, agnostic);
957 }
958 
nativeSetWindowCrop(JNIEnv * env,jclass clazz,jlong transactionObj,jlong nativeObject,jint l,jint t,jint r,jint b)959 static void nativeSetWindowCrop(JNIEnv* env, jclass clazz, jlong transactionObj,
960         jlong nativeObject,
961         jint l, jint t, jint r, jint b) {
962     auto transaction = reinterpret_cast<SurfaceComposerClient::Transaction*>(transactionObj);
963 
964     SurfaceControl* const ctrl = reinterpret_cast<SurfaceControl *>(nativeObject);
965     Rect crop(l, t, r, b);
966     transaction->setCrop(ctrl, crop);
967 }
968 
nativeSetCornerRadius(JNIEnv * env,jclass clazz,jlong transactionObj,jlong nativeObject,jfloat cornerRadius)969 static void nativeSetCornerRadius(JNIEnv* env, jclass clazz, jlong transactionObj,
970          jlong nativeObject, jfloat cornerRadius) {
971     auto transaction = reinterpret_cast<SurfaceComposerClient::Transaction*>(transactionObj);
972 
973     SurfaceControl* const ctrl = reinterpret_cast<SurfaceControl *>(nativeObject);
974     transaction->setCornerRadius(ctrl, cornerRadius);
975 }
976 
nativeSetBackgroundBlurRadius(JNIEnv * env,jclass clazz,jlong transactionObj,jlong nativeObject,jint blurRadius)977 static void nativeSetBackgroundBlurRadius(JNIEnv* env, jclass clazz, jlong transactionObj,
978          jlong nativeObject, jint blurRadius) {
979     auto transaction = reinterpret_cast<SurfaceComposerClient::Transaction*>(transactionObj);
980 
981     SurfaceControl* const ctrl = reinterpret_cast<SurfaceControl *>(nativeObject);
982     transaction->setBackgroundBlurRadius(ctrl, blurRadius);
983 }
984 
nativeSetLayerStack(JNIEnv * env,jclass clazz,jlong transactionObj,jlong nativeObject,jint layerStack)985 static void nativeSetLayerStack(JNIEnv* env, jclass clazz, jlong transactionObj,
986         jlong nativeObject, jint layerStack) {
987     auto transaction = reinterpret_cast<SurfaceComposerClient::Transaction*>(transactionObj);
988 
989     SurfaceControl* const ctrl = reinterpret_cast<SurfaceControl *>(nativeObject);
990     transaction->setLayerStack(ctrl, ui::LayerStack::fromValue(layerStack));
991 }
992 
nativeSetShadowRadius(JNIEnv * env,jclass clazz,jlong transactionObj,jlong nativeObject,jfloat shadowRadius)993 static void nativeSetShadowRadius(JNIEnv* env, jclass clazz, jlong transactionObj,
994          jlong nativeObject, jfloat shadowRadius) {
995     auto transaction = reinterpret_cast<SurfaceComposerClient::Transaction*>(transactionObj);
996 
997     const auto ctrl = reinterpret_cast<SurfaceControl *>(nativeObject);
998     transaction->setShadowRadius(ctrl, shadowRadius);
999 }
1000 
nativeSetTrustedOverlay(JNIEnv * env,jclass clazz,jlong transactionObj,jlong nativeObject,jboolean isTrustedOverlay)1001 static void nativeSetTrustedOverlay(JNIEnv* env, jclass clazz, jlong transactionObj,
1002                                     jlong nativeObject, jboolean isTrustedOverlay) {
1003     auto transaction = reinterpret_cast<SurfaceComposerClient::Transaction*>(transactionObj);
1004 
1005     SurfaceControl* const ctrl = reinterpret_cast<SurfaceControl *>(nativeObject);
1006     transaction->setTrustedOverlay(ctrl, isTrustedOverlay);
1007 }
1008 
nativeSetFrameRate(JNIEnv * env,jclass clazz,jlong transactionObj,jlong nativeObject,jfloat frameRate,jint compatibility,jint changeFrameRateStrategy)1009 static void nativeSetFrameRate(JNIEnv* env, jclass clazz, jlong transactionObj, jlong nativeObject,
1010                                jfloat frameRate, jint compatibility, jint changeFrameRateStrategy) {
1011     auto transaction = reinterpret_cast<SurfaceComposerClient::Transaction*>(transactionObj);
1012 
1013     const auto ctrl = reinterpret_cast<SurfaceControl*>(nativeObject);
1014     // Our compatibility is a Surface.FRAME_RATE_COMPATIBILITY_* value, and
1015     // Transaction::setFrameRate() takes an ANATIVEWINDOW_FRAME_RATE_COMPATIBILITY_* value. The
1016     // values are identical though, so no need to convert anything.
1017     transaction->setFrameRate(ctrl, frameRate, static_cast<int8_t>(compatibility),
1018                               static_cast<int8_t>(changeFrameRateStrategy));
1019 }
1020 
nativeSetFixedTransformHint(JNIEnv * env,jclass clazz,jlong transactionObj,jlong nativeObject,jint transformHint)1021 static void nativeSetFixedTransformHint(JNIEnv* env, jclass clazz, jlong transactionObj,
1022                                         jlong nativeObject, jint transformHint) {
1023     auto transaction = reinterpret_cast<SurfaceComposerClient::Transaction*>(transactionObj);
1024 
1025     SurfaceControl* const ctrl = reinterpret_cast<SurfaceControl*>(nativeObject);
1026     transaction->setFixedTransformHint(ctrl, transformHint);
1027 }
1028 
nativeSetDropInputMode(JNIEnv * env,jclass clazz,jlong transactionObj,jlong nativeObject,jint mode)1029 static void nativeSetDropInputMode(JNIEnv* env, jclass clazz, jlong transactionObj,
1030                                    jlong nativeObject, jint mode) {
1031     auto transaction = reinterpret_cast<SurfaceComposerClient::Transaction*>(transactionObj);
1032     SurfaceControl* const ctrl = reinterpret_cast<SurfaceControl*>(nativeObject);
1033     transaction->setDropInputMode(ctrl, static_cast<gui::DropInputMode>(mode));
1034 }
1035 
nativeSanitize(JNIEnv * env,jclass clazz,jlong transactionObj)1036 static void nativeSanitize(JNIEnv* env, jclass clazz, jlong transactionObj) {
1037     auto transaction = reinterpret_cast<SurfaceComposerClient::Transaction*>(transactionObj);
1038     transaction->sanitize();
1039 }
1040 
nativeSetDestinationFrame(JNIEnv * env,jclass clazz,jlong transactionObj,jlong nativeObject,jint l,jint t,jint r,jint b)1041 static void nativeSetDestinationFrame(JNIEnv* env, jclass clazz, jlong transactionObj,
1042                                       jlong nativeObject, jint l, jint t, jint r, jint b) {
1043     auto transaction = reinterpret_cast<SurfaceComposerClient::Transaction*>(transactionObj);
1044     SurfaceControl* const ctrl = reinterpret_cast<SurfaceControl*>(nativeObject);
1045     Rect crop(l, t, r, b);
1046     transaction->setDestinationFrame(ctrl, crop);
1047 }
1048 
nativeGetPhysicalDisplayIds(JNIEnv * env,jclass clazz)1049 static jlongArray nativeGetPhysicalDisplayIds(JNIEnv* env, jclass clazz) {
1050     const auto displayIds = SurfaceComposerClient::getPhysicalDisplayIds();
1051     jlongArray array = env->NewLongArray(displayIds.size());
1052     if (array == nullptr) {
1053         jniThrowException(env, "java/lang/OutOfMemoryError", nullptr);
1054         return nullptr;
1055     }
1056 
1057     if (displayIds.empty()) {
1058         return array;
1059     }
1060 
1061     jlong* values = env->GetLongArrayElements(array, 0);
1062     for (size_t i = 0; i < displayIds.size(); ++i) {
1063         values[i] = static_cast<jlong>(displayIds[i].value);
1064     }
1065 
1066     env->ReleaseLongArrayElements(array, values, 0);
1067     return array;
1068 }
1069 
nativeGetPrimaryPhysicalDisplayId(JNIEnv * env,jclass clazz)1070 static jlong nativeGetPrimaryPhysicalDisplayId(JNIEnv* env, jclass clazz) {
1071     PhysicalDisplayId displayId;
1072     SurfaceComposerClient::getPrimaryPhysicalDisplayId(&displayId);
1073     return static_cast<jlong>(displayId.value);
1074 }
1075 
nativeGetPhysicalDisplayToken(JNIEnv * env,jclass clazz,jlong physicalDisplayId)1076 static jobject nativeGetPhysicalDisplayToken(JNIEnv* env, jclass clazz, jlong physicalDisplayId) {
1077     const auto id = DisplayId::fromValue<PhysicalDisplayId>(physicalDisplayId);
1078     if (!id) return nullptr;
1079     sp<IBinder> token = SurfaceComposerClient::getPhysicalDisplayToken(*id);
1080     return javaObjectForIBinder(env, token);
1081 }
1082 
nativeGetDisplayedContentSamplingAttributes(JNIEnv * env,jclass clazz,jobject tokenObj)1083 static jobject nativeGetDisplayedContentSamplingAttributes(JNIEnv* env, jclass clazz,
1084         jobject tokenObj) {
1085     sp<IBinder> token(ibinderForJavaObject(env, tokenObj));
1086 
1087     ui::PixelFormat format;
1088     ui::Dataspace dataspace;
1089     uint8_t componentMask;
1090     status_t err = SurfaceComposerClient::getDisplayedContentSamplingAttributes(
1091             token, &format, &dataspace, &componentMask);
1092     if (err != OK) {
1093         return nullptr;
1094     }
1095     return env->NewObject(gDisplayedContentSamplingAttributesClassInfo.clazz,
1096                           gDisplayedContentSamplingAttributesClassInfo.ctor,
1097                           format, dataspace, componentMask);
1098 }
1099 
nativeSetDisplayedContentSamplingEnabled(JNIEnv * env,jclass clazz,jobject tokenObj,jboolean enable,jint componentMask,jint maxFrames)1100 static jboolean nativeSetDisplayedContentSamplingEnabled(JNIEnv* env, jclass clazz,
1101         jobject tokenObj, jboolean enable, jint componentMask, jint maxFrames) {
1102     sp<IBinder> token(ibinderForJavaObject(env, tokenObj));
1103     status_t rc = SurfaceComposerClient::setDisplayContentSamplingEnabled(
1104             token, enable, componentMask, maxFrames);
1105     return rc == OK;
1106 }
1107 
nativeGetDisplayedContentSample(JNIEnv * env,jclass clazz,jobject tokenObj,jlong maxFrames,jlong timestamp)1108 static jobject nativeGetDisplayedContentSample(JNIEnv* env, jclass clazz, jobject tokenObj,
1109     jlong maxFrames, jlong timestamp) {
1110     sp<IBinder> token(ibinderForJavaObject(env, tokenObj));
1111 
1112     DisplayedFrameStats stats;
1113     status_t err = SurfaceComposerClient::getDisplayedContentSample(
1114             token, maxFrames, timestamp, &stats);
1115     if (err != OK) {
1116         return nullptr;
1117     }
1118 
1119     jlongArray histogramComponent0 = env->NewLongArray(stats.component_0_sample.size());
1120     jlongArray histogramComponent1 = env->NewLongArray(stats.component_1_sample.size());
1121     jlongArray histogramComponent2 = env->NewLongArray(stats.component_2_sample.size());
1122     jlongArray histogramComponent3 = env->NewLongArray(stats.component_3_sample.size());
1123     if ((histogramComponent0 == nullptr) ||
1124         (histogramComponent1 == nullptr) ||
1125         (histogramComponent2 == nullptr) ||
1126         (histogramComponent3 == nullptr)) {
1127         return JNI_FALSE;
1128     }
1129 
1130     env->SetLongArrayRegion(histogramComponent0, 0,
1131             stats.component_0_sample.size(),
1132             reinterpret_cast<jlong*>(stats.component_0_sample.data()));
1133     env->SetLongArrayRegion(histogramComponent1, 0,
1134             stats.component_1_sample.size(),
1135             reinterpret_cast<jlong*>(stats.component_1_sample.data()));
1136     env->SetLongArrayRegion(histogramComponent2, 0,
1137             stats.component_2_sample.size(),
1138             reinterpret_cast<jlong*>(stats.component_2_sample.data()));
1139     env->SetLongArrayRegion(histogramComponent3, 0,
1140             stats.component_3_sample.size(),
1141             reinterpret_cast<jlong*>(stats.component_3_sample.data()));
1142     return env->NewObject(gDisplayedContentSampleClassInfo.clazz,
1143                           gDisplayedContentSampleClassInfo.ctor,
1144                           stats.numFrames,
1145                           histogramComponent0,
1146                           histogramComponent1,
1147                           histogramComponent2,
1148                           histogramComponent3);
1149 }
1150 
nativeCreateDisplay(JNIEnv * env,jclass clazz,jstring nameObj,jboolean secure)1151 static jobject nativeCreateDisplay(JNIEnv* env, jclass clazz, jstring nameObj,
1152         jboolean secure) {
1153     ScopedUtfChars name(env, nameObj);
1154     sp<IBinder> token(SurfaceComposerClient::createDisplay(
1155             String8(name.c_str()), bool(secure)));
1156     return javaObjectForIBinder(env, token);
1157 }
1158 
nativeDestroyDisplay(JNIEnv * env,jclass clazz,jobject tokenObj)1159 static void nativeDestroyDisplay(JNIEnv* env, jclass clazz, jobject tokenObj) {
1160     sp<IBinder> token(ibinderForJavaObject(env, tokenObj));
1161     if (token == NULL) return;
1162     SurfaceComposerClient::destroyDisplay(token);
1163 }
1164 
nativeSetDisplaySurface(JNIEnv * env,jclass clazz,jlong transactionObj,jobject tokenObj,jlong nativeSurfaceObject)1165 static void nativeSetDisplaySurface(JNIEnv* env, jclass clazz,
1166         jlong transactionObj,
1167         jobject tokenObj, jlong nativeSurfaceObject) {
1168     sp<IBinder> token(ibinderForJavaObject(env, tokenObj));
1169     if (token == NULL) return;
1170     sp<IGraphicBufferProducer> bufferProducer;
1171     sp<Surface> sur(reinterpret_cast<Surface *>(nativeSurfaceObject));
1172     if (sur != NULL) {
1173         bufferProducer = sur->getIGraphicBufferProducer();
1174     }
1175 
1176 
1177     status_t err = NO_ERROR;
1178     {
1179         auto transaction = reinterpret_cast<SurfaceComposerClient::Transaction*>(transactionObj);
1180         err = transaction->setDisplaySurface(token,
1181                 bufferProducer);
1182     }
1183     if (err != NO_ERROR) {
1184         doThrowIAE(env, "Illegal Surface, could not enable async mode. Was this"
1185                 " Surface created with singleBufferMode?");
1186     }
1187 }
1188 
nativeSetDisplayLayerStack(JNIEnv * env,jclass clazz,jlong transactionObj,jobject tokenObj,jint layerStack)1189 static void nativeSetDisplayLayerStack(JNIEnv* env, jclass clazz,
1190         jlong transactionObj,
1191         jobject tokenObj, jint layerStack) {
1192 
1193     sp<IBinder> token(ibinderForJavaObject(env, tokenObj));
1194     if (token == NULL) return;
1195 
1196     {
1197         auto transaction = reinterpret_cast<SurfaceComposerClient::Transaction*>(transactionObj);
1198         transaction->setDisplayLayerStack(token, ui::LayerStack::fromValue(layerStack));
1199     }
1200 }
1201 
nativeSetDisplayFlags(JNIEnv * env,jclass clazz,jlong transactionObj,jobject tokenObj,jint flags)1202 static void nativeSetDisplayFlags(JNIEnv* env, jclass clazz, jlong transactionObj, jobject tokenObj,
1203                                   jint flags) {
1204     sp<IBinder> token(ibinderForJavaObject(env, tokenObj));
1205     if (token == NULL) return;
1206 
1207     {
1208         auto transaction = reinterpret_cast<SurfaceComposerClient::Transaction*>(transactionObj);
1209         transaction->setDisplayFlags(token, flags);
1210     }
1211 }
1212 
nativeSetDisplayProjection(JNIEnv * env,jclass clazz,jlong transactionObj,jobject tokenObj,jint orientation,jint layerStackRect_left,jint layerStackRect_top,jint layerStackRect_right,jint layerStackRect_bottom,jint displayRect_left,jint displayRect_top,jint displayRect_right,jint displayRect_bottom)1213 static void nativeSetDisplayProjection(JNIEnv* env, jclass clazz,
1214         jlong transactionObj,
1215         jobject tokenObj, jint orientation,
1216         jint layerStackRect_left, jint layerStackRect_top, jint layerStackRect_right, jint layerStackRect_bottom,
1217         jint displayRect_left, jint displayRect_top, jint displayRect_right, jint displayRect_bottom) {
1218     sp<IBinder> token(ibinderForJavaObject(env, tokenObj));
1219     if (token == NULL) return;
1220     Rect layerStackRect(layerStackRect_left, layerStackRect_top, layerStackRect_right, layerStackRect_bottom);
1221     Rect displayRect(displayRect_left, displayRect_top, displayRect_right, displayRect_bottom);
1222 
1223     {
1224         auto transaction = reinterpret_cast<SurfaceComposerClient::Transaction*>(transactionObj);
1225         transaction->setDisplayProjection(token, static_cast<ui::Rotation>(orientation),
1226                                           layerStackRect, displayRect);
1227     }
1228 }
1229 
nativeSetDisplaySize(JNIEnv * env,jclass clazz,jlong transactionObj,jobject tokenObj,jint width,jint height)1230 static void nativeSetDisplaySize(JNIEnv* env, jclass clazz,
1231         jlong transactionObj,
1232         jobject tokenObj, jint width, jint height) {
1233     sp<IBinder> token(ibinderForJavaObject(env, tokenObj));
1234     if (token == NULL) return;
1235 
1236     {
1237         auto transaction = reinterpret_cast<SurfaceComposerClient::Transaction*>(transactionObj);
1238         transaction->setDisplaySize(token, width, height);
1239     }
1240 }
1241 
convertDeviceProductInfoToJavaObject(JNIEnv * env,const std::optional<DeviceProductInfo> & info)1242 static jobject convertDeviceProductInfoToJavaObject(
1243         JNIEnv* env, const std::optional<DeviceProductInfo>& info) {
1244     using ModelYear = android::DeviceProductInfo::ModelYear;
1245     using ManufactureYear = android::DeviceProductInfo::ManufactureYear;
1246     using ManufactureWeekAndYear = android::DeviceProductInfo::ManufactureWeekAndYear;
1247 
1248     if (!info) return nullptr;
1249     jstring name = env->NewStringUTF(info->name.data());
1250     jstring manufacturerPnpId = env->NewStringUTF(info->manufacturerPnpId.data());
1251     jobject productId = env->NewStringUTF(info->productId.data());
1252     const auto& date = info->manufactureOrModelDate;
1253     jobject modelYear, manufactureDate;
1254     if (const auto* model = std::get_if<ModelYear>(&date)) {
1255         modelYear = toInteger(env, model->year);
1256         manufactureDate = nullptr;
1257     } else if (const auto* manufactureWeekAndYear = std::get_if<ManufactureWeekAndYear>(&date)) {
1258         modelYear = nullptr;
1259         manufactureDate = env->NewObject(gDeviceProductInfoManufactureDateClassInfo.clazz,
1260                                                gDeviceProductInfoManufactureDateClassInfo.ctor,
1261                                                toInteger(env, manufactureWeekAndYear->week),
1262                                                toInteger(env, manufactureWeekAndYear->year));
1263     } else if (const auto* manufactureYear = std::get_if<ManufactureYear>(&date)) {
1264         modelYear = nullptr;
1265         manufactureDate = env->NewObject(gDeviceProductInfoManufactureDateClassInfo.clazz,
1266                                        gDeviceProductInfoManufactureDateClassInfo.ctor,
1267                                        nullptr,
1268                                        toInteger(env, manufactureYear->year));
1269     } else {
1270         LOG_FATAL("Unknown alternative for variant DeviceProductInfo::ManufactureOrModelDate");
1271     }
1272     jint connectionToSinkType;
1273     // Relative address maps to HDMI physical address. All addresses are 4 digits long allowing
1274     // for a 5–device-deep hierarchy. For more information, refer:
1275     // Section 8.7 - Physical Address of HDMI Specification Version 1.3a
1276     using android::hardware::display::IDeviceProductInfoConstants;
1277     if (info->relativeAddress.size() != 4) {
1278         connectionToSinkType = IDeviceProductInfoConstants::CONNECTION_TO_SINK_UNKNOWN;
1279     } else if (info->relativeAddress[0] == 0) {
1280         connectionToSinkType = IDeviceProductInfoConstants::CONNECTION_TO_SINK_BUILT_IN;
1281     } else if (info->relativeAddress[1] == 0) {
1282         connectionToSinkType = IDeviceProductInfoConstants::CONNECTION_TO_SINK_DIRECT;
1283     } else {
1284         connectionToSinkType = IDeviceProductInfoConstants::CONNECTION_TO_SINK_TRANSITIVE;
1285     }
1286 
1287     return env->NewObject(gDeviceProductInfoClassInfo.clazz, gDeviceProductInfoClassInfo.ctor, name,
1288                           manufacturerPnpId, productId, modelYear, manufactureDate,
1289                           connectionToSinkType);
1290 }
1291 
nativeGetStaticDisplayInfo(JNIEnv * env,jclass clazz,jobject tokenObj)1292 static jobject nativeGetStaticDisplayInfo(JNIEnv* env, jclass clazz, jobject tokenObj) {
1293     ui::StaticDisplayInfo info;
1294     if (const auto token = ibinderForJavaObject(env, tokenObj);
1295         !token || SurfaceComposerClient::getStaticDisplayInfo(token, &info) != NO_ERROR) {
1296         return nullptr;
1297     }
1298 
1299     jobject object =
1300             env->NewObject(gStaticDisplayInfoClassInfo.clazz, gStaticDisplayInfoClassInfo.ctor);
1301     env->SetBooleanField(object, gStaticDisplayInfoClassInfo.isInternal,
1302                          info.connectionType == ui::DisplayConnectionType::Internal);
1303     env->SetFloatField(object, gStaticDisplayInfoClassInfo.density, info.density);
1304     env->SetBooleanField(object, gStaticDisplayInfoClassInfo.secure, info.secure);
1305     env->SetObjectField(object, gStaticDisplayInfoClassInfo.deviceProductInfo,
1306                         convertDeviceProductInfoToJavaObject(env, info.deviceProductInfo));
1307     env->SetIntField(object, gStaticDisplayInfoClassInfo.installOrientation,
1308                      static_cast<uint32_t>(info.installOrientation));
1309     return object;
1310 }
1311 
convertDisplayModeToJavaObject(JNIEnv * env,const ui::DisplayMode & config)1312 static jobject convertDisplayModeToJavaObject(JNIEnv* env, const ui::DisplayMode& config) {
1313     jobject object = env->NewObject(gDisplayModeClassInfo.clazz, gDisplayModeClassInfo.ctor);
1314     env->SetIntField(object, gDisplayModeClassInfo.id, config.id);
1315     env->SetIntField(object, gDisplayModeClassInfo.width, config.resolution.getWidth());
1316     env->SetIntField(object, gDisplayModeClassInfo.height, config.resolution.getHeight());
1317     env->SetFloatField(object, gDisplayModeClassInfo.xDpi, config.xDpi);
1318     env->SetFloatField(object, gDisplayModeClassInfo.yDpi, config.yDpi);
1319 
1320     env->SetFloatField(object, gDisplayModeClassInfo.refreshRate, config.refreshRate);
1321     env->SetLongField(object, gDisplayModeClassInfo.appVsyncOffsetNanos, config.appVsyncOffset);
1322     env->SetLongField(object, gDisplayModeClassInfo.presentationDeadlineNanos,
1323                       config.presentationDeadline);
1324     env->SetIntField(object, gDisplayModeClassInfo.group, config.group);
1325     return object;
1326 }
1327 
convertHdrCapabilitiesToJavaObject(JNIEnv * env,const HdrCapabilities & capabilities)1328 jobject convertHdrCapabilitiesToJavaObject(JNIEnv* env, const HdrCapabilities& capabilities) {
1329     const auto& types = capabilities.getSupportedHdrTypes();
1330     std::vector<int32_t> intTypes;
1331     for (auto type : types) {
1332         intTypes.push_back(static_cast<int32_t>(type));
1333     }
1334     auto typesArray = env->NewIntArray(types.size());
1335     env->SetIntArrayRegion(typesArray, 0, intTypes.size(), intTypes.data());
1336 
1337     return env->NewObject(gHdrCapabilitiesClassInfo.clazz, gHdrCapabilitiesClassInfo.ctor,
1338                           typesArray, capabilities.getDesiredMaxLuminance(),
1339                           capabilities.getDesiredMaxAverageLuminance(),
1340                           capabilities.getDesiredMinLuminance());
1341 }
1342 
nativeGetDynamicDisplayInfo(JNIEnv * env,jclass clazz,jobject tokenObj)1343 static jobject nativeGetDynamicDisplayInfo(JNIEnv* env, jclass clazz, jobject tokenObj) {
1344     ui::DynamicDisplayInfo info;
1345     if (const auto token = ibinderForJavaObject(env, tokenObj);
1346         !token || SurfaceComposerClient::getDynamicDisplayInfo(token, &info) != NO_ERROR) {
1347         return nullptr;
1348     }
1349 
1350     jobject object =
1351             env->NewObject(gDynamicDisplayInfoClassInfo.clazz, gDynamicDisplayInfoClassInfo.ctor);
1352     if (object == NULL) {
1353         jniThrowException(env, "java/lang/OutOfMemoryError", NULL);
1354         return NULL;
1355     }
1356 
1357     const auto numModes = info.supportedDisplayModes.size();
1358     jobjectArray modesArray = env->NewObjectArray(numModes, gDisplayModeClassInfo.clazz, nullptr);
1359     for (size_t i = 0; i < numModes; i++) {
1360         const ui::DisplayMode& mode = info.supportedDisplayModes[i];
1361         jobject displayModeObj = convertDisplayModeToJavaObject(env, mode);
1362         env->SetObjectArrayElement(modesArray, static_cast<jsize>(i), displayModeObj);
1363         env->DeleteLocalRef(displayModeObj);
1364     }
1365     env->SetObjectField(object, gDynamicDisplayInfoClassInfo.supportedDisplayModes, modesArray);
1366     env->SetIntField(object, gDynamicDisplayInfoClassInfo.activeDisplayModeId,
1367                      info.activeDisplayModeId);
1368 
1369     jintArray colorModesArray = env->NewIntArray(info.supportedColorModes.size());
1370     if (colorModesArray == NULL) {
1371         jniThrowException(env, "java/lang/OutOfMemoryError", NULL);
1372         return NULL;
1373     }
1374     jint* colorModesArrayValues = env->GetIntArrayElements(colorModesArray, 0);
1375     for (size_t i = 0; i < info.supportedColorModes.size(); i++) {
1376         colorModesArrayValues[i] = static_cast<jint>(info.supportedColorModes[i]);
1377     }
1378     env->ReleaseIntArrayElements(colorModesArray, colorModesArrayValues, 0);
1379     env->SetObjectField(object, gDynamicDisplayInfoClassInfo.supportedColorModes, colorModesArray);
1380 
1381     env->SetIntField(object, gDynamicDisplayInfoClassInfo.activeColorMode,
1382                      static_cast<jint>(info.activeColorMode));
1383 
1384     env->SetObjectField(object, gDynamicDisplayInfoClassInfo.hdrCapabilities,
1385                         convertHdrCapabilitiesToJavaObject(env, info.hdrCapabilities));
1386 
1387     env->SetBooleanField(object, gDynamicDisplayInfoClassInfo.autoLowLatencyModeSupported,
1388                          info.autoLowLatencyModeSupported);
1389 
1390     env->SetBooleanField(object, gDynamicDisplayInfoClassInfo.gameContentTypeSupported,
1391                          info.gameContentTypeSupported);
1392 
1393     env->SetIntField(object, gDynamicDisplayInfoClassInfo.preferredBootDisplayMode,
1394                      info.preferredBootDisplayMode);
1395     return object;
1396 }
1397 
nativeSetDesiredDisplayModeSpecs(JNIEnv * env,jclass clazz,jobject tokenObj,jobject DesiredDisplayModeSpecs)1398 static jboolean nativeSetDesiredDisplayModeSpecs(JNIEnv* env, jclass clazz, jobject tokenObj,
1399                                                  jobject DesiredDisplayModeSpecs) {
1400     sp<IBinder> token(ibinderForJavaObject(env, tokenObj));
1401     if (token == nullptr) return JNI_FALSE;
1402 
1403     ui::DisplayModeId defaultMode = env->GetIntField(DesiredDisplayModeSpecs,
1404                                                      gDesiredDisplayModeSpecsClassInfo.defaultMode);
1405     jboolean allowGroupSwitching =
1406             env->GetBooleanField(DesiredDisplayModeSpecs,
1407                                  gDesiredDisplayModeSpecsClassInfo.allowGroupSwitching);
1408     jfloat primaryRefreshRateMin =
1409             env->GetFloatField(DesiredDisplayModeSpecs,
1410                                gDesiredDisplayModeSpecsClassInfo.primaryRefreshRateMin);
1411     jfloat primaryRefreshRateMax =
1412             env->GetFloatField(DesiredDisplayModeSpecs,
1413                                gDesiredDisplayModeSpecsClassInfo.primaryRefreshRateMax);
1414     jfloat appRequestRefreshRateMin =
1415             env->GetFloatField(DesiredDisplayModeSpecs,
1416                                gDesiredDisplayModeSpecsClassInfo.appRequestRefreshRateMin);
1417     jfloat appRequestRefreshRateMax =
1418             env->GetFloatField(DesiredDisplayModeSpecs,
1419                                gDesiredDisplayModeSpecsClassInfo.appRequestRefreshRateMax);
1420 
1421     size_t result = SurfaceComposerClient::setDesiredDisplayModeSpecs(token, defaultMode,
1422                                                                       allowGroupSwitching,
1423                                                                       primaryRefreshRateMin,
1424                                                                       primaryRefreshRateMax,
1425                                                                       appRequestRefreshRateMin,
1426                                                                       appRequestRefreshRateMax);
1427     return result == NO_ERROR ? JNI_TRUE : JNI_FALSE;
1428 }
1429 
nativeGetDesiredDisplayModeSpecs(JNIEnv * env,jclass clazz,jobject tokenObj)1430 static jobject nativeGetDesiredDisplayModeSpecs(JNIEnv* env, jclass clazz, jobject tokenObj) {
1431     sp<IBinder> token(ibinderForJavaObject(env, tokenObj));
1432     if (token == nullptr) return nullptr;
1433 
1434     ui::DisplayModeId defaultMode;
1435     bool allowGroupSwitching;
1436     float primaryRefreshRateMin;
1437     float primaryRefreshRateMax;
1438     float appRequestRefreshRateMin;
1439     float appRequestRefreshRateMax;
1440     if (SurfaceComposerClient::getDesiredDisplayModeSpecs(token, &defaultMode, &allowGroupSwitching,
1441                                                           &primaryRefreshRateMin,
1442                                                           &primaryRefreshRateMax,
1443                                                           &appRequestRefreshRateMin,
1444                                                           &appRequestRefreshRateMax) != NO_ERROR) {
1445         return nullptr;
1446     }
1447 
1448     return env->NewObject(gDesiredDisplayModeSpecsClassInfo.clazz,
1449                           gDesiredDisplayModeSpecsClassInfo.ctor, defaultMode, allowGroupSwitching,
1450                           primaryRefreshRateMin, primaryRefreshRateMax, appRequestRefreshRateMin,
1451                           appRequestRefreshRateMax);
1452 }
1453 
nativeGetDisplayNativePrimaries(JNIEnv * env,jclass,jobject tokenObj)1454 static jobject nativeGetDisplayNativePrimaries(JNIEnv* env, jclass, jobject tokenObj) {
1455     sp<IBinder> token(ibinderForJavaObject(env, tokenObj));
1456     if (token == NULL) return NULL;
1457 
1458     ui::DisplayPrimaries primaries;
1459     if (SurfaceComposerClient::getDisplayNativePrimaries(token, primaries) != NO_ERROR) {
1460         return NULL;
1461     }
1462 
1463     jobject jred = env->NewObject(gCieXyzClassInfo.clazz, gCieXyzClassInfo.ctor);
1464     if (jred == NULL) {
1465         jniThrowException(env, "java/lang/OutOfMemoryError", NULL);
1466         return NULL;
1467     }
1468 
1469     jobject jgreen = env->NewObject(gCieXyzClassInfo.clazz, gCieXyzClassInfo.ctor);
1470     if (jgreen == NULL) {
1471         jniThrowException(env, "java/lang/OutOfMemoryError", NULL);
1472         return NULL;
1473     }
1474 
1475     jobject jblue = env->NewObject(gCieXyzClassInfo.clazz, gCieXyzClassInfo.ctor);
1476     if (jblue == NULL) {
1477         jniThrowException(env, "java/lang/OutOfMemoryError", NULL);
1478         return NULL;
1479     }
1480 
1481     jobject jwhite = env->NewObject(gCieXyzClassInfo.clazz, gCieXyzClassInfo.ctor);
1482     if (jwhite == NULL) {
1483         jniThrowException(env, "java/lang/OutOfMemoryError", NULL);
1484         return NULL;
1485     }
1486 
1487     jobject jprimaries = env->NewObject(gDisplayPrimariesClassInfo.clazz,
1488             gDisplayPrimariesClassInfo.ctor);
1489     if (jprimaries == NULL) {
1490         jniThrowException(env, "java/lang/OutOfMemoryError", NULL);
1491         return NULL;
1492     }
1493 
1494     env->SetFloatField(jred, gCieXyzClassInfo.X, primaries.red.X);
1495     env->SetFloatField(jred, gCieXyzClassInfo.Y, primaries.red.Y);
1496     env->SetFloatField(jred, gCieXyzClassInfo.Z, primaries.red.Z);
1497     env->SetFloatField(jgreen, gCieXyzClassInfo.X, primaries.green.X);
1498     env->SetFloatField(jgreen, gCieXyzClassInfo.Y, primaries.green.Y);
1499     env->SetFloatField(jgreen, gCieXyzClassInfo.Z, primaries.green.Z);
1500     env->SetFloatField(jblue, gCieXyzClassInfo.X, primaries.blue.X);
1501     env->SetFloatField(jblue, gCieXyzClassInfo.Y, primaries.blue.Y);
1502     env->SetFloatField(jblue, gCieXyzClassInfo.Z, primaries.blue.Z);
1503     env->SetFloatField(jwhite, gCieXyzClassInfo.X, primaries.white.X);
1504     env->SetFloatField(jwhite, gCieXyzClassInfo.Y, primaries.white.Y);
1505     env->SetFloatField(jwhite, gCieXyzClassInfo.Z, primaries.white.Z);
1506     env->SetObjectField(jprimaries, gDisplayPrimariesClassInfo.red, jred);
1507     env->SetObjectField(jprimaries, gDisplayPrimariesClassInfo.green, jgreen);
1508     env->SetObjectField(jprimaries, gDisplayPrimariesClassInfo.blue, jblue);
1509     env->SetObjectField(jprimaries, gDisplayPrimariesClassInfo.white, jwhite);
1510 
1511     return jprimaries;
1512 }
1513 
nativeGetCompositionDataspaces(JNIEnv * env,jclass)1514 static jintArray nativeGetCompositionDataspaces(JNIEnv* env, jclass) {
1515     ui::Dataspace defaultDataspace, wcgDataspace;
1516     ui::PixelFormat defaultPixelFormat, wcgPixelFormat;
1517     if (SurfaceComposerClient::getCompositionPreference(&defaultDataspace,
1518                                                         &defaultPixelFormat,
1519                                                         &wcgDataspace,
1520                                                         &wcgPixelFormat) != NO_ERROR) {
1521         return nullptr;
1522     }
1523     jintArray array = env->NewIntArray(2);
1524     if (array == nullptr) {
1525         jniThrowException(env, "java/lang/OutOfMemoryError", nullptr);
1526         return nullptr;
1527     }
1528     jint* arrayValues = env->GetIntArrayElements(array, 0);
1529     arrayValues[0] = static_cast<jint>(defaultDataspace);
1530     arrayValues[1] = static_cast<jint>(wcgDataspace);
1531     env->ReleaseIntArrayElements(array, arrayValues, 0);
1532     return array;
1533 }
1534 
nativeSetActiveColorMode(JNIEnv * env,jclass,jobject tokenObj,jint colorMode)1535 static jboolean nativeSetActiveColorMode(JNIEnv* env, jclass,
1536         jobject tokenObj, jint colorMode) {
1537     sp<IBinder> token(ibinderForJavaObject(env, tokenObj));
1538     if (token == NULL) return JNI_FALSE;
1539     status_t err = SurfaceComposerClient::setActiveColorMode(token,
1540             static_cast<ui::ColorMode>(colorMode));
1541     return err == NO_ERROR ? JNI_TRUE : JNI_FALSE;
1542 }
1543 
nativeSetDisplayPowerMode(JNIEnv * env,jclass clazz,jobject tokenObj,jint mode)1544 static void nativeSetDisplayPowerMode(JNIEnv* env, jclass clazz, jobject tokenObj, jint mode) {
1545     sp<IBinder> token(ibinderForJavaObject(env, tokenObj));
1546     if (token == NULL) return;
1547 
1548     android::base::Timer t;
1549     SurfaceComposerClient::setDisplayPowerMode(token, mode);
1550     if (t.duration() > 100ms) ALOGD("Excessive delay in setPowerMode()");
1551 }
1552 
nativeGetProtectedContentSupport(JNIEnv * env,jclass)1553 static jboolean nativeGetProtectedContentSupport(JNIEnv* env, jclass) {
1554     return static_cast<jboolean>(SurfaceComposerClient::getProtectedContentSupport());
1555 }
1556 
nativeClearContentFrameStats(JNIEnv * env,jclass clazz,jlong nativeObject)1557 static jboolean nativeClearContentFrameStats(JNIEnv* env, jclass clazz, jlong nativeObject) {
1558     SurfaceControl* const ctrl = reinterpret_cast<SurfaceControl *>(nativeObject);
1559     status_t err = ctrl->clearLayerFrameStats();
1560 
1561     if (err < 0 && err != NO_INIT) {
1562         doThrowIAE(env);
1563     }
1564 
1565     // The other end is not ready, just report we failed.
1566     if (err == NO_INIT) {
1567         return JNI_FALSE;
1568     }
1569 
1570     return JNI_TRUE;
1571 }
1572 
nativeGetContentFrameStats(JNIEnv * env,jclass clazz,jlong nativeObject,jobject outStats)1573 static jboolean nativeGetContentFrameStats(JNIEnv* env, jclass clazz, jlong nativeObject,
1574     jobject outStats) {
1575     FrameStats stats;
1576 
1577     SurfaceControl* const ctrl = reinterpret_cast<SurfaceControl *>(nativeObject);
1578     status_t err = ctrl->getLayerFrameStats(&stats);
1579     if (err < 0 && err != NO_INIT) {
1580         doThrowIAE(env);
1581     }
1582 
1583     // The other end is not ready, fine just return empty stats.
1584     if (err == NO_INIT) {
1585         return JNI_FALSE;
1586     }
1587 
1588     jlong refreshPeriodNano = static_cast<jlong>(stats.refreshPeriodNano);
1589     size_t frameCount = stats.desiredPresentTimesNano.size();
1590 
1591     jlongArray postedTimesNanoDst = env->NewLongArray(frameCount);
1592     if (postedTimesNanoDst == NULL) {
1593         return JNI_FALSE;
1594     }
1595 
1596     jlongArray presentedTimesNanoDst = env->NewLongArray(frameCount);
1597     if (presentedTimesNanoDst == NULL) {
1598         return JNI_FALSE;
1599     }
1600 
1601     jlongArray readyTimesNanoDst = env->NewLongArray(frameCount);
1602     if (readyTimesNanoDst == NULL) {
1603         return JNI_FALSE;
1604     }
1605 
1606     nsecs_t postedTimesNanoSrc[frameCount];
1607     nsecs_t presentedTimesNanoSrc[frameCount];
1608     nsecs_t readyTimesNanoSrc[frameCount];
1609 
1610     for (size_t i = 0; i < frameCount; i++) {
1611         nsecs_t postedTimeNano = stats.desiredPresentTimesNano[i];
1612         if (postedTimeNano == INT64_MAX) {
1613             postedTimeNano = gWindowContentFrameStatsClassInfo.UNDEFINED_TIME_NANO;
1614         }
1615         postedTimesNanoSrc[i] = postedTimeNano;
1616 
1617         nsecs_t presentedTimeNano = stats.actualPresentTimesNano[i];
1618         if (presentedTimeNano == INT64_MAX) {
1619             presentedTimeNano = gWindowContentFrameStatsClassInfo.UNDEFINED_TIME_NANO;
1620         }
1621         presentedTimesNanoSrc[i] = presentedTimeNano;
1622 
1623         nsecs_t readyTimeNano = stats.frameReadyTimesNano[i];
1624         if (readyTimeNano == INT64_MAX) {
1625             readyTimeNano = gWindowContentFrameStatsClassInfo.UNDEFINED_TIME_NANO;
1626         }
1627         readyTimesNanoSrc[i] = readyTimeNano;
1628     }
1629 
1630     env->SetLongArrayRegion(postedTimesNanoDst, 0, frameCount, postedTimesNanoSrc);
1631     env->SetLongArrayRegion(presentedTimesNanoDst, 0, frameCount, presentedTimesNanoSrc);
1632     env->SetLongArrayRegion(readyTimesNanoDst, 0, frameCount, readyTimesNanoSrc);
1633 
1634     env->CallVoidMethod(outStats, gWindowContentFrameStatsClassInfo.init, refreshPeriodNano,
1635             postedTimesNanoDst, presentedTimesNanoDst, readyTimesNanoDst);
1636 
1637     if (env->ExceptionCheck()) {
1638         return JNI_FALSE;
1639     }
1640 
1641     return JNI_TRUE;
1642 }
1643 
nativeClearAnimationFrameStats(JNIEnv * env,jclass clazz)1644 static jboolean nativeClearAnimationFrameStats(JNIEnv* env, jclass clazz) {
1645     status_t err = SurfaceComposerClient::clearAnimationFrameStats();
1646 
1647     if (err < 0 && err != NO_INIT) {
1648         doThrowIAE(env);
1649     }
1650 
1651     // The other end is not ready, just report we failed.
1652     if (err == NO_INIT) {
1653         return JNI_FALSE;
1654     }
1655 
1656     return JNI_TRUE;
1657 }
1658 
nativeGetAnimationFrameStats(JNIEnv * env,jclass clazz,jobject outStats)1659 static jboolean nativeGetAnimationFrameStats(JNIEnv* env, jclass clazz, jobject outStats) {
1660     FrameStats stats;
1661 
1662     status_t err = SurfaceComposerClient::getAnimationFrameStats(&stats);
1663     if (err < 0 && err != NO_INIT) {
1664         doThrowIAE(env);
1665     }
1666 
1667     // The other end is not ready, fine just return empty stats.
1668     if (err == NO_INIT) {
1669         return JNI_FALSE;
1670     }
1671 
1672     jlong refreshPeriodNano = static_cast<jlong>(stats.refreshPeriodNano);
1673     size_t frameCount = stats.desiredPresentTimesNano.size();
1674 
1675     jlongArray presentedTimesNanoDst = env->NewLongArray(frameCount);
1676     if (presentedTimesNanoDst == NULL) {
1677         return JNI_FALSE;
1678     }
1679 
1680     nsecs_t presentedTimesNanoSrc[frameCount];
1681 
1682     for (size_t i = 0; i < frameCount; i++) {
1683         nsecs_t presentedTimeNano = stats.actualPresentTimesNano[i];
1684         if (presentedTimeNano == INT64_MAX) {
1685             presentedTimeNano = gWindowContentFrameStatsClassInfo.UNDEFINED_TIME_NANO;
1686         }
1687         presentedTimesNanoSrc[i] = presentedTimeNano;
1688     }
1689 
1690     env->SetLongArrayRegion(presentedTimesNanoDst, 0, frameCount, presentedTimesNanoSrc);
1691 
1692     env->CallVoidMethod(outStats, gWindowAnimationFrameStatsClassInfo.init, refreshPeriodNano,
1693             presentedTimesNanoDst);
1694 
1695     if (env->ExceptionCheck()) {
1696         return JNI_FALSE;
1697     }
1698 
1699     return JNI_TRUE;
1700 }
1701 
nativeReparent(JNIEnv * env,jclass clazz,jlong transactionObj,jlong nativeObject,jlong newParentObject)1702 static void nativeReparent(JNIEnv* env, jclass clazz, jlong transactionObj,
1703         jlong nativeObject,
1704         jlong newParentObject) {
1705     auto ctrl = reinterpret_cast<SurfaceControl *>(nativeObject);
1706     auto newParent = reinterpret_cast<SurfaceControl *>(newParentObject);
1707     auto transaction = reinterpret_cast<SurfaceComposerClient::Transaction*>(transactionObj);
1708     transaction->reparent(ctrl, newParent);
1709 }
1710 
nativeOverrideHdrTypes(JNIEnv * env,jclass clazz,jobject tokenObject,jintArray jHdrTypes)1711 static void nativeOverrideHdrTypes(JNIEnv* env, jclass clazz, jobject tokenObject,
1712                                    jintArray jHdrTypes) {
1713     sp<IBinder> token(ibinderForJavaObject(env, tokenObject));
1714     if (token == nullptr || jHdrTypes == nullptr) return;
1715 
1716     int* hdrTypes = env->GetIntArrayElements(jHdrTypes, 0);
1717     int numHdrTypes = env->GetArrayLength(jHdrTypes);
1718 
1719     std::vector<ui::Hdr> hdrTypesVector;
1720     for (int i = 0; i < numHdrTypes; i++) {
1721         hdrTypesVector.push_back(static_cast<ui::Hdr>(hdrTypes[i]));
1722     }
1723     env->ReleaseIntArrayElements(jHdrTypes, hdrTypes, 0);
1724 
1725     status_t error = SurfaceComposerClient::overrideHdrTypes(token, hdrTypesVector);
1726     if (error != NO_ERROR) {
1727         jniThrowExceptionFmt(env, "java/lang/SecurityException",
1728                              "ACCESS_SURFACE_FLINGER is missing");
1729     }
1730 }
1731 
nativeGetBootDisplayModeSupport(JNIEnv * env,jclass clazz)1732 static jboolean nativeGetBootDisplayModeSupport(JNIEnv* env, jclass clazz) {
1733     bool isBootDisplayModeSupported = false;
1734     SurfaceComposerClient::getBootDisplayModeSupport(&isBootDisplayModeSupported);
1735     return static_cast<jboolean>(isBootDisplayModeSupported);
1736 }
1737 
nativeSetBootDisplayMode(JNIEnv * env,jclass clazz,jobject tokenObject,jint displayModId)1738 static void nativeSetBootDisplayMode(JNIEnv* env, jclass clazz, jobject tokenObject,
1739                                      jint displayModId) {
1740     sp<IBinder> token(ibinderForJavaObject(env, tokenObject));
1741     if (token == NULL) return;
1742 
1743     SurfaceComposerClient::setBootDisplayMode(token, displayModId);
1744 }
1745 
nativeClearBootDisplayMode(JNIEnv * env,jclass clazz,jobject tokenObject)1746 static void nativeClearBootDisplayMode(JNIEnv* env, jclass clazz, jobject tokenObject) {
1747     sp<IBinder> token(ibinderForJavaObject(env, tokenObject));
1748     if (token == NULL) return;
1749 
1750     SurfaceComposerClient::clearBootDisplayMode(token);
1751 }
1752 
nativeSetAutoLowLatencyMode(JNIEnv * env,jclass clazz,jobject tokenObject,jboolean on)1753 static void nativeSetAutoLowLatencyMode(JNIEnv* env, jclass clazz, jobject tokenObject, jboolean on) {
1754     sp<IBinder> token(ibinderForJavaObject(env, tokenObject));
1755     if (token == NULL) return;
1756 
1757     SurfaceComposerClient::setAutoLowLatencyMode(token, on);
1758 }
1759 
nativeSetGameContentType(JNIEnv * env,jclass clazz,jobject tokenObject,jboolean on)1760 static void nativeSetGameContentType(JNIEnv* env, jclass clazz, jobject tokenObject, jboolean on) {
1761     sp<IBinder> token(ibinderForJavaObject(env, tokenObject));
1762     if (token == NULL) return;
1763 
1764     SurfaceComposerClient::setGameContentType(token, on);
1765 }
1766 
nativeReadFromParcel(JNIEnv * env,jclass clazz,jobject parcelObj)1767 static jlong nativeReadFromParcel(JNIEnv* env, jclass clazz, jobject parcelObj) {
1768     Parcel* parcel = parcelForJavaObject(env, parcelObj);
1769     if (parcel == NULL) {
1770         doThrowNPE(env);
1771         return 0;
1772     }
1773     sp<SurfaceControl> surface;
1774     SurfaceControl::readFromParcel(*parcel, &surface);
1775     if (surface == nullptr) {
1776         return 0;
1777     }
1778     surface->incStrong((void *)nativeCreate);
1779     return reinterpret_cast<jlong>(surface.get());
1780 }
1781 
nativeCopyFromSurfaceControl(JNIEnv * env,jclass clazz,jlong surfaceControlNativeObj)1782 static jlong nativeCopyFromSurfaceControl(JNIEnv* env, jclass clazz, jlong surfaceControlNativeObj) {
1783     sp<SurfaceControl> surface(reinterpret_cast<SurfaceControl *>(surfaceControlNativeObj));
1784     if (surface == nullptr) {
1785         return 0;
1786     }
1787 
1788     sp<SurfaceControl> newSurface = new SurfaceControl(surface);
1789     newSurface->incStrong((void *)nativeCreate);
1790     return reinterpret_cast<jlong>(newSurface.get());
1791 }
1792 
nativeWriteToParcel(JNIEnv * env,jclass clazz,jlong nativeObject,jobject parcelObj)1793 static void nativeWriteToParcel(JNIEnv* env, jclass clazz,
1794         jlong nativeObject, jobject parcelObj) {
1795     Parcel* parcel = parcelForJavaObject(env, parcelObj);
1796     if (parcel == NULL) {
1797         doThrowNPE(env);
1798         return;
1799     }
1800     SurfaceControl* const self = reinterpret_cast<SurfaceControl *>(nativeObject);
1801     if (self != nullptr) {
1802         self->writeToParcel(*parcel);
1803     }
1804 }
1805 
nativeGetDisplayBrightnessSupport(JNIEnv * env,jclass clazz,jobject displayTokenObject)1806 static jboolean nativeGetDisplayBrightnessSupport(JNIEnv* env, jclass clazz,
1807         jobject displayTokenObject) {
1808     sp<IBinder> displayToken(ibinderForJavaObject(env, displayTokenObject));
1809     if (displayToken == nullptr) {
1810         return JNI_FALSE;
1811     }
1812     return static_cast<jboolean>(SurfaceComposerClient::getDisplayBrightnessSupport(displayToken));
1813 }
1814 
nativeSetDisplayBrightness(JNIEnv * env,jclass clazz,jobject displayTokenObject,jfloat sdrBrightness,jfloat sdrBrightnessNits,jfloat displayBrightness,jfloat displayBrightnessNits)1815 static jboolean nativeSetDisplayBrightness(JNIEnv* env, jclass clazz, jobject displayTokenObject,
1816                                            jfloat sdrBrightness, jfloat sdrBrightnessNits,
1817                                            jfloat displayBrightness, jfloat displayBrightnessNits) {
1818     sp<IBinder> displayToken(ibinderForJavaObject(env, displayTokenObject));
1819     if (displayToken == nullptr) {
1820         return JNI_FALSE;
1821     }
1822     gui::DisplayBrightness brightness;
1823     brightness.sdrWhitePoint = sdrBrightness;
1824     brightness.sdrWhitePointNits = sdrBrightnessNits;
1825     brightness.displayBrightness = displayBrightness;
1826     brightness.displayBrightnessNits = displayBrightnessNits;
1827     status_t error = SurfaceComposerClient::setDisplayBrightness(displayToken, brightness);
1828     return error == OK ? JNI_TRUE : JNI_FALSE;
1829 }
1830 
nativeWriteTransactionToParcel(JNIEnv * env,jclass clazz,jlong nativeObject,jobject parcelObj)1831 static void nativeWriteTransactionToParcel(JNIEnv* env, jclass clazz, jlong nativeObject,
1832         jobject parcelObj) {
1833     Parcel* parcel = parcelForJavaObject(env, parcelObj);
1834     if (parcel == NULL) {
1835         doThrowNPE(env);
1836         return;
1837     }
1838     SurfaceComposerClient::Transaction* const self =
1839             reinterpret_cast<SurfaceComposerClient::Transaction *>(nativeObject);
1840     if (self != nullptr) {
1841         self->writeToParcel(parcel);
1842     }
1843 }
1844 
nativeClearTransaction(JNIEnv * env,jclass clazz,jlong nativeObject)1845 static void nativeClearTransaction(JNIEnv* env, jclass clazz, jlong nativeObject) {
1846     SurfaceComposerClient::Transaction* const self =
1847             reinterpret_cast<SurfaceComposerClient::Transaction*>(nativeObject);
1848     if (self != nullptr) {
1849         self->clear();
1850     }
1851 }
1852 
nativeReadTransactionFromParcel(JNIEnv * env,jclass clazz,jobject parcelObj)1853 static jlong nativeReadTransactionFromParcel(JNIEnv* env, jclass clazz, jobject parcelObj) {
1854     Parcel* parcel = parcelForJavaObject(env, parcelObj);
1855     if (parcel == NULL) {
1856         doThrowNPE(env);
1857         return 0;
1858     }
1859     std::unique_ptr<SurfaceComposerClient::Transaction> transaction =
1860             SurfaceComposerClient::Transaction::createFromParcel(parcel);
1861 
1862     return reinterpret_cast<jlong>(transaction.release());
1863 }
1864 
nativeMirrorSurface(JNIEnv * env,jclass clazz,jlong mirrorOfObj)1865 static jlong nativeMirrorSurface(JNIEnv* env, jclass clazz, jlong mirrorOfObj) {
1866     sp<SurfaceComposerClient> client = SurfaceComposerClient::getDefault();
1867     SurfaceControl *mirrorOf = reinterpret_cast<SurfaceControl*>(mirrorOfObj);
1868     sp<SurfaceControl> surface = client->mirrorSurface(mirrorOf);
1869 
1870     surface->incStrong((void *)nativeCreate);
1871     return reinterpret_cast<jlong>(surface.get());
1872 }
1873 
nativeSetGlobalShadowSettings(JNIEnv * env,jclass clazz,jfloatArray jAmbientColor,jfloatArray jSpotColor,jfloat lightPosY,jfloat lightPosZ,jfloat lightRadius)1874 static void nativeSetGlobalShadowSettings(JNIEnv* env, jclass clazz, jfloatArray jAmbientColor,
1875         jfloatArray jSpotColor, jfloat lightPosY, jfloat lightPosZ, jfloat lightRadius) {
1876     sp<SurfaceComposerClient> client = SurfaceComposerClient::getDefault();
1877 
1878     float* floatAmbientColor = env->GetFloatArrayElements(jAmbientColor, 0);
1879     half4 ambientColor = half4(floatAmbientColor[0], floatAmbientColor[1], floatAmbientColor[2],
1880             floatAmbientColor[3]);
1881     env->ReleaseFloatArrayElements(jAmbientColor, floatAmbientColor, 0);
1882 
1883     float* floatSpotColor = env->GetFloatArrayElements(jSpotColor, 0);
1884     half4 spotColor = half4(floatSpotColor[0], floatSpotColor[1], floatSpotColor[2],
1885             floatSpotColor[3]);
1886     env->ReleaseFloatArrayElements(jSpotColor, floatSpotColor, 0);
1887 
1888     client->setGlobalShadowSettings(ambientColor, spotColor, lightPosY, lightPosZ, lightRadius);
1889 }
1890 
nativeGetDisplayDecorationSupport(JNIEnv * env,jclass clazz,jobject displayTokenObject)1891 static jobject nativeGetDisplayDecorationSupport(JNIEnv* env, jclass clazz,
1892                                                  jobject displayTokenObject) {
1893     sp<IBinder> displayToken(ibinderForJavaObject(env, displayTokenObject));
1894     if (displayToken == nullptr) {
1895         return nullptr;
1896     }
1897     const auto support = SurfaceComposerClient::getDisplayDecorationSupport(displayToken);
1898     if (!support) {
1899         return nullptr;
1900     }
1901 
1902     using aidl::android::hardware::graphics::common::PixelFormat;
1903     if (support.value().format == PixelFormat::R_8 && !hwui_uses_vulkan()) {
1904         return nullptr;
1905     }
1906 
1907     jobject jDisplayDecorationSupport =
1908             env->NewObject(gDisplayDecorationSupportInfo.clazz, gDisplayDecorationSupportInfo.ctor);
1909     if (jDisplayDecorationSupport == nullptr) {
1910         jniThrowException(env, "java/lang/OutOfMemoryError", nullptr);
1911         return nullptr;
1912     }
1913 
1914     env->SetIntField(jDisplayDecorationSupport, gDisplayDecorationSupportInfo.format,
1915                      static_cast<jint>(support.value().format));
1916     env->SetIntField(jDisplayDecorationSupport, gDisplayDecorationSupportInfo.alphaInterpretation,
1917                      static_cast<jint>(support.value().alphaInterpretation));
1918     return jDisplayDecorationSupport;
1919 }
1920 
nativeGetHandle(JNIEnv * env,jclass clazz,jlong nativeObject)1921 static jlong nativeGetHandle(JNIEnv* env, jclass clazz, jlong nativeObject) {
1922     SurfaceControl *surfaceControl = reinterpret_cast<SurfaceControl*>(nativeObject);
1923     return reinterpret_cast<jlong>(surfaceControl->getHandle().get());
1924 }
1925 
nativeRemoveCurrentInputFocus(JNIEnv * env,jclass clazz,jlong transactionObj,jint displayId)1926 static void nativeRemoveCurrentInputFocus(JNIEnv* env, jclass clazz, jlong transactionObj,
1927                                           jint displayId) {
1928     auto transaction = reinterpret_cast<SurfaceComposerClient::Transaction*>(transactionObj);
1929     FocusRequest request;
1930     request.timestamp = systemTime(SYSTEM_TIME_MONOTONIC);
1931     request.displayId = displayId;
1932     request.windowName = "<null>";
1933     transaction->setFocusedWindow(request);
1934 }
1935 
nativeSetFocusedWindow(JNIEnv * env,jclass clazz,jlong transactionObj,jobject toTokenObj,jstring windowNameJstr,jobject focusedTokenObj,jstring focusedWindowNameJstr,jint displayId)1936 static void nativeSetFocusedWindow(JNIEnv* env, jclass clazz, jlong transactionObj,
1937                                    jobject toTokenObj, jstring windowNameJstr,
1938                                    jobject focusedTokenObj, jstring focusedWindowNameJstr,
1939                                    jint displayId) {
1940     auto transaction = reinterpret_cast<SurfaceComposerClient::Transaction*>(transactionObj);
1941     if (toTokenObj == NULL) return;
1942 
1943     sp<IBinder> toToken(ibinderForJavaObject(env, toTokenObj));
1944     sp<IBinder> focusedToken;
1945     if (focusedTokenObj != NULL) {
1946         focusedToken = ibinderForJavaObject(env, focusedTokenObj);
1947     }
1948 
1949     FocusRequest request;
1950     request.token = toToken;
1951     if (windowNameJstr != NULL) {
1952         ScopedUtfChars windowName(env, windowNameJstr);
1953         request.windowName = windowName.c_str();
1954     }
1955 
1956     request.focusedToken = focusedToken;
1957     if (focusedWindowNameJstr != NULL) {
1958         ScopedUtfChars focusedWindowName(env, focusedWindowNameJstr);
1959         request.focusedWindowName = focusedWindowName.c_str();
1960     }
1961     request.timestamp = systemTime(SYSTEM_TIME_MONOTONIC);
1962     request.displayId = displayId;
1963     transaction->setFocusedWindow(request);
1964 }
1965 
nativeSetFrameTimelineVsync(JNIEnv * env,jclass clazz,jlong transactionObj,jlong frameTimelineVsyncId)1966 static void nativeSetFrameTimelineVsync(JNIEnv* env, jclass clazz, jlong transactionObj,
1967                                         jlong frameTimelineVsyncId) {
1968     auto transaction = reinterpret_cast<SurfaceComposerClient::Transaction*>(transactionObj);
1969 
1970     transaction->setFrameTimelineInfo(
1971             {frameTimelineVsyncId, android::os::IInputConstants::INVALID_INPUT_EVENT_ID});
1972 }
1973 
nativeAddTransactionCommittedListener(JNIEnv * env,jclass clazz,jlong transactionObj,jobject transactionCommittedListenerObject)1974 static void nativeAddTransactionCommittedListener(JNIEnv* env, jclass clazz, jlong transactionObj,
1975                                                   jobject transactionCommittedListenerObject) {
1976     auto transaction = reinterpret_cast<SurfaceComposerClient::Transaction*>(transactionObj);
1977 
1978     void* context =
1979             new TransactionCommittedListenerWrapper(env, transactionCommittedListenerObject);
1980     transaction->addTransactionCommittedCallback(TransactionCommittedListenerWrapper::
1981                                                          transactionCallbackThunk,
1982                                                  context);
1983 }
1984 
1985 class JankDataListenerWrapper : public JankDataListener {
1986 public:
JankDataListenerWrapper(JNIEnv * env,jobject onJankDataListenerObject)1987     JankDataListenerWrapper(JNIEnv* env, jobject onJankDataListenerObject) {
1988         mOnJankDataListenerWeak = env->NewWeakGlobalRef(onJankDataListenerObject);
1989         env->GetJavaVM(&mVm);
1990     }
1991 
~JankDataListenerWrapper()1992     ~JankDataListenerWrapper() {
1993         JNIEnv* env = getEnv();
1994         env->DeleteWeakGlobalRef(mOnJankDataListenerWeak);
1995     }
1996 
onJankDataAvailable(const std::vector<JankData> & jankData)1997     void onJankDataAvailable(const std::vector<JankData>& jankData) {
1998         JNIEnv* env = getEnv();
1999 
2000         jobject target = env->NewLocalRef(mOnJankDataListenerWeak);
2001         if (target == nullptr) return;
2002 
2003         jobjectArray jJankDataArray = env->NewObjectArray(jankData.size(),
2004                 gJankDataClassInfo.clazz, nullptr);
2005         for (int i = 0; i < jankData.size(); i++) {
2006             jobject jJankData = env->NewObject(gJankDataClassInfo.clazz,
2007                     gJankDataClassInfo.ctor, jankData[i].frameVsyncId, jankData[i].jankType);
2008             env->SetObjectArrayElement(jJankDataArray, i, jJankData);
2009             env->DeleteLocalRef(jJankData);
2010         }
2011         env->CallVoidMethod(target,
2012                 gJankDataListenerClassInfo.onJankDataAvailable,
2013                 jJankDataArray);
2014         env->DeleteLocalRef(jJankDataArray);
2015         env->DeleteLocalRef(target);
2016     }
2017 
2018 private:
2019 
getEnv()2020     JNIEnv* getEnv() {
2021         JNIEnv* env;
2022         mVm->GetEnv(reinterpret_cast<void**>(&env), JNI_VERSION_1_6);
2023         return env;
2024     }
2025 
2026     JavaVM* mVm;
2027     jobject mOnJankDataListenerWeak;
2028 };
2029 
nativeAddJankDataListener(JNIEnv * env,jclass clazz,jlong jankDataCallbackListenerPtr,jlong nativeSurfaceControl)2030 static void nativeAddJankDataListener(JNIEnv* env, jclass clazz,
2031                                        jlong jankDataCallbackListenerPtr,
2032                                        jlong nativeSurfaceControl) {
2033     sp<SurfaceControl> surface(reinterpret_cast<SurfaceControl *>(nativeSurfaceControl));
2034     if (surface == nullptr) {
2035         return;
2036     }
2037     sp<JankDataListenerWrapper> wrapper =
2038             reinterpret_cast<JankDataListenerWrapper*>(jankDataCallbackListenerPtr);
2039     TransactionCompletedListener::getInstance()->addJankListener(wrapper, surface);
2040 }
2041 
nativeRemoveJankDataListener(JNIEnv * env,jclass clazz,jlong jankDataCallbackListenerPtr)2042 static void nativeRemoveJankDataListener(JNIEnv* env, jclass clazz,
2043                                           jlong jankDataCallbackListenerPtr) {
2044     sp<JankDataListenerWrapper> wrapper =
2045             reinterpret_cast<JankDataListenerWrapper*>(jankDataCallbackListenerPtr);
2046     TransactionCompletedListener::getInstance()->removeJankListener(wrapper);
2047 }
2048 
nativeCreateJankDataListenerWrapper(JNIEnv * env,jclass clazz,jobject jankDataListenerObject)2049 static jlong nativeCreateJankDataListenerWrapper(JNIEnv* env, jclass clazz,
2050                                                  jobject jankDataListenerObject) {
2051     return reinterpret_cast<jlong>(
2052             new JankDataListenerWrapper(env, jankDataListenerObject));
2053 }
2054 
nativeGetGPUContextPriority(JNIEnv * env,jclass clazz)2055 static jint nativeGetGPUContextPriority(JNIEnv* env, jclass clazz) {
2056     return static_cast<jint>(SurfaceComposerClient::getGPUContextPriority());
2057 }
2058 
nativeSetTransformHint(JNIEnv * env,jclass clazz,jlong nativeSurfaceControl,jint transformHint)2059 static void nativeSetTransformHint(JNIEnv* env, jclass clazz, jlong nativeSurfaceControl,
2060                                    jint transformHint) {
2061     sp<SurfaceControl> surface(reinterpret_cast<SurfaceControl*>(nativeSurfaceControl));
2062     if (surface == nullptr) {
2063         return;
2064     }
2065     surface->setTransformHint(transformHint);
2066 }
2067 
nativeGetTransformHint(JNIEnv * env,jclass clazz,jlong nativeSurfaceControl)2068 static jint nativeGetTransformHint(JNIEnv* env, jclass clazz, jlong nativeSurfaceControl) {
2069     sp<SurfaceControl> surface(reinterpret_cast<SurfaceControl*>(nativeSurfaceControl));
2070     return surface->getTransformHint();
2071 }
2072 
nativeGetLayerId(JNIEnv * env,jclass clazz,jlong nativeSurfaceControl)2073 static jint nativeGetLayerId(JNIEnv* env, jclass clazz, jlong nativeSurfaceControl) {
2074     sp<SurfaceControl> surface(reinterpret_cast<SurfaceControl*>(nativeSurfaceControl));
2075 
2076     return surface->getLayerId();
2077 }
2078 
2079 // ----------------------------------------------------------------------------
2080 
2081 static const JNINativeMethod sSurfaceControlMethods[] = {
2082         // clang-format off
2083     {"nativeCreate", "(Landroid/view/SurfaceSession;Ljava/lang/String;IIIIJLandroid/os/Parcel;)J",
2084             (void*)nativeCreate },
2085     {"nativeReadFromParcel", "(Landroid/os/Parcel;)J",
2086             (void*)nativeReadFromParcel },
2087     {"nativeCopyFromSurfaceControl", "(J)J" ,
2088             (void*)nativeCopyFromSurfaceControl },
2089     {"nativeWriteToParcel", "(JLandroid/os/Parcel;)V",
2090             (void*)nativeWriteToParcel },
2091     {"nativeRelease", "(J)V",
2092             (void*)nativeRelease },
2093     {"nativeDisconnect", "(J)V",
2094             (void*)nativeDisconnect },
2095     {"nativeUpdateDefaultBufferSize", "(JII)V",
2096             (void*)nativeSetDefaultBufferSize},
2097     {"nativeCreateTransaction", "()J",
2098             (void*)nativeCreateTransaction },
2099     {"nativeApplyTransaction", "(JZ)V",
2100             (void*)nativeApplyTransaction },
2101     {"nativeGetNativeTransactionFinalizer", "()J",
2102             (void*)nativeGetNativeTransactionFinalizer },
2103     {"nativeMergeTransaction", "(JJ)V",
2104             (void*)nativeMergeTransaction },
2105     {"nativeSetAnimationTransaction", "(J)V",
2106             (void*)nativeSetAnimationTransaction },
2107     {"nativeSetEarlyWakeupStart", "(J)V",
2108             (void*)nativeSetEarlyWakeupStart },
2109     {"nativeSetEarlyWakeupEnd", "(J)V",
2110             (void*)nativeSetEarlyWakeupEnd },
2111     {"nativeGetTransactionId", "(J)J",
2112                 (void*)nativeGetTransactionId },
2113     {"nativeSetLayer", "(JJI)V",
2114             (void*)nativeSetLayer },
2115     {"nativeSetRelativeLayer", "(JJJI)V",
2116             (void*)nativeSetRelativeLayer },
2117     {"nativeSetPosition", "(JJFF)V",
2118             (void*)nativeSetPosition },
2119     {"nativeSetScale", "(JJFF)V",
2120             (void*)nativeSetScale },
2121     {"nativeSetSize", "(JJII)V",
2122             (void*)nativeSetSize },
2123     {"nativeSetTransparentRegionHint", "(JJLandroid/graphics/Region;)V",
2124             (void*)nativeSetTransparentRegionHint },
2125     {"nativeSetDamageRegion", "(JJLandroid/graphics/Region;)V",
2126             (void*)nativeSetDamageRegion },
2127     {"nativeSetDimmingEnabled", "(JJZ)V", (void*)nativeSetDimmingEnabled },
2128     {"nativeSetAlpha", "(JJF)V",
2129             (void*)nativeSetAlpha },
2130     {"nativeSetColor", "(JJ[F)V",
2131             (void*)nativeSetColor },
2132     {"nativeSetMatrix", "(JJFFFF)V",
2133             (void*)nativeSetMatrix },
2134     {"nativeSetColorTransform", "(JJ[F[F)V",
2135             (void*)nativeSetColorTransform },
2136     {"nativeSetColorSpaceAgnostic", "(JJZ)V",
2137             (void*)nativeSetColorSpaceAgnostic },
2138     {"nativeSetFlags", "(JJII)V",
2139             (void*)nativeSetFlags },
2140     {"nativeSetFrameRateSelectionPriority", "(JJI)V",
2141             (void*)nativeSetFrameRateSelectionPriority },
2142     {"nativeSetWindowCrop", "(JJIIII)V",
2143             (void*)nativeSetWindowCrop },
2144     {"nativeSetCornerRadius", "(JJF)V",
2145             (void*)nativeSetCornerRadius },
2146     {"nativeSetBackgroundBlurRadius", "(JJI)V",
2147             (void*)nativeSetBackgroundBlurRadius },
2148     {"nativeSetLayerStack", "(JJI)V",
2149             (void*)nativeSetLayerStack },
2150     {"nativeSetBlurRegions", "(JJ[[FI)V",
2151             (void*)nativeSetBlurRegions },
2152     {"nativeSetStretchEffect", "(JJFFFFFFFFFF)V",
2153             (void*) nativeSetStretchEffect },
2154     {"nativeSetShadowRadius", "(JJF)V",
2155             (void*)nativeSetShadowRadius },
2156     {"nativeSetFrameRate", "(JJFII)V",
2157             (void*)nativeSetFrameRate },
2158     {"nativeGetPhysicalDisplayIds", "()[J",
2159             (void*)nativeGetPhysicalDisplayIds },
2160     {"nativeGetPrimaryPhysicalDisplayId", "()J",
2161             (void*)nativeGetPrimaryPhysicalDisplayId },
2162     {"nativeGetPhysicalDisplayToken", "(J)Landroid/os/IBinder;",
2163             (void*)nativeGetPhysicalDisplayToken },
2164     {"nativeCreateDisplay", "(Ljava/lang/String;Z)Landroid/os/IBinder;",
2165             (void*)nativeCreateDisplay },
2166     {"nativeDestroyDisplay", "(Landroid/os/IBinder;)V",
2167             (void*)nativeDestroyDisplay },
2168     {"nativeSetDisplaySurface", "(JLandroid/os/IBinder;J)V",
2169             (void*)nativeSetDisplaySurface },
2170     {"nativeSetDisplayLayerStack", "(JLandroid/os/IBinder;I)V",
2171             (void*)nativeSetDisplayLayerStack },
2172     {"nativeSetDisplayFlags", "(JLandroid/os/IBinder;I)V",
2173             (void*)nativeSetDisplayFlags },
2174     {"nativeSetDisplayProjection", "(JLandroid/os/IBinder;IIIIIIIII)V",
2175             (void*)nativeSetDisplayProjection },
2176     {"nativeSetDisplaySize", "(JLandroid/os/IBinder;II)V",
2177             (void*)nativeSetDisplaySize },
2178     {"nativeGetStaticDisplayInfo",
2179             "(Landroid/os/IBinder;)Landroid/view/SurfaceControl$StaticDisplayInfo;",
2180             (void*)nativeGetStaticDisplayInfo },
2181     {"nativeGetDynamicDisplayInfo",
2182             "(Landroid/os/IBinder;)Landroid/view/SurfaceControl$DynamicDisplayInfo;",
2183             (void*)nativeGetDynamicDisplayInfo },
2184     {"nativeSetDesiredDisplayModeSpecs",
2185             "(Landroid/os/IBinder;Landroid/view/SurfaceControl$DesiredDisplayModeSpecs;)Z",
2186             (void*)nativeSetDesiredDisplayModeSpecs },
2187     {"nativeGetDesiredDisplayModeSpecs",
2188             "(Landroid/os/IBinder;)Landroid/view/SurfaceControl$DesiredDisplayModeSpecs;",
2189             (void*)nativeGetDesiredDisplayModeSpecs },
2190     {"nativeGetDisplayNativePrimaries",
2191             "(Landroid/os/IBinder;)Landroid/view/SurfaceControl$DisplayPrimaries;",
2192             (void*)nativeGetDisplayNativePrimaries },
2193     {"nativeSetActiveColorMode", "(Landroid/os/IBinder;I)Z",
2194             (void*)nativeSetActiveColorMode},
2195      {"nativeGetBootDisplayModeSupport", "()Z",
2196                 (void*)nativeGetBootDisplayModeSupport },
2197     {"nativeSetBootDisplayMode", "(Landroid/os/IBinder;I)V",
2198             (void*)nativeSetBootDisplayMode },
2199     {"nativeClearBootDisplayMode", "(Landroid/os/IBinder;)V",
2200             (void*)nativeClearBootDisplayMode },
2201     {"nativeSetAutoLowLatencyMode", "(Landroid/os/IBinder;Z)V",
2202             (void*)nativeSetAutoLowLatencyMode },
2203     {"nativeSetGameContentType", "(Landroid/os/IBinder;Z)V",
2204             (void*)nativeSetGameContentType },
2205     {"nativeGetCompositionDataspaces", "()[I",
2206             (void*)nativeGetCompositionDataspaces},
2207     {"nativeOverrideHdrTypes", "(Landroid/os/IBinder;[I)V",
2208                 (void*)nativeOverrideHdrTypes },
2209     {"nativeClearContentFrameStats", "(J)Z",
2210             (void*)nativeClearContentFrameStats },
2211     {"nativeGetContentFrameStats", "(JLandroid/view/WindowContentFrameStats;)Z",
2212             (void*)nativeGetContentFrameStats },
2213     {"nativeClearAnimationFrameStats", "()Z",
2214             (void*)nativeClearAnimationFrameStats },
2215     {"nativeGetAnimationFrameStats", "(Landroid/view/WindowAnimationFrameStats;)Z",
2216             (void*)nativeGetAnimationFrameStats },
2217     {"nativeSetDisplayPowerMode", "(Landroid/os/IBinder;I)V",
2218             (void*)nativeSetDisplayPowerMode },
2219     {"nativeGetProtectedContentSupport", "()Z",
2220             (void*)nativeGetProtectedContentSupport },
2221     {"nativeReparent", "(JJJ)V",
2222             (void*)nativeReparent },
2223     {"nativeCaptureDisplay",
2224             "(Landroid/view/SurfaceControl$DisplayCaptureArgs;Landroid/view/SurfaceControl$ScreenCaptureListener;)I",
2225             (void*)nativeCaptureDisplay },
2226     {"nativeCaptureLayers",
2227             "(Landroid/view/SurfaceControl$LayerCaptureArgs;Landroid/view/SurfaceControl$ScreenCaptureListener;)I",
2228             (void*)nativeCaptureLayers },
2229     {"nativeSetInputWindowInfo", "(JJLandroid/view/InputWindowHandle;)V",
2230             (void*)nativeSetInputWindowInfo },
2231     {"nativeSetMetadata", "(JJILandroid/os/Parcel;)V",
2232             (void*)nativeSetMetadata },
2233     {"nativeGetDisplayedContentSamplingAttributes",
2234             "(Landroid/os/IBinder;)Landroid/hardware/display/DisplayedContentSamplingAttributes;",
2235             (void*)nativeGetDisplayedContentSamplingAttributes },
2236     {"nativeSetDisplayedContentSamplingEnabled", "(Landroid/os/IBinder;ZII)Z",
2237             (void*)nativeSetDisplayedContentSamplingEnabled },
2238     {"nativeGetDisplayedContentSample",
2239             "(Landroid/os/IBinder;JJ)Landroid/hardware/display/DisplayedContentSample;",
2240             (void*)nativeGetDisplayedContentSample },
2241     {"nativeSetGeometry", "(JJLandroid/graphics/Rect;Landroid/graphics/Rect;J)V",
2242             (void*)nativeSetGeometry },
2243     {"nativeSetBuffer", "(JJLandroid/hardware/HardwareBuffer;JLjava/util/function/Consumer;)V",
2244             (void*)nativeSetBuffer },
2245     {"nativeSetBufferTransform", "(JJI)V", (void*) nativeSetBufferTransform},
2246     {"nativeSetDataSpace", "(JJI)V",
2247             (void*)nativeSetDataSpace },
2248     {"nativeSyncInputWindows", "(J)V",
2249             (void*)nativeSyncInputWindows },
2250     {"nativeGetDisplayBrightnessSupport", "(Landroid/os/IBinder;)Z",
2251             (void*)nativeGetDisplayBrightnessSupport },
2252     {"nativeSetDisplayBrightness", "(Landroid/os/IBinder;FFFF)Z",
2253             (void*)nativeSetDisplayBrightness },
2254     {"nativeReadTransactionFromParcel", "(Landroid/os/Parcel;)J",
2255             (void*)nativeReadTransactionFromParcel },
2256     {"nativeWriteTransactionToParcel", "(JLandroid/os/Parcel;)V",
2257             (void*)nativeWriteTransactionToParcel },
2258     {"nativeClearTransaction", "(J)V",
2259             (void*)nativeClearTransaction },
2260     {"nativeMirrorSurface", "(J)J",
2261             (void*)nativeMirrorSurface },
2262     {"nativeSetGlobalShadowSettings", "([F[FFFF)V",
2263             (void*)nativeSetGlobalShadowSettings },
2264     {"nativeGetDisplayDecorationSupport",
2265             "(Landroid/os/IBinder;)Landroid/hardware/graphics/common/DisplayDecorationSupport;",
2266             (void*)nativeGetDisplayDecorationSupport},
2267     {"nativeGetHandle", "(J)J",
2268             (void*)nativeGetHandle },
2269     {"nativeSetFixedTransformHint", "(JJI)V",
2270             (void*)nativeSetFixedTransformHint},
2271     {"nativeSetFocusedWindow", "(JLandroid/os/IBinder;Ljava/lang/String;Landroid/os/IBinder;Ljava/lang/String;I)V",
2272             (void*)nativeSetFocusedWindow},
2273     {"nativeRemoveCurrentInputFocus", "(JI)V",
2274             (void*)nativeRemoveCurrentInputFocus},
2275     {"nativeSetFrameTimelineVsync", "(JJ)V",
2276             (void*)nativeSetFrameTimelineVsync },
2277     {"nativeAddJankDataListener", "(JJ)V",
2278             (void*)nativeAddJankDataListener },
2279     {"nativeRemoveJankDataListener", "(J)V",
2280             (void*)nativeRemoveJankDataListener },
2281     {"nativeCreateJankDataListenerWrapper", "(Landroid/view/SurfaceControl$OnJankDataListener;)J",
2282             (void*)nativeCreateJankDataListenerWrapper },
2283     {"nativeGetGPUContextPriority", "()I",
2284             (void*)nativeGetGPUContextPriority },
2285     {"nativeSetTransformHint", "(JI)V",
2286             (void*)nativeSetTransformHint },
2287     {"nativeGetTransformHint", "(J)I",
2288             (void*)nativeGetTransformHint },
2289     {"nativeSetTrustedOverlay", "(JJZ)V",
2290             (void*)nativeSetTrustedOverlay },
2291     {"nativeGetLayerId", "(J)I",
2292             (void*)nativeGetLayerId },
2293     {"nativeSetDropInputMode", "(JJI)V",
2294              (void*)nativeSetDropInputMode },
2295     {"nativeAddTransactionCommittedListener", "(JLandroid/view/SurfaceControl$TransactionCommittedListener;)V",
2296             (void*) nativeAddTransactionCommittedListener },
2297     {"nativeSanitize", "(J)V",
2298             (void*) nativeSanitize },
2299     {"nativeSetDestinationFrame", "(JJIIII)V",
2300                 (void*)nativeSetDestinationFrame },
2301         // clang-format on
2302 };
2303 
register_android_view_SurfaceControl(JNIEnv * env)2304 int register_android_view_SurfaceControl(JNIEnv* env)
2305 {
2306     int err = RegisterMethodsOrDie(env, "android/view/SurfaceControl",
2307             sSurfaceControlMethods, NELEM(sSurfaceControlMethods));
2308 
2309     jclass integerClass = FindClassOrDie(env, "java/lang/Integer");
2310     gIntegerClassInfo.clazz = MakeGlobalRefOrDie(env, integerClass);
2311     gIntegerClassInfo.ctor = GetMethodIDOrDie(env, gIntegerClassInfo.clazz, "<init>", "(I)V");
2312 
2313     jclass infoClazz = FindClassOrDie(env, "android/view/SurfaceControl$StaticDisplayInfo");
2314     gStaticDisplayInfoClassInfo.clazz = MakeGlobalRefOrDie(env, infoClazz);
2315     gStaticDisplayInfoClassInfo.ctor = GetMethodIDOrDie(env, infoClazz, "<init>", "()V");
2316     gStaticDisplayInfoClassInfo.isInternal = GetFieldIDOrDie(env, infoClazz, "isInternal", "Z");
2317     gStaticDisplayInfoClassInfo.density = GetFieldIDOrDie(env, infoClazz, "density", "F");
2318     gStaticDisplayInfoClassInfo.secure = GetFieldIDOrDie(env, infoClazz, "secure", "Z");
2319     gStaticDisplayInfoClassInfo.deviceProductInfo =
2320             GetFieldIDOrDie(env, infoClazz, "deviceProductInfo",
2321                             "Landroid/hardware/display/DeviceProductInfo;");
2322     gStaticDisplayInfoClassInfo.installOrientation =
2323             GetFieldIDOrDie(env, infoClazz, "installOrientation", "I");
2324 
2325     jclass dynamicInfoClazz = FindClassOrDie(env, "android/view/SurfaceControl$DynamicDisplayInfo");
2326     gDynamicDisplayInfoClassInfo.clazz = MakeGlobalRefOrDie(env, dynamicInfoClazz);
2327     gDynamicDisplayInfoClassInfo.ctor = GetMethodIDOrDie(env, dynamicInfoClazz, "<init>", "()V");
2328     gDynamicDisplayInfoClassInfo.supportedDisplayModes =
2329             GetFieldIDOrDie(env, dynamicInfoClazz, "supportedDisplayModes",
2330                             "[Landroid/view/SurfaceControl$DisplayMode;");
2331     gDynamicDisplayInfoClassInfo.activeDisplayModeId =
2332             GetFieldIDOrDie(env, dynamicInfoClazz, "activeDisplayModeId", "I");
2333     gDynamicDisplayInfoClassInfo.supportedColorModes =
2334             GetFieldIDOrDie(env, dynamicInfoClazz, "supportedColorModes", "[I");
2335     gDynamicDisplayInfoClassInfo.activeColorMode =
2336             GetFieldIDOrDie(env, dynamicInfoClazz, "activeColorMode", "I");
2337     gDynamicDisplayInfoClassInfo.hdrCapabilities =
2338             GetFieldIDOrDie(env, dynamicInfoClazz, "hdrCapabilities",
2339                             "Landroid/view/Display$HdrCapabilities;");
2340     gDynamicDisplayInfoClassInfo.autoLowLatencyModeSupported =
2341             GetFieldIDOrDie(env, dynamicInfoClazz, "autoLowLatencyModeSupported", "Z");
2342     gDynamicDisplayInfoClassInfo.gameContentTypeSupported =
2343             GetFieldIDOrDie(env, dynamicInfoClazz, "gameContentTypeSupported", "Z");
2344     gDynamicDisplayInfoClassInfo.preferredBootDisplayMode =
2345             GetFieldIDOrDie(env, dynamicInfoClazz, "preferredBootDisplayMode", "I");
2346 
2347     jclass modeClazz = FindClassOrDie(env, "android/view/SurfaceControl$DisplayMode");
2348     gDisplayModeClassInfo.clazz = MakeGlobalRefOrDie(env, modeClazz);
2349     gDisplayModeClassInfo.ctor = GetMethodIDOrDie(env, modeClazz, "<init>", "()V");
2350     gDisplayModeClassInfo.id = GetFieldIDOrDie(env, modeClazz, "id", "I");
2351     gDisplayModeClassInfo.width = GetFieldIDOrDie(env, modeClazz, "width", "I");
2352     gDisplayModeClassInfo.height = GetFieldIDOrDie(env, modeClazz, "height", "I");
2353     gDisplayModeClassInfo.xDpi = GetFieldIDOrDie(env, modeClazz, "xDpi", "F");
2354     gDisplayModeClassInfo.yDpi = GetFieldIDOrDie(env, modeClazz, "yDpi", "F");
2355     gDisplayModeClassInfo.refreshRate = GetFieldIDOrDie(env, modeClazz, "refreshRate", "F");
2356     gDisplayModeClassInfo.appVsyncOffsetNanos =
2357             GetFieldIDOrDie(env, modeClazz, "appVsyncOffsetNanos", "J");
2358     gDisplayModeClassInfo.presentationDeadlineNanos =
2359             GetFieldIDOrDie(env, modeClazz, "presentationDeadlineNanos", "J");
2360     gDisplayModeClassInfo.group = GetFieldIDOrDie(env, modeClazz, "group", "I");
2361 
2362     jclass rectClazz = FindClassOrDie(env, "android/graphics/Rect");
2363     gRectClassInfo.bottom = GetFieldIDOrDie(env, rectClazz, "bottom", "I");
2364     gRectClassInfo.left =   GetFieldIDOrDie(env, rectClazz, "left", "I");
2365     gRectClassInfo.right =  GetFieldIDOrDie(env, rectClazz, "right", "I");
2366     gRectClassInfo.top =    GetFieldIDOrDie(env, rectClazz, "top", "I");
2367 
2368     jclass frameStatsClazz = FindClassOrDie(env, "android/view/FrameStats");
2369     jfieldID undefined_time_nano_field = GetStaticFieldIDOrDie(env,
2370             frameStatsClazz, "UNDEFINED_TIME_NANO", "J");
2371     nsecs_t undefined_time_nano = env->GetStaticLongField(frameStatsClazz, undefined_time_nano_field);
2372 
2373     jclass contFrameStatsClazz = FindClassOrDie(env, "android/view/WindowContentFrameStats");
2374     gWindowContentFrameStatsClassInfo.init = GetMethodIDOrDie(env,
2375             contFrameStatsClazz, "init", "(J[J[J[J)V");
2376     gWindowContentFrameStatsClassInfo.UNDEFINED_TIME_NANO = undefined_time_nano;
2377 
2378     jclass animFrameStatsClazz = FindClassOrDie(env, "android/view/WindowAnimationFrameStats");
2379     gWindowAnimationFrameStatsClassInfo.init =  GetMethodIDOrDie(env,
2380             animFrameStatsClazz, "init", "(J[J)V");
2381     gWindowAnimationFrameStatsClassInfo.UNDEFINED_TIME_NANO = undefined_time_nano;
2382 
2383     jclass hdrCapabilitiesClazz = FindClassOrDie(env, "android/view/Display$HdrCapabilities");
2384     gHdrCapabilitiesClassInfo.clazz = MakeGlobalRefOrDie(env, hdrCapabilitiesClazz);
2385     gHdrCapabilitiesClassInfo.ctor = GetMethodIDOrDie(env, hdrCapabilitiesClazz, "<init>",
2386             "([IFFF)V");
2387 
2388     jclass deviceProductInfoClazz =
2389             FindClassOrDie(env, "android/hardware/display/DeviceProductInfo");
2390     gDeviceProductInfoClassInfo.clazz = MakeGlobalRefOrDie(env, deviceProductInfoClazz);
2391     gDeviceProductInfoClassInfo.ctor =
2392             GetMethodIDOrDie(env, deviceProductInfoClazz, "<init>",
2393                              "(Ljava/lang/String;"
2394                              "Ljava/lang/String;"
2395                              "Ljava/lang/String;"
2396                              "Ljava/lang/Integer;"
2397                              "Landroid/hardware/display/DeviceProductInfo$ManufactureDate;"
2398                              "I)V");
2399 
2400     jclass deviceProductInfoManufactureDateClazz =
2401             FindClassOrDie(env, "android/hardware/display/DeviceProductInfo$ManufactureDate");
2402     gDeviceProductInfoManufactureDateClassInfo.clazz =
2403             MakeGlobalRefOrDie(env, deviceProductInfoManufactureDateClazz);
2404     gDeviceProductInfoManufactureDateClassInfo.ctor =
2405             GetMethodIDOrDie(env, deviceProductInfoManufactureDateClazz, "<init>",
2406                              "(Ljava/lang/Integer;Ljava/lang/Integer;)V");
2407 
2408     jclass screenshotGraphicsBufferClazz =
2409             FindClassOrDie(env, "android/view/SurfaceControl$ScreenshotHardwareBuffer");
2410     gScreenshotHardwareBufferClassInfo.clazz =
2411             MakeGlobalRefOrDie(env, screenshotGraphicsBufferClazz);
2412     gScreenshotHardwareBufferClassInfo.builder =
2413             GetStaticMethodIDOrDie(env, screenshotGraphicsBufferClazz, "createFromNative",
2414                                    "(Landroid/hardware/HardwareBuffer;IZZ)Landroid/view/"
2415                                    "SurfaceControl$ScreenshotHardwareBuffer;");
2416 
2417     jclass displayedContentSampleClazz = FindClassOrDie(env,
2418             "android/hardware/display/DisplayedContentSample");
2419     gDisplayedContentSampleClassInfo.clazz = MakeGlobalRefOrDie(env, displayedContentSampleClazz);
2420     gDisplayedContentSampleClassInfo.ctor = GetMethodIDOrDie(env,
2421             displayedContentSampleClazz, "<init>", "(J[J[J[J[J)V");
2422 
2423     jclass displayedContentSamplingAttributesClazz = FindClassOrDie(env,
2424             "android/hardware/display/DisplayedContentSamplingAttributes");
2425     gDisplayedContentSamplingAttributesClassInfo.clazz = MakeGlobalRefOrDie(env,
2426             displayedContentSamplingAttributesClazz);
2427     gDisplayedContentSamplingAttributesClassInfo.ctor = GetMethodIDOrDie(env,
2428             displayedContentSamplingAttributesClazz, "<init>", "(III)V");
2429 
2430     jclass cieXyzClazz = FindClassOrDie(env, "android/view/SurfaceControl$CieXyz");
2431     gCieXyzClassInfo.clazz = MakeGlobalRefOrDie(env, cieXyzClazz);
2432     gCieXyzClassInfo.ctor = GetMethodIDOrDie(env, gCieXyzClassInfo.clazz, "<init>", "()V");
2433     gCieXyzClassInfo.X = GetFieldIDOrDie(env, cieXyzClazz, "X", "F");
2434     gCieXyzClassInfo.Y = GetFieldIDOrDie(env, cieXyzClazz, "Y", "F");
2435     gCieXyzClassInfo.Z = GetFieldIDOrDie(env, cieXyzClazz, "Z", "F");
2436 
2437     jclass displayPrimariesClazz = FindClassOrDie(env,
2438             "android/view/SurfaceControl$DisplayPrimaries");
2439     gDisplayPrimariesClassInfo.clazz = MakeGlobalRefOrDie(env, displayPrimariesClazz);
2440     gDisplayPrimariesClassInfo.ctor = GetMethodIDOrDie(env, gDisplayPrimariesClassInfo.clazz,
2441             "<init>", "()V");
2442     gDisplayPrimariesClassInfo.red = GetFieldIDOrDie(env, displayPrimariesClazz, "red",
2443             "Landroid/view/SurfaceControl$CieXyz;");
2444     gDisplayPrimariesClassInfo.green = GetFieldIDOrDie(env, displayPrimariesClazz, "green",
2445             "Landroid/view/SurfaceControl$CieXyz;");
2446     gDisplayPrimariesClassInfo.blue = GetFieldIDOrDie(env, displayPrimariesClazz, "blue",
2447             "Landroid/view/SurfaceControl$CieXyz;");
2448     gDisplayPrimariesClassInfo.white = GetFieldIDOrDie(env, displayPrimariesClazz, "white",
2449             "Landroid/view/SurfaceControl$CieXyz;");
2450 
2451     jclass DesiredDisplayModeSpecsClazz =
2452             FindClassOrDie(env, "android/view/SurfaceControl$DesiredDisplayModeSpecs");
2453     gDesiredDisplayModeSpecsClassInfo.clazz = MakeGlobalRefOrDie(env, DesiredDisplayModeSpecsClazz);
2454     gDesiredDisplayModeSpecsClassInfo.ctor =
2455             GetMethodIDOrDie(env, gDesiredDisplayModeSpecsClassInfo.clazz, "<init>", "(IZFFFF)V");
2456     gDesiredDisplayModeSpecsClassInfo.defaultMode =
2457             GetFieldIDOrDie(env, DesiredDisplayModeSpecsClazz, "defaultMode", "I");
2458     gDesiredDisplayModeSpecsClassInfo.allowGroupSwitching =
2459             GetFieldIDOrDie(env, DesiredDisplayModeSpecsClazz, "allowGroupSwitching", "Z");
2460     gDesiredDisplayModeSpecsClassInfo.primaryRefreshRateMin =
2461             GetFieldIDOrDie(env, DesiredDisplayModeSpecsClazz, "primaryRefreshRateMin", "F");
2462     gDesiredDisplayModeSpecsClassInfo.primaryRefreshRateMax =
2463             GetFieldIDOrDie(env, DesiredDisplayModeSpecsClazz, "primaryRefreshRateMax", "F");
2464     gDesiredDisplayModeSpecsClassInfo.appRequestRefreshRateMin =
2465             GetFieldIDOrDie(env, DesiredDisplayModeSpecsClazz, "appRequestRefreshRateMin", "F");
2466     gDesiredDisplayModeSpecsClassInfo.appRequestRefreshRateMax =
2467             GetFieldIDOrDie(env, DesiredDisplayModeSpecsClazz, "appRequestRefreshRateMax", "F");
2468 
2469     jclass captureArgsClazz = FindClassOrDie(env, "android/view/SurfaceControl$CaptureArgs");
2470     gCaptureArgsClassInfo.pixelFormat = GetFieldIDOrDie(env, captureArgsClazz, "mPixelFormat", "I");
2471     gCaptureArgsClassInfo.sourceCrop =
2472             GetFieldIDOrDie(env, captureArgsClazz, "mSourceCrop", "Landroid/graphics/Rect;");
2473     gCaptureArgsClassInfo.frameScaleX = GetFieldIDOrDie(env, captureArgsClazz, "mFrameScaleX", "F");
2474     gCaptureArgsClassInfo.frameScaleY = GetFieldIDOrDie(env, captureArgsClazz, "mFrameScaleY", "F");
2475     gCaptureArgsClassInfo.captureSecureLayers =
2476             GetFieldIDOrDie(env, captureArgsClazz, "mCaptureSecureLayers", "Z");
2477     gCaptureArgsClassInfo.allowProtected =
2478             GetFieldIDOrDie(env, captureArgsClazz, "mAllowProtected", "Z");
2479     gCaptureArgsClassInfo.uid = GetFieldIDOrDie(env, captureArgsClazz, "mUid", "J");
2480     gCaptureArgsClassInfo.grayscale = GetFieldIDOrDie(env, captureArgsClazz, "mGrayscale", "Z");
2481 
2482     jclass displayCaptureArgsClazz =
2483             FindClassOrDie(env, "android/view/SurfaceControl$DisplayCaptureArgs");
2484     gDisplayCaptureArgsClassInfo.displayToken =
2485             GetFieldIDOrDie(env, displayCaptureArgsClazz, "mDisplayToken", "Landroid/os/IBinder;");
2486     gDisplayCaptureArgsClassInfo.width =
2487             GetFieldIDOrDie(env, displayCaptureArgsClazz, "mWidth", "I");
2488     gDisplayCaptureArgsClassInfo.height =
2489             GetFieldIDOrDie(env, displayCaptureArgsClazz, "mHeight", "I");
2490     gDisplayCaptureArgsClassInfo.useIdentityTransform =
2491             GetFieldIDOrDie(env, displayCaptureArgsClazz, "mUseIdentityTransform", "Z");
2492 
2493     jclass layerCaptureArgsClazz =
2494             FindClassOrDie(env, "android/view/SurfaceControl$LayerCaptureArgs");
2495     gLayerCaptureArgsClassInfo.layer =
2496             GetFieldIDOrDie(env, layerCaptureArgsClazz, "mNativeLayer", "J");
2497     gLayerCaptureArgsClassInfo.excludeLayers =
2498             GetFieldIDOrDie(env, layerCaptureArgsClazz, "mNativeExcludeLayers", "[J");
2499     gLayerCaptureArgsClassInfo.childrenOnly =
2500             GetFieldIDOrDie(env, layerCaptureArgsClazz, "mChildrenOnly", "Z");
2501 
2502     jclass screenCaptureListenerClazz =
2503             FindClassOrDie(env, "android/view/SurfaceControl$ScreenCaptureListener");
2504     gScreenCaptureListenerClassInfo.clazz = MakeGlobalRefOrDie(env, screenCaptureListenerClazz);
2505     gScreenCaptureListenerClassInfo.onScreenCaptureComplete =
2506             GetMethodIDOrDie(env, screenCaptureListenerClazz, "onScreenCaptureComplete",
2507                              "(Landroid/view/SurfaceControl$ScreenshotHardwareBuffer;)V");
2508 
2509     jclass jankDataClazz =
2510                 FindClassOrDie(env, "android/view/SurfaceControl$JankData");
2511     gJankDataClassInfo.clazz = MakeGlobalRefOrDie(env, jankDataClazz);
2512     gJankDataClassInfo.ctor =
2513             GetMethodIDOrDie(env, gJankDataClassInfo.clazz, "<init>", "(JI)V");
2514     jclass onJankDataListenerClazz =
2515             FindClassOrDie(env, "android/view/SurfaceControl$OnJankDataListener");
2516     gJankDataListenerClassInfo.clazz = MakeGlobalRefOrDie(env, onJankDataListenerClazz);
2517     gJankDataListenerClassInfo.onJankDataAvailable =
2518             GetMethodIDOrDie(env, onJankDataListenerClazz, "onJankDataAvailable",
2519                              "([Landroid/view/SurfaceControl$JankData;)V");
2520 
2521     jclass transactionCommittedListenerClazz =
2522             FindClassOrDie(env, "android/view/SurfaceControl$TransactionCommittedListener");
2523     gTransactionCommittedListenerClassInfo.clazz =
2524             MakeGlobalRefOrDie(env, transactionCommittedListenerClazz);
2525     gTransactionCommittedListenerClassInfo.onTransactionCommitted =
2526             GetMethodIDOrDie(env, transactionCommittedListenerClazz, "onTransactionCommitted",
2527                              "()V");
2528 
2529     jclass displayDecorationSupportClazz =
2530             FindClassOrDie(env, "android/hardware/graphics/common/DisplayDecorationSupport");
2531     gDisplayDecorationSupportInfo.clazz = MakeGlobalRefOrDie(env, displayDecorationSupportClazz);
2532     gDisplayDecorationSupportInfo.ctor =
2533             GetMethodIDOrDie(env, displayDecorationSupportClazz, "<init>", "()V");
2534     gDisplayDecorationSupportInfo.format =
2535             GetFieldIDOrDie(env, displayDecorationSupportClazz, "format", "I");
2536     gDisplayDecorationSupportInfo.alphaInterpretation =
2537             GetFieldIDOrDie(env, displayDecorationSupportClazz, "alphaInterpretation", "I");
2538 
2539     jclass surfaceControlClazz = FindClassOrDie(env, "android/view/SurfaceControl");
2540     gInvokeReleaseCallback.clazz = MakeGlobalRefOrDie(env, surfaceControlClazz);
2541     gInvokeReleaseCallback.invokeReleaseCallback =
2542             GetStaticMethodIDOrDie(env, surfaceControlClazz, "invokeReleaseCallback",
2543                                    "(Ljava/util/function/Consumer;J)V");
2544 
2545     return err;
2546 }
2547 
2548 } // namespace android
2549