xref: /aosp_15_r20/frameworks/base/core/jni/android_view_SurfaceControl.cpp (revision d57664e9bc4670b3ecf6748a746a57c557b6bc9e)
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 <aidl/android/hardware/graphics/common/PixelFormat.h>
21 #include <android-base/chrono_utils.h>
22 #include <android/graphics/properties.h>
23 #include <android/graphics/region.h>
24 #include <android/gui/BnWindowInfosReportedListener.h>
25 #include <android/gui/EdgeExtensionParameters.h>
26 #include <android/gui/JankData.h>
27 #include <android/hardware/display/IDeviceProductInfoConstants.h>
28 #include <android/os/IInputConstants.h>
29 #include <android_runtime/AndroidRuntime.h>
30 #include <android_runtime/android_graphics_GraphicBuffer.h>
31 #include <android_runtime/android_hardware_HardwareBuffer.h>
32 #include <android_runtime/android_hardware_OverlayProperties.h>
33 #include <android_runtime/android_view_Surface.h>
34 #include <android_runtime/android_view_SurfaceControl.h>
35 #include <android_runtime/android_view_SurfaceSession.h>
36 #include <cutils/ashmem.h>
37 #include <gui/ISurfaceComposer.h>
38 #include <gui/JankInfo.h>
39 #include <gui/Surface.h>
40 #include <gui/SurfaceComposerClient.h>
41 #include <jni.h>
42 #include <nativehelper/JNIHelp.h>
43 #include <nativehelper/ScopedPrimitiveArray.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/FloatRect.h>
55 #include <ui/FrameStats.h>
56 #include <ui/GraphicTypes.h>
57 #include <ui/HdrCapabilities.h>
58 #include <ui/PictureProfileHandle.h>
59 #include <ui/Rect.h>
60 #include <ui/Region.h>
61 #include <ui/StaticDisplayInfo.h>
62 #include <utils/LightRefBase.h>
63 #include <utils/Log.h>
64 
65 #include <memory>
66 
67 #include "android_hardware_input_InputWindowHandle.h"
68 #include "android_os_Parcel.h"
69 #include "android_util_Binder.h"
70 #include "core_jni_helpers.h"
71 #include "jni_common.h"
72 
73 // ----------------------------------------------------------------------------
74 
75 namespace android {
76 
77 using gui::FocusRequest;
78 
doThrowNPE(JNIEnv * env)79 static void doThrowNPE(JNIEnv* env) {
80     jniThrowNullPointerException(env, NULL);
81 }
82 
doThrowIAE(JNIEnv * env,const char * msg=nullptr)83 static void doThrowIAE(JNIEnv* env, const char* msg = nullptr) {
84     jniThrowException(env, "java/lang/IllegalArgumentException", msg);
85 }
86 
87 static const char* const OutOfResourcesException =
88     "android/view/Surface$OutOfResourcesException";
89 
90 static struct {
91     jclass clazz;
92     jmethodID ctor;
93 } gIntegerClassInfo;
94 
toInteger(JNIEnv * env,int32_t i)95 static jobject toInteger(JNIEnv* env, int32_t i) {
96     return env->NewObject(gIntegerClassInfo.clazz, gIntegerClassInfo.ctor, i);
97 }
98 
99 static struct {
100     jclass clazz;
101     jmethodID run;
102 } gRunnableClassInfo;
103 
104 static struct {
105     jclass clazz;
106     jmethodID ctor;
107     jfieldID isInternal;
108     jfieldID density;
109     jfieldID secure;
110     jfieldID deviceProductInfo;
111     jfieldID installOrientation;
112 } gStaticDisplayInfoClassInfo;
113 
114 static struct {
115     jclass clazz;
116     jmethodID ctor;
117     jfieldID supportedDisplayModes;
118     jfieldID activeDisplayModeId;
119     jfieldID renderFrameRate;
120     jfieldID hasArrSupport;
121     jfieldID frameRateCategoryRate;
122     jfieldID supportedRefreshRates;
123     jfieldID supportedColorModes;
124     jfieldID activeColorMode;
125     jfieldID hdrCapabilities;
126     jfieldID autoLowLatencyModeSupported;
127     jfieldID gameContentTypeSupported;
128     jfieldID preferredBootDisplayMode;
129 } gDynamicDisplayInfoClassInfo;
130 
131 static struct {
132     jclass clazz;
133     jmethodID ctor;
134     jfieldID id;
135     jfieldID width;
136     jfieldID height;
137     jfieldID xDpi;
138     jfieldID yDpi;
139     jfieldID peakRefreshRate;
140     jfieldID vsyncRate;
141     jfieldID appVsyncOffsetNanos;
142     jfieldID presentationDeadlineNanos;
143     jfieldID group;
144     jfieldID supportedHdrTypes;
145 } gDisplayModeClassInfo;
146 
147 // Implements SkMallocPixelRef::ReleaseProc, to delete the screenshot on unref.
DeleteScreenshot(void * addr,void * context)148 void DeleteScreenshot(void* addr, void* context) {
149     delete ((ScreenshotClient*) context);
150 }
151 
152 static struct {
153     nsecs_t UNDEFINED_TIME_NANO;
154     jmethodID init;
155 } gWindowContentFrameStatsClassInfo;
156 
157 static struct {
158     nsecs_t UNDEFINED_TIME_NANO;
159     jmethodID init;
160 } gWindowAnimationFrameStatsClassInfo;
161 
162 static struct {
163     jclass clazz;
164     jmethodID ctor;
165 } gHdrCapabilitiesClassInfo;
166 
167 static struct {
168     jclass clazz;
169     jmethodID ctor;
170 } gDeviceProductInfoClassInfo;
171 
172 static struct {
173     jclass clazz;
174     jmethodID ctor;
175 } gDeviceProductInfoManufactureDateClassInfo;
176 
177 static struct {
178     jclass clazz;
179     jmethodID ctor;
180 } gDisplayedContentSampleClassInfo;
181 
182 static struct {
183     jclass clazz;
184     jmethodID ctor;
185 } gDisplayedContentSamplingAttributesClassInfo;
186 
187 static struct {
188     jclass clazz;
189     jmethodID ctor;
190     jfieldID X;
191     jfieldID Y;
192     jfieldID Z;
193 } gCieXyzClassInfo;
194 
195 static struct {
196     jclass clazz;
197     jmethodID ctor;
198     jfieldID red;
199     jfieldID green;
200     jfieldID blue;
201     jfieldID white;
202 } gDisplayPrimariesClassInfo;
203 
204 static struct {
205     jclass clazz;
206     jmethodID ctor;
207     jfieldID min;
208     jfieldID max;
209 } gRefreshRateRangeClassInfo;
210 
211 static struct {
212     jclass clazz;
213     jmethodID ctor;
214     jfieldID physical;
215     jfieldID render;
216 } gRefreshRateRangesClassInfo;
217 
218 static struct {
219     jclass clazz;
220     jmethodID ctor;
221     jfieldID timeoutMillis;
222 } gIdleScreenRefreshRateConfigClassInfo;
223 
224 static struct {
225     jclass clazz;
226     jmethodID ctor;
227     jfieldID defaultMode;
228     jfieldID allowGroupSwitching;
229     jfieldID primaryRanges;
230     jfieldID appRequestRanges;
231     jfieldID idleScreenRefreshRateConfig;
232 } gDesiredDisplayModeSpecsClassInfo;
233 
234 static struct {
235     jclass clazz;
236     jmethodID onJankDataAvailable;
237 } gJankDataListenerClassInfo;
238 
239 static struct {
240     jclass clazz;
241     jmethodID ctor;
242 } gJankDataClassInfo;
243 
244 static struct {
245     jclass clazz;
246     jmethodID onTransactionCommitted;
247 } gTransactionCommittedListenerClassInfo;
248 
249 static struct {
250     jclass clazz;
251     jmethodID accept;
252 } gConsumerClassInfo;
253 
254 static struct {
255     jclass clazz;
256     jmethodID ctor;
257 } gTransactionStatsClassInfo;
258 
259 static struct {
260     jclass clazz;
261     jmethodID ctor;
262     jfieldID format;
263     jfieldID alphaInterpretation;
264 } gDisplayDecorationSupportInfo;
265 
266 static struct {
267     jclass clazz;
268     jfieldID mNativeObject;
269 } gTransactionClassInfo;
270 
271 static struct {
272     jclass clazz;
273     jfieldID mNativeObject;
274     jfieldID mName;
275     jmethodID ctor;
276     jmethodID invokeReleaseCallback;
277 } gSurfaceControlClassInfo;
278 
279 static struct {
280     jclass clazz;
281     jfieldID mMinAlpha;
282     jfieldID mMinFractionRendered;
283     jfieldID mStabilityRequirementMs;
284 } gTrustedPresentationThresholdsClassInfo;
285 
286 static struct {
287     jmethodID onTrustedPresentationChanged;
288 } gTrustedPresentationCallbackClassInfo;
289 
290 static struct {
291     jclass clazz;
292     jmethodID ctor;
293     jfieldID layerName;
294     jfieldID bufferId;
295     jfieldID frameNumber;
296 } gStalledTransactionInfoClassInfo;
297 
298 static struct {
299     jclass clazz;
300     jmethodID ctor;
301 } gFrameRateCategoryRateClassInfo;
302 
303 static struct {
304     jclass clazz;
305     jmethodID asList;
306 } gUtilArrays;
307 
pickDataspaceFromColorMode(const ui::ColorMode colorMode)308 constexpr ui::Dataspace pickDataspaceFromColorMode(const ui::ColorMode colorMode) {
309     switch (colorMode) {
310         case ui::ColorMode::DISPLAY_P3:
311         case ui::ColorMode::BT2100_PQ:
312         case ui::ColorMode::BT2100_HLG:
313         case ui::ColorMode::DISPLAY_BT2020:
314             return ui::Dataspace::DISPLAY_P3;
315         default:
316             return ui::Dataspace::V0_SRGB;
317     }
318 }
319 
320 class TransactionCommittedListenerWrapper {
321 public:
TransactionCommittedListenerWrapper(JNIEnv * env,jobject object)322     explicit TransactionCommittedListenerWrapper(JNIEnv* env, jobject object) {
323         env->GetJavaVM(&mVm);
324         mTransactionCommittedListenerObject = env->NewGlobalRef(object);
325         LOG_ALWAYS_FATAL_IF(!mTransactionCommittedListenerObject, "Failed to make global ref");
326     }
327 
~TransactionCommittedListenerWrapper()328     ~TransactionCommittedListenerWrapper() {
329         getenv()->DeleteGlobalRef(mTransactionCommittedListenerObject);
330     }
331 
callback()332     void callback() {
333         JNIEnv* env = getenv();
334         env->CallVoidMethod(mTransactionCommittedListenerObject,
335                             gTransactionCommittedListenerClassInfo.onTransactionCommitted);
336         DieIfException(env, "Uncaught exception in TransactionCommittedListener.");
337     }
338 
transactionCallbackThunk(void * context,nsecs_t,const sp<Fence> &,const std::vector<SurfaceControlStats> &)339     static void transactionCallbackThunk(void* context, nsecs_t /*latchTime*/,
340                                          const sp<Fence>& /*presentFence*/,
341                                          const std::vector<SurfaceControlStats>& /*stats*/) {
342         TransactionCommittedListenerWrapper* listener =
343                 reinterpret_cast<TransactionCommittedListenerWrapper*>(context);
344         listener->callback();
345         delete listener;
346     }
347 
348 private:
349     jobject mTransactionCommittedListenerObject;
350     JavaVM* mVm;
351 
getenv()352     JNIEnv* getenv() {
353         JNIEnv* env;
354         mVm->GetEnv(reinterpret_cast<void**>(&env), JNI_VERSION_1_6);
355         return env;
356     }
357 };
358 
359 class TransactionCompletedListenerWrapper {
360 public:
TransactionCompletedListenerWrapper(JNIEnv * env,jobject object)361     explicit TransactionCompletedListenerWrapper(JNIEnv* env, jobject object) {
362         env->GetJavaVM(&mVm);
363         mTransactionCompletedListenerObject = env->NewGlobalRef(object);
364         LOG_ALWAYS_FATAL_IF(!mTransactionCompletedListenerObject, "Failed to make global ref");
365     }
366 
~TransactionCompletedListenerWrapper()367     ~TransactionCompletedListenerWrapper() {
368         getenv()->DeleteGlobalRef(mTransactionCompletedListenerObject);
369     }
370 
callback(nsecs_t latchTime,const sp<Fence> & presentFence,const std::vector<SurfaceControlStats> &)371     void callback(nsecs_t latchTime, const sp<Fence>& presentFence,
372                   const std::vector<SurfaceControlStats>& /*stats*/) {
373         JNIEnv* env = getenv();
374         // Adding a strong reference for java SyncFence
375         if (presentFence) {
376             presentFence->incStrong(0);
377         }
378 
379         jobject stats =
380                 env->NewObject(gTransactionStatsClassInfo.clazz, gTransactionStatsClassInfo.ctor,
381                                latchTime,
382                                static_cast<jlong>(reinterpret_cast<uintptr_t>(presentFence.get())));
383         env->CallVoidMethod(mTransactionCompletedListenerObject, gConsumerClassInfo.accept, stats);
384         env->DeleteLocalRef(stats);
385         DieIfException(env, "Uncaught exception in TransactionCompletedListener.");
386     }
387 
transactionCallbackThunk(void * context,nsecs_t latchTime,const sp<Fence> & presentFence,const std::vector<SurfaceControlStats> & stats)388     static void transactionCallbackThunk(void* context, nsecs_t latchTime,
389                                          const sp<Fence>& presentFence,
390                                          const std::vector<SurfaceControlStats>& stats) {
391         TransactionCompletedListenerWrapper* listener =
392                 reinterpret_cast<TransactionCompletedListenerWrapper*>(context);
393         listener->callback(latchTime, presentFence, stats);
394         delete listener;
395     }
396 
397 private:
398     jobject mTransactionCompletedListenerObject;
399     JavaVM* mVm;
400 
getenv()401     JNIEnv* getenv() {
402         JNIEnv* env;
403         mVm->GetEnv(reinterpret_cast<void**>(&env), JNI_VERSION_1_6);
404         return env;
405     }
406 };
407 
408 class WindowInfosReportedListenerWrapper : public gui::BnWindowInfosReportedListener {
409 public:
WindowInfosReportedListenerWrapper(JNIEnv * env,jobject listener)410     explicit WindowInfosReportedListenerWrapper(JNIEnv* env, jobject listener) {
411         env->GetJavaVM(&mVm);
412         mListener = env->NewGlobalRef(listener);
413         LOG_ALWAYS_FATAL_IF(!mListener, "Failed to make global ref");
414     }
415 
~WindowInfosReportedListenerWrapper()416     ~WindowInfosReportedListenerWrapper() {
417         if (mListener) {
418             getenv()->DeleteGlobalRef(mListener);
419             mListener = nullptr;
420         }
421     }
422 
onWindowInfosReported()423     binder::Status onWindowInfosReported() override {
424         JNIEnv* env = getenv();
425         env->CallVoidMethod(mListener, gRunnableClassInfo.run);
426         DieIfException(env, "Uncaught exception in WindowInfosReportedListener.");
427         return binder::Status::ok();
428     }
429 
430 private:
431     jobject mListener;
432     JavaVM* mVm;
433 
getenv()434     JNIEnv* getenv() {
435         JNIEnv* env;
436         mVm->GetEnv(reinterpret_cast<void**>(&env), JNI_VERSION_1_6);
437         return env;
438     }
439 };
440 
441 class TrustedPresentationCallbackWrapper {
442 public:
TrustedPresentationCallbackWrapper(JNIEnv * env,jobject trustedPresentationListener)443     explicit TrustedPresentationCallbackWrapper(JNIEnv* env, jobject trustedPresentationListener) {
444         env->GetJavaVM(&mVm);
445         mTrustedPresentationCallback = env->NewGlobalRef(trustedPresentationListener);
446         LOG_ALWAYS_FATAL_IF(!mTrustedPresentationCallback, "Failed to make global ref");
447     }
448 
~TrustedPresentationCallbackWrapper()449     ~TrustedPresentationCallbackWrapper() {
450         getenv()->DeleteGlobalRef(mTrustedPresentationCallback);
451     }
452 
onTrustedPresentationChanged(bool inTrustedPresentationState)453     void onTrustedPresentationChanged(bool inTrustedPresentationState) {
454         JNIEnv* env = getenv();
455         env->CallVoidMethod(mTrustedPresentationCallback,
456                             gTrustedPresentationCallbackClassInfo.onTrustedPresentationChanged,
457                             inTrustedPresentationState);
458         DieIfException(env, "Uncaught exception in TrustedPresentationCallback.");
459     }
460 
addCallbackRef(const sp<SurfaceComposerClient::PresentationCallbackRAII> & callbackRef)461     void addCallbackRef(const sp<SurfaceComposerClient::PresentationCallbackRAII>& callbackRef) {
462         mCallbackRef = callbackRef;
463     }
464 
onTrustedPresentationChangedThunk(void * context,bool inTrustedPresentationState)465     static void onTrustedPresentationChangedThunk(void* context, bool inTrustedPresentationState) {
466         TrustedPresentationCallbackWrapper* listener =
467                 reinterpret_cast<TrustedPresentationCallbackWrapper*>(context);
468         listener->onTrustedPresentationChanged(inTrustedPresentationState);
469     }
470 
471 private:
472     jobject mTrustedPresentationCallback;
473     JavaVM* mVm;
474     sp<SurfaceComposerClient::PresentationCallbackRAII> mCallbackRef;
475 
getenv()476     JNIEnv* getenv() {
477         JNIEnv* env;
478         mVm->GetEnv(reinterpret_cast<void**>(&env), JNI_VERSION_1_6);
479         return env;
480     }
481 };
482 
483 // ----------------------------------------------------------------------------
484 
nativeCreateTransaction(JNIEnv * env,jclass clazz)485 static jlong nativeCreateTransaction(JNIEnv* env, jclass clazz) {
486     return reinterpret_cast<jlong>(new SurfaceComposerClient::Transaction);
487 }
488 
releaseTransaction(SurfaceComposerClient::Transaction * t)489 static void releaseTransaction(SurfaceComposerClient::Transaction* t) {
490     delete t;
491 }
492 
nativeGetNativeTransactionFinalizer(JNIEnv * env,jclass clazz)493 static jlong nativeGetNativeTransactionFinalizer(JNIEnv* env, jclass clazz) {
494     return static_cast<jlong>(reinterpret_cast<uintptr_t>(&releaseTransaction));
495 }
496 
nativeCreate(JNIEnv * env,jclass clazz,jobject sessionObj,jstring nameStr,jint w,jint h,jint format,jint flags,jlong parentObject,jobject metadataParcel)497 static jlong nativeCreate(JNIEnv* env, jclass clazz, jobject sessionObj,
498         jstring nameStr, jint w, jint h, jint format, jint flags, jlong parentObject,
499         jobject metadataParcel) {
500     ScopedUtfChars name(env, nameStr);
501     sp<SurfaceComposerClient> client;
502     if (sessionObj != NULL) {
503         client = android_view_SurfaceSession_getClient(env, sessionObj);
504     } else {
505         client = SurfaceComposerClient::getDefault();
506     }
507     SurfaceControl *parent = reinterpret_cast<SurfaceControl*>(parentObject);
508     sp<SurfaceControl> surface;
509     LayerMetadata metadata;
510     Parcel* parcel = parcelForJavaObject(env, metadataParcel);
511     if (parcel && !parcel->objectsCount()) {
512         status_t err = metadata.readFromParcel(parcel);
513         if (err != NO_ERROR) {
514           jniThrowException(env, "java/lang/IllegalArgumentException",
515                             "Metadata parcel has wrong format");
516         }
517     }
518 
519     sp<IBinder> parentHandle;
520     if (parent != nullptr) {
521         parentHandle = parent->getHandle();
522     }
523 
524     status_t err = client->createSurfaceChecked(String8(name.c_str()), w, h, format, &surface,
525                                                 flags, parentHandle, std::move(metadata));
526     if (err == NAME_NOT_FOUND) {
527         jniThrowException(env, "java/lang/IllegalArgumentException", NULL);
528         return 0;
529     } else if (err != NO_ERROR) {
530         jniThrowException(env, OutOfResourcesException, statusToString(err).c_str());
531         return 0;
532     }
533 
534     surface->incStrong((void *)nativeCreate);
535     return reinterpret_cast<jlong>(surface.get());
536 }
537 
release(SurfaceControl * ctrl)538 static void release(SurfaceControl* ctrl) {
539     ctrl->decStrong((void *)nativeCreate);
540 }
541 
nativeGetNativeSurfaceControlFinalizer(JNIEnv * env,jclass clazz)542 static jlong nativeGetNativeSurfaceControlFinalizer(JNIEnv* env, jclass clazz) {
543     return static_cast<jlong>(reinterpret_cast<uintptr_t>(&release));
544 }
545 
nativeDisconnect(JNIEnv * env,jclass clazz,jlong nativeObject)546 static void nativeDisconnect(JNIEnv* env, jclass clazz, jlong nativeObject) {
547     SurfaceControl* const ctrl = reinterpret_cast<SurfaceControl *>(nativeObject);
548     if (ctrl != NULL) {
549         ctrl->disconnect();
550     }
551 }
552 
nativeSetDefaultBufferSize(JNIEnv * env,jclass clazz,jlong nativeObject,jint width,jint height)553 static void nativeSetDefaultBufferSize(JNIEnv* env, jclass clazz, jlong nativeObject,
554                                        jint width, jint height) {
555     SurfaceControl* const ctrl = reinterpret_cast<SurfaceControl *>(nativeObject);
556     if (ctrl != NULL) {
557         ctrl->updateDefaultBufferSize(width, height);
558     }
559 }
560 
nativeApplyTransaction(JNIEnv * env,jclass clazz,jlong transactionObj,jboolean sync,jboolean oneWay)561 static void nativeApplyTransaction(JNIEnv* env, jclass clazz, jlong transactionObj, jboolean sync,
562                                    jboolean oneWay) {
563     auto transaction = reinterpret_cast<SurfaceComposerClient::Transaction*>(transactionObj);
564     transaction->apply(sync, oneWay);
565 }
566 
nativeMergeTransaction(JNIEnv * env,jclass clazz,jlong transactionObj,jlong otherTransactionObj)567 static void nativeMergeTransaction(JNIEnv* env, jclass clazz,
568         jlong transactionObj, jlong otherTransactionObj) {
569     auto transaction = reinterpret_cast<SurfaceComposerClient::Transaction*>(transactionObj);
570     auto otherTransaction = reinterpret_cast<SurfaceComposerClient::Transaction*>(
571             otherTransactionObj);
572     transaction->merge(std::move(*otherTransaction));
573 }
574 
nativeSetAnimationTransaction(JNIEnv * env,jclass clazz,jlong transactionObj)575 static void nativeSetAnimationTransaction(JNIEnv* env, jclass clazz, jlong transactionObj) {
576     auto transaction = reinterpret_cast<SurfaceComposerClient::Transaction*>(transactionObj);
577     transaction->setAnimationTransaction();
578 }
579 
nativeSetEarlyWakeupStart(JNIEnv * env,jclass clazz,jlong transactionObj)580 static void nativeSetEarlyWakeupStart(JNIEnv* env, jclass clazz, jlong transactionObj) {
581     auto transaction = reinterpret_cast<SurfaceComposerClient::Transaction*>(transactionObj);
582     transaction->setEarlyWakeupStart();
583 }
584 
nativeSetEarlyWakeupEnd(JNIEnv * env,jclass clazz,jlong transactionObj)585 static void nativeSetEarlyWakeupEnd(JNIEnv* env, jclass clazz, jlong transactionObj) {
586     auto transaction = reinterpret_cast<SurfaceComposerClient::Transaction*>(transactionObj);
587     transaction->setEarlyWakeupEnd();
588 }
589 
nativeGetTransactionId(JNIEnv * env,jclass clazz,jlong transactionObj)590 static jlong nativeGetTransactionId(JNIEnv* env, jclass clazz, jlong transactionObj) {
591     auto transaction = reinterpret_cast<SurfaceComposerClient::Transaction*>(transactionObj);
592     return transaction->getId();
593 }
594 
nativeSetLayer(JNIEnv * env,jclass clazz,jlong transactionObj,jlong nativeObject,jint zorder)595 static void nativeSetLayer(JNIEnv* env, jclass clazz, jlong transactionObj,
596         jlong nativeObject, jint zorder) {
597     auto transaction = reinterpret_cast<SurfaceComposerClient::Transaction*>(transactionObj);
598 
599     SurfaceControl* const ctrl = reinterpret_cast<SurfaceControl *>(nativeObject);
600     transaction->setLayer(ctrl, zorder);
601 }
602 
nativeSetRelativeLayer(JNIEnv * env,jclass clazz,jlong transactionObj,jlong nativeObject,jlong relativeToObject,jint zorder)603 static void nativeSetRelativeLayer(JNIEnv* env, jclass clazz, jlong transactionObj,
604         jlong nativeObject,
605         jlong relativeToObject, jint zorder) {
606 
607     auto ctrl = reinterpret_cast<SurfaceControl *>(nativeObject);
608     auto relative = reinterpret_cast<SurfaceControl *>(relativeToObject);
609     auto transaction = reinterpret_cast<SurfaceComposerClient::Transaction*>(transactionObj);
610     transaction->setRelativeLayer(ctrl, relative, zorder);
611 }
612 
nativeSetPosition(JNIEnv * env,jclass clazz,jlong transactionObj,jlong nativeObject,jfloat x,jfloat y)613 static void nativeSetPosition(JNIEnv* env, jclass clazz, jlong transactionObj,
614         jlong nativeObject, jfloat x, jfloat y) {
615     auto transaction = reinterpret_cast<SurfaceComposerClient::Transaction*>(transactionObj);
616 
617     SurfaceControl* const ctrl = reinterpret_cast<SurfaceControl *>(nativeObject);
618     transaction->setPosition(ctrl, x, y);
619 }
620 
nativeSetScale(JNIEnv * env,jclass clazz,jlong transactionObj,jlong nativeObject,jfloat xScale,jfloat yScale)621 static void nativeSetScale(JNIEnv* env, jclass clazz, jlong transactionObj, jlong nativeObject,
622                            jfloat xScale, jfloat yScale) {
623     auto transaction = reinterpret_cast<SurfaceComposerClient::Transaction*>(transactionObj);
624 
625     SurfaceControl* const ctrl = reinterpret_cast<SurfaceControl*>(nativeObject);
626     transaction->setMatrix(ctrl, xScale, 0, 0, yScale);
627 }
628 
nativeSetGeometry(JNIEnv * env,jclass clazz,jlong transactionObj,jlong nativeObject,jobject sourceObj,jobject dstObj,jlong orientation)629 static void nativeSetGeometry(JNIEnv* env, jclass clazz, jlong transactionObj, jlong nativeObject,
630         jobject sourceObj, jobject dstObj, jlong orientation) {
631     auto transaction = reinterpret_cast<SurfaceComposerClient::Transaction*>(transactionObj);
632     SurfaceControl* const ctrl = reinterpret_cast<SurfaceControl *>(nativeObject);
633 
634     Rect source, dst;
635     if (sourceObj != NULL) {
636         source = JNICommon::rectFromObj(env, sourceObj);
637     } else {
638         source.makeInvalid();
639     }
640     if (dstObj != NULL) {
641         dst = JNICommon::rectFromObj(env, dstObj);
642     } else {
643         dst.makeInvalid();
644     }
645     transaction->setGeometry(ctrl, source, dst, orientation);
646 }
647 
648 class JGlobalRefHolder {
649 public:
JGlobalRefHolder(JavaVM * vm,jobject object)650     JGlobalRefHolder(JavaVM* vm, jobject object) : mVm(vm), mObject(object) {}
651 
~JGlobalRefHolder()652     virtual ~JGlobalRefHolder() {
653         env()->DeleteGlobalRef(mObject);
654         mObject = nullptr;
655     }
656 
object()657     jobject object() { return mObject; }
vm()658     JavaVM* vm() { return mVm; }
659 
env()660     JNIEnv* env() {
661         JNIEnv* env = nullptr;
662         if (mVm->GetEnv(reinterpret_cast<void**>(&env), JNI_VERSION_1_6) != JNI_OK) {
663             if (mVm->AttachCurrentThreadAsDaemon(&env, nullptr) != JNI_OK) {
664                 LOG_ALWAYS_FATAL("Failed to AttachCurrentThread!");
665             }
666         }
667         return env;
668     }
669 
670 private:
671     JGlobalRefHolder(const JGlobalRefHolder&) = delete;
672     void operator=(const JGlobalRefHolder&) = delete;
673 
674     JavaVM* mVm;
675     jobject mObject;
676 };
677 
genReleaseCallback(JNIEnv * env,jobject releaseCallback)678 static ReleaseBufferCallback genReleaseCallback(JNIEnv* env, jobject releaseCallback) {
679     if (releaseCallback == nullptr) return nullptr;
680 
681     JavaVM* vm = nullptr;
682     LOG_ALWAYS_FATAL_IF(env->GetJavaVM(&vm) != JNI_OK, "Unable to get Java VM");
683     auto globalCallbackRef =
684             std::make_shared<JGlobalRefHolder>(vm, env->NewGlobalRef(releaseCallback));
685     return [globalCallbackRef](const ReleaseCallbackId&, const sp<Fence>& releaseFence,
686                                std::optional<uint32_t> currentMaxAcquiredBufferCount) {
687         Fence* fenceCopy = releaseFence.get();
688         // We need to grab an extra ref as Java's SyncFence takes ownership
689         if (fenceCopy) {
690             fenceCopy->incStrong(0);
691         }
692         globalCallbackRef->env()
693                 ->CallStaticVoidMethod(gSurfaceControlClassInfo.clazz,
694                                        gSurfaceControlClassInfo.invokeReleaseCallback,
695                                        globalCallbackRef->object(),
696                                        reinterpret_cast<jlong>(fenceCopy));
697     };
698 }
699 
nativeSetBuffer(JNIEnv * env,jclass clazz,jlong transactionObj,jlong nativeObject,jobject bufferObject,jlong fencePtr,jobject releaseCallback)700 static void nativeSetBuffer(JNIEnv* env, jclass clazz, jlong transactionObj, jlong nativeObject,
701                             jobject bufferObject, jlong fencePtr, jobject releaseCallback) {
702     auto transaction = reinterpret_cast<SurfaceComposerClient::Transaction*>(transactionObj);
703     SurfaceControl* const ctrl = reinterpret_cast<SurfaceControl*>(nativeObject);
704     sp<GraphicBuffer> graphicBuffer;
705     if (bufferObject != nullptr) {
706         graphicBuffer = GraphicBuffer::fromAHardwareBuffer(
707                 android_hardware_HardwareBuffer_getNativeHardwareBuffer(env, bufferObject));
708     }
709     std::optional<sp<Fence>> optFence = std::nullopt;
710     if (fencePtr != 0) {
711         optFence = sp<Fence>{reinterpret_cast<Fence*>(fencePtr)};
712     }
713     transaction->setBuffer(ctrl, graphicBuffer, optFence, std::nullopt, 0 /* producerId */,
714                            genReleaseCallback(env, releaseCallback));
715 }
716 
nativeUnsetBuffer(JNIEnv * env,jclass clazz,jlong transactionObj,jlong nativeObject)717 static void nativeUnsetBuffer(JNIEnv* env, jclass clazz, jlong transactionObj, jlong nativeObject) {
718     auto transaction = reinterpret_cast<SurfaceComposerClient::Transaction*>(transactionObj);
719     SurfaceControl* const ctrl = reinterpret_cast<SurfaceControl*>(nativeObject);
720     transaction->unsetBuffer(ctrl);
721 }
722 
nativeSetBufferTransform(JNIEnv * env,jclass clazz,jlong transactionObj,jlong nativeObject,jint transform)723 static void nativeSetBufferTransform(JNIEnv* env, jclass clazz, jlong transactionObj,
724                                      jlong nativeObject, jint transform) {
725     auto transaction = reinterpret_cast<SurfaceComposerClient::Transaction*>(transactionObj);
726     SurfaceControl* const ctrl = reinterpret_cast<SurfaceControl*>(nativeObject);
727     transaction->setTransform(ctrl, transform);
728     bool transformToInverseDisplay = (NATIVE_WINDOW_TRANSFORM_INVERSE_DISPLAY & transform) ==
729             NATIVE_WINDOW_TRANSFORM_INVERSE_DISPLAY;
730     transaction->setTransformToDisplayInverse(ctrl, transformToInverseDisplay);
731 }
732 
nativeSetDataSpace(JNIEnv * env,jclass clazz,jlong transactionObj,jlong nativeObject,jint dataSpace)733 static void nativeSetDataSpace(JNIEnv* env, jclass clazz, jlong transactionObj, jlong nativeObject,
734                                jint dataSpace) {
735     auto transaction = reinterpret_cast<SurfaceComposerClient::Transaction*>(transactionObj);
736     SurfaceControl* const ctrl = reinterpret_cast<SurfaceControl*>(nativeObject);
737     ui::Dataspace dataspace = static_cast<ui::Dataspace>(dataSpace);
738     transaction->setDataspace(ctrl, dataspace);
739 }
740 
nativeSetExtendedRangeBrightness(JNIEnv * env,jclass clazz,jlong transactionObj,jlong nativeObject,float currentBufferRatio,float desiredRatio)741 static void nativeSetExtendedRangeBrightness(JNIEnv* env, jclass clazz, jlong transactionObj,
742                                              jlong nativeObject, float currentBufferRatio,
743                                              float desiredRatio) {
744     auto transaction = reinterpret_cast<SurfaceComposerClient::Transaction*>(transactionObj);
745     SurfaceControl* const ctrl = reinterpret_cast<SurfaceControl*>(nativeObject);
746     transaction->setExtendedRangeBrightness(ctrl, currentBufferRatio, desiredRatio);
747 }
748 
nativeSetDesiredHdrHeadroom(JNIEnv * env,jclass clazz,jlong transactionObj,jlong nativeObject,float desiredRatio)749 static void nativeSetDesiredHdrHeadroom(JNIEnv* env, jclass clazz, jlong transactionObj,
750                                         jlong nativeObject, float desiredRatio) {
751     auto transaction = reinterpret_cast<SurfaceComposerClient::Transaction*>(transactionObj);
752     SurfaceControl* const ctrl = reinterpret_cast<SurfaceControl*>(nativeObject);
753     transaction->setDesiredHdrHeadroom(ctrl, desiredRatio);
754 }
755 
nativeSetLuts(JNIEnv * env,jclass clazz,jlong transactionObj,jlong nativeObject,jfloatArray jbufferArray,jintArray joffsetArray,jintArray jdimensionArray,jintArray jsizeArray,jintArray jsamplingKeyArray)756 static void nativeSetLuts(JNIEnv* env, jclass clazz, jlong transactionObj, jlong nativeObject,
757                           jfloatArray jbufferArray, jintArray joffsetArray,
758                           jintArray jdimensionArray, jintArray jsizeArray,
759                           jintArray jsamplingKeyArray) {
760     auto transaction = reinterpret_cast<SurfaceComposerClient::Transaction*>(transactionObj);
761     SurfaceControl* const ctrl = reinterpret_cast<SurfaceControl*>(nativeObject);
762 
763     std::vector<int32_t> offsets;
764     std::vector<int32_t> dimensions;
765     std::vector<int32_t> sizes;
766     std::vector<int32_t> samplingKeys;
767     int32_t fd = -1;
768 
769     if (jdimensionArray) {
770         jsize numLuts = env->GetArrayLength(jdimensionArray);
771         ScopedIntArrayRW joffsets(env, joffsetArray);
772         if (joffsets.get() == nullptr) {
773             jniThrowRuntimeException(env, "Failed to get ScopedIntArrayRW from joffsetArray");
774             return;
775         }
776         ScopedIntArrayRW jdimensions(env, jdimensionArray);
777         if (jdimensions.get() == nullptr) {
778             jniThrowRuntimeException(env, "Failed to get ScopedIntArrayRW from jdimensionArray");
779             return;
780         }
781         ScopedIntArrayRW jsizes(env, jsizeArray);
782         if (jsizes.get() == nullptr) {
783             jniThrowRuntimeException(env, "Failed to get ScopedIntArrayRW from jsizeArray");
784             return;
785         }
786         ScopedIntArrayRW jsamplingKeys(env, jsamplingKeyArray);
787         if (jsamplingKeys.get() == nullptr) {
788             jniThrowRuntimeException(env, "Failed to get ScopedIntArrayRW from jsamplingKeyArray");
789             return;
790         }
791 
792         if (numLuts > 0) {
793             offsets = std::vector<int32_t>(joffsets.get(), joffsets.get() + numLuts);
794             dimensions = std::vector<int32_t>(jdimensions.get(), jdimensions.get() + numLuts);
795             sizes = std::vector<int32_t>(jsizes.get(), jsizes.get() + numLuts);
796             samplingKeys = std::vector<int32_t>(jsamplingKeys.get(), jsamplingKeys.get() + numLuts);
797 
798             ScopedFloatArrayRW jbuffers(env, jbufferArray);
799             if (jbuffers.get() == nullptr) {
800                 jniThrowRuntimeException(env, "Failed to get ScopedFloatArrayRW from jbufferArray");
801                 return;
802             }
803 
804             // create the shared memory and copy jbuffers
805             size_t bufferSize = jbuffers.size() * sizeof(float);
806             fd = ashmem_create_region("lut_shared_mem", bufferSize);
807             if (fd < 0) {
808                 jniThrowRuntimeException(env, "ashmem_create_region() failed");
809                 return;
810             }
811             void* ptr = mmap(nullptr, bufferSize, PROT_READ | PROT_WRITE, MAP_SHARED, fd, 0);
812             if (ptr == MAP_FAILED) {
813                 jniThrowRuntimeException(env, "Failed to map the shared memory");
814                 return;
815             }
816             memcpy(ptr, jbuffers.get(), bufferSize);
817             // unmap
818             munmap(ptr, bufferSize);
819         }
820     }
821 
822     transaction->setLuts(ctrl, base::unique_fd(fd), offsets, dimensions, sizes, samplingKeys);
823 }
824 
nativeSetPictureProfileId(JNIEnv * env,jclass clazz,jlong transactionObj,jlong surfaceControlObj,jlong pictureProfileId)825 static void nativeSetPictureProfileId(JNIEnv* env, jclass clazz, jlong transactionObj,
826                                       jlong surfaceControlObj, jlong pictureProfileId) {
827     auto transaction = reinterpret_cast<SurfaceComposerClient::Transaction*>(transactionObj);
828     SurfaceControl* const surfaceControl = reinterpret_cast<SurfaceControl*>(surfaceControlObj);
829     PictureProfileHandle handle(pictureProfileId);
830     transaction->setPictureProfileHandle(surfaceControl, handle);
831 }
832 
nativeSetContentPriority(JNIEnv * env,jclass clazz,jlong transactionObj,jlong surfaceControlObj,jint priority)833 static void nativeSetContentPriority(JNIEnv* env, jclass clazz, jlong transactionObj,
834                                      jlong surfaceControlObj, jint priority) {
835     auto transaction = reinterpret_cast<SurfaceComposerClient::Transaction*>(transactionObj);
836     SurfaceControl* const surfaceControl = reinterpret_cast<SurfaceControl*>(surfaceControlObj);
837     transaction->setContentPriority(surfaceControl, priority);
838 }
839 
nativeSetCachingHint(JNIEnv * env,jclass clazz,jlong transactionObj,jlong nativeObject,jint cachingHint)840 static void nativeSetCachingHint(JNIEnv* env, jclass clazz, jlong transactionObj,
841                                  jlong nativeObject, jint cachingHint) {
842     auto transaction = reinterpret_cast<SurfaceComposerClient::Transaction*>(transactionObj);
843     SurfaceControl* const ctrl = reinterpret_cast<SurfaceControl*>(nativeObject);
844     transaction->setCachingHint(ctrl, static_cast<gui::CachingHint>(cachingHint));
845 }
846 
nativeSetBlurRegions(JNIEnv * env,jclass clazz,jlong transactionObj,jlong nativeObject,jobjectArray regions,jint regionsLength)847 static void nativeSetBlurRegions(JNIEnv* env, jclass clazz, jlong transactionObj,
848                                  jlong nativeObject, jobjectArray regions, jint regionsLength) {
849     auto transaction = reinterpret_cast<SurfaceComposerClient::Transaction*>(transactionObj);
850     SurfaceControl* const ctrl = reinterpret_cast<SurfaceControl*>(nativeObject);
851 
852     std::vector<BlurRegion> blurRegionVector;
853     const int size = regionsLength;
854     float region[10];
855     for (int i = 0; i < size; i++) {
856         jfloatArray regionArray = (jfloatArray)env->GetObjectArrayElement(regions, i);
857         env->GetFloatArrayRegion(regionArray, 0, 10, region);
858         float blurRadius = region[0];
859         float alpha = region[1];
860         float left = region[2];
861         float top = region[3];
862         float right = region[4];
863         float bottom = region[5];
864         float cornerRadiusTL = region[6];
865         float cornerRadiusTR = region[7];
866         float cornerRadiusBL = region[8];
867         float cornerRadiusBR = region[9];
868 
869         blurRegionVector.push_back(BlurRegion{.blurRadius = static_cast<uint32_t>(blurRadius),
870                                               .cornerRadiusTL = cornerRadiusTL,
871                                               .cornerRadiusTR = cornerRadiusTR,
872                                               .cornerRadiusBL = cornerRadiusBL,
873                                               .cornerRadiusBR = cornerRadiusBR,
874                                               .alpha = alpha,
875                                               .left = static_cast<int>(left),
876                                               .top = static_cast<int>(top),
877                                               .right = static_cast<int>(right),
878                                               .bottom = static_cast<int>(bottom)});
879     }
880 
881     transaction->setBlurRegions(ctrl, blurRegionVector);
882 }
883 
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)884 static void nativeSetStretchEffect(JNIEnv* env, jclass clazz, jlong transactionObj,
885                                    jlong nativeObject, jfloat width, jfloat height,
886                                    jfloat vecX, jfloat vecY,
887                                    jfloat maxStretchAmountX, jfloat maxStretchAmountY,
888                                    jfloat childRelativeLeft, jfloat childRelativeTop,
889                                    jfloat childRelativeRight, jfloat childRelativeBottom) {
890     auto transaction = reinterpret_cast<SurfaceComposerClient::Transaction*>(transactionObj);
891     auto* const ctrl = reinterpret_cast<SurfaceControl*>(nativeObject);
892     auto stretch = StretchEffect{
893       .width = width,
894       .height = height,
895       .vectorX = vecX,
896       .vectorY = vecY,
897       .maxAmountX = maxStretchAmountX,
898       .maxAmountY = maxStretchAmountY,
899       .mappedChildBounds = FloatRect(
900           childRelativeLeft, childRelativeTop, childRelativeRight, childRelativeBottom)
901     };
902     transaction->setStretchEffect(ctrl, stretch);
903 }
904 
nativeSetEdgeExtensionEffect(JNIEnv * env,jclass clazz,jlong transactionObj,jlong nativeObj,jboolean leftEdge,jboolean rightEdge,jboolean topEdge,jboolean bottomEdge)905 static void nativeSetEdgeExtensionEffect(JNIEnv* env, jclass clazz, jlong transactionObj,
906                                          jlong nativeObj, jboolean leftEdge, jboolean rightEdge,
907                                          jboolean topEdge, jboolean bottomEdge) {
908     auto transaction = reinterpret_cast<SurfaceComposerClient::Transaction*>(transactionObj);
909     auto* const ctrl = reinterpret_cast<SurfaceControl*>(nativeObj);
910 
911     auto effect = gui::EdgeExtensionParameters();
912     effect.extendLeft = leftEdge;
913     effect.extendRight = rightEdge;
914     effect.extendTop = topEdge;
915     effect.extendBottom = bottomEdge;
916     transaction->setEdgeExtensionEffect(ctrl, effect);
917 }
918 
nativeSetFlags(JNIEnv * env,jclass clazz,jlong transactionObj,jlong nativeObject,jint flags,jint mask)919 static void nativeSetFlags(JNIEnv* env, jclass clazz, jlong transactionObj,
920         jlong nativeObject, jint flags, jint mask) {
921     auto transaction = reinterpret_cast<SurfaceComposerClient::Transaction*>(transactionObj);
922 
923     SurfaceControl* const ctrl = reinterpret_cast<SurfaceControl *>(nativeObject);
924     transaction->setFlags(ctrl, flags, mask);
925 }
926 
nativeSetFrameRateSelectionPriority(JNIEnv * env,jclass clazz,jlong transactionObj,jlong nativeObject,jint priority)927 static void nativeSetFrameRateSelectionPriority(JNIEnv* env, jclass clazz, jlong transactionObj,
928         jlong nativeObject, jint priority) {
929     auto transaction = reinterpret_cast<SurfaceComposerClient::Transaction*>(transactionObj);
930 
931     SurfaceControl* const ctrl = reinterpret_cast<SurfaceControl *>(nativeObject);
932     transaction->setFrameRateSelectionPriority(ctrl, priority);
933 }
934 
nativeSetTransparentRegionHint(JNIEnv * env,jclass clazz,jlong transactionObj,jlong nativeObject,jobject regionObj)935 static void nativeSetTransparentRegionHint(JNIEnv* env, jclass clazz, jlong transactionObj,
936         jlong nativeObject, jobject regionObj) {
937     SurfaceControl* const ctrl = reinterpret_cast<SurfaceControl *>(nativeObject);
938     graphics::RegionIterator iterator(env, regionObj);
939     if (!iterator.isValid()) {
940         doThrowIAE(env);
941         return;
942     }
943 
944     ARect bounds = iterator.getTotalBounds();
945     Region reg({bounds.left, bounds.top, bounds.right, bounds.bottom});
946     if (iterator.isComplex()) {
947         while (!iterator.isDone()) {
948             ARect rect = iterator.getRect();
949             reg.addRectUnchecked(rect.left, rect.top, rect.right, rect.bottom);
950             iterator.next();
951         }
952     }
953 
954     {
955         auto transaction = reinterpret_cast<SurfaceComposerClient::Transaction*>(transactionObj);
956         transaction->setTransparentRegionHint(ctrl, reg);
957     }
958 }
959 
nativeSetDamageRegion(JNIEnv * env,jclass clazz,jlong transactionObj,jlong nativeObject,jobject regionObj)960 static void nativeSetDamageRegion(JNIEnv* env, jclass clazz, jlong transactionObj,
961                                   jlong nativeObject, jobject regionObj) {
962     SurfaceControl* const surfaceControl = reinterpret_cast<SurfaceControl*>(nativeObject);
963     auto transaction = reinterpret_cast<SurfaceComposerClient::Transaction*>(transactionObj);
964 
965     if (regionObj == nullptr) {
966         transaction->setSurfaceDamageRegion(surfaceControl, Region::INVALID_REGION);
967         return;
968     }
969 
970     graphics::RegionIterator iterator(env, regionObj);
971     if (!iterator.isValid()) {
972         transaction->setSurfaceDamageRegion(surfaceControl, Region::INVALID_REGION);
973         return;
974     }
975 
976     Region region;
977     while (!iterator.isDone()) {
978         ARect rect = iterator.getRect();
979         region.orSelf(static_cast<const Rect&>(rect));
980         iterator.next();
981     }
982 
983     if (region.getBounds().isEmpty()) {
984         transaction->setSurfaceDamageRegion(surfaceControl, Region::INVALID_REGION);
985         return;
986     }
987 
988     transaction->setSurfaceDamageRegion(surfaceControl, region);
989 }
990 
nativeSetDimmingEnabled(JNIEnv * env,jclass clazz,jlong transactionObj,jlong nativeObject,jboolean dimmingEnabled)991 static void nativeSetDimmingEnabled(JNIEnv* env, jclass clazz, jlong transactionObj,
992                                     jlong nativeObject, jboolean dimmingEnabled) {
993     auto transaction = reinterpret_cast<SurfaceComposerClient::Transaction*>(transactionObj);
994 
995     SurfaceControl* const ctrl = reinterpret_cast<SurfaceControl*>(nativeObject);
996     transaction->setDimmingEnabled(ctrl, dimmingEnabled);
997 }
998 
nativeSetAlpha(JNIEnv * env,jclass clazz,jlong transactionObj,jlong nativeObject,jfloat alpha)999 static void nativeSetAlpha(JNIEnv* env, jclass clazz, jlong transactionObj,
1000         jlong nativeObject, jfloat alpha) {
1001     auto transaction = reinterpret_cast<SurfaceComposerClient::Transaction*>(transactionObj);
1002 
1003     SurfaceControl* const ctrl = reinterpret_cast<SurfaceControl *>(nativeObject);
1004     transaction->setAlpha(ctrl, alpha);
1005 }
1006 
nativeSetInputWindowInfo(JNIEnv * env,jclass clazz,jlong transactionObj,jlong nativeObject,jobject inputWindow)1007 static void nativeSetInputWindowInfo(JNIEnv* env, jclass clazz, jlong transactionObj,
1008         jlong nativeObject, jobject inputWindow) {
1009     if (!inputWindow) {
1010         jniThrowNullPointerException(env, "InputWindowHandle is null");
1011         return;
1012     }
1013 
1014     auto transaction = reinterpret_cast<SurfaceComposerClient::Transaction*>(transactionObj);
1015 
1016     sp<gui::WindowInfoHandle> info = android_view_InputWindowHandle_getHandle(env, inputWindow);
1017     auto ctrl = reinterpret_cast<SurfaceControl *>(nativeObject);
1018     transaction->setInputWindowInfo(ctrl, std::move(info));
1019 }
1020 
nativeAddWindowInfosReportedListener(JNIEnv * env,jclass clazz,jlong transactionObj,jobject runnable)1021 static void nativeAddWindowInfosReportedListener(JNIEnv* env, jclass clazz, jlong transactionObj,
1022                                                  jobject runnable) {
1023     auto listener = sp<WindowInfosReportedListenerWrapper>::make(env, runnable);
1024     auto transaction = reinterpret_cast<SurfaceComposerClient::Transaction*>(transactionObj);
1025     transaction->addWindowInfosReportedListener(listener);
1026 }
1027 
nativeSetMetadata(JNIEnv * env,jclass clazz,jlong transactionObj,jlong nativeObject,jint id,jobject parcelObj)1028 static void nativeSetMetadata(JNIEnv* env, jclass clazz, jlong transactionObj,
1029         jlong nativeObject, jint id, jobject parcelObj) {
1030     Parcel* parcel = parcelForJavaObject(env, parcelObj);
1031     if (!parcel) {
1032         jniThrowNullPointerException(env, "attribute data");
1033         return;
1034     }
1035     if (parcel->objectsCount()) {
1036         jniThrowException(env, "java/lang/RuntimeException",
1037                 "Tried to marshall a Parcel that contained Binder objects.");
1038         return;
1039     }
1040 
1041     auto transaction = reinterpret_cast<SurfaceComposerClient::Transaction*>(transactionObj);
1042 
1043     SurfaceControl* const ctrl = reinterpret_cast<SurfaceControl*>(nativeObject);
1044     transaction->setMetadata(ctrl, id, *parcel);
1045 }
1046 
nativeSetColor(JNIEnv * env,jclass clazz,jlong transactionObj,jlong nativeObject,jfloatArray fColor)1047 static void nativeSetColor(JNIEnv* env, jclass clazz, jlong transactionObj,
1048         jlong nativeObject, jfloatArray fColor) {
1049     auto transaction = reinterpret_cast<SurfaceComposerClient::Transaction*>(transactionObj);
1050     SurfaceControl* const ctrl = reinterpret_cast<SurfaceControl *>(nativeObject);
1051 
1052     float* floatColors = env->GetFloatArrayElements(fColor, 0);
1053     half3 color(floatColors[0], floatColors[1], floatColors[2]);
1054     transaction->setColor(ctrl, color);
1055     env->ReleaseFloatArrayElements(fColor, floatColors, 0);
1056 }
1057 
nativeSetMatrix(JNIEnv * env,jclass clazz,jlong transactionObj,jlong nativeObject,jfloat dsdx,jfloat dtdx,jfloat dtdy,jfloat dsdy)1058 static void nativeSetMatrix(JNIEnv* env, jclass clazz, jlong transactionObj,
1059         jlong nativeObject,
1060         jfloat dsdx, jfloat dtdx, jfloat dtdy, jfloat dsdy) {
1061     auto transaction = reinterpret_cast<SurfaceComposerClient::Transaction*>(transactionObj);
1062 
1063     SurfaceControl* const ctrl = reinterpret_cast<SurfaceControl *>(nativeObject);
1064     transaction->setMatrix(ctrl, dsdx, dtdx, dtdy, dsdy);
1065 }
1066 
nativeSetColorTransform(JNIEnv * env,jclass clazz,jlong transactionObj,jlong nativeObject,jfloatArray fMatrix,jfloatArray fTranslation)1067 static void nativeSetColorTransform(JNIEnv* env, jclass clazz, jlong transactionObj,
1068         jlong nativeObject, jfloatArray fMatrix, jfloatArray fTranslation) {
1069     auto transaction = reinterpret_cast<SurfaceComposerClient::Transaction*>(transactionObj);
1070     SurfaceControl* const surfaceControl = reinterpret_cast<SurfaceControl*>(nativeObject);
1071     float* floatMatrix = env->GetFloatArrayElements(fMatrix, 0);
1072     mat3 matrix(static_cast<float const*>(floatMatrix));
1073     env->ReleaseFloatArrayElements(fMatrix, floatMatrix, 0);
1074 
1075     float* floatTranslation = env->GetFloatArrayElements(fTranslation, 0);
1076     vec3 translation(floatTranslation[0], floatTranslation[1], floatTranslation[2]);
1077     env->ReleaseFloatArrayElements(fTranslation, floatTranslation, 0);
1078 
1079     transaction->setColorTransform(surfaceControl, matrix, translation);
1080 }
1081 
nativeSetColorSpaceAgnostic(JNIEnv * env,jclass clazz,jlong transactionObj,jlong nativeObject,jboolean agnostic)1082 static void nativeSetColorSpaceAgnostic(JNIEnv* env, jclass clazz, jlong transactionObj,
1083         jlong nativeObject, jboolean agnostic) {
1084     auto transaction = reinterpret_cast<SurfaceComposerClient::Transaction*>(transactionObj);
1085     SurfaceControl* const surfaceControl = reinterpret_cast<SurfaceControl*>(nativeObject);
1086     transaction->setColorSpaceAgnostic(surfaceControl, agnostic);
1087 }
1088 
nativeSetWindowCrop(JNIEnv * env,jclass clazz,jlong transactionObj,jlong nativeObject,jint l,jint t,jint r,jint b)1089 static void nativeSetWindowCrop(JNIEnv* env, jclass clazz, jlong transactionObj,
1090         jlong nativeObject,
1091         jint l, jint t, jint r, jint b) {
1092     auto transaction = reinterpret_cast<SurfaceComposerClient::Transaction*>(transactionObj);
1093 
1094     SurfaceControl* const ctrl = reinterpret_cast<SurfaceControl *>(nativeObject);
1095     Rect crop(l, t, r, b);
1096     transaction->setCrop(ctrl, crop);
1097 }
1098 
nativeSetCrop(JNIEnv * env,jclass clazz,jlong transactionObj,jlong nativeObject,jfloat l,jfloat t,jfloat r,jfloat b)1099 static void nativeSetCrop(JNIEnv* env, jclass clazz, jlong transactionObj, jlong nativeObject,
1100                           jfloat l, jfloat t, jfloat r, jfloat b) {
1101     auto transaction = reinterpret_cast<SurfaceComposerClient::Transaction*>(transactionObj);
1102 
1103     SurfaceControl* const ctrl = reinterpret_cast<SurfaceControl*>(nativeObject);
1104     FloatRect crop(l, t, r, b);
1105     transaction->setCrop(ctrl, crop);
1106 }
1107 
nativeSetCornerRadius(JNIEnv * env,jclass clazz,jlong transactionObj,jlong nativeObject,jfloat cornerRadius)1108 static void nativeSetCornerRadius(JNIEnv* env, jclass clazz, jlong transactionObj,
1109          jlong nativeObject, jfloat cornerRadius) {
1110     auto transaction = reinterpret_cast<SurfaceComposerClient::Transaction*>(transactionObj);
1111 
1112     SurfaceControl* const ctrl = reinterpret_cast<SurfaceControl *>(nativeObject);
1113     transaction->setCornerRadius(ctrl, cornerRadius);
1114 }
1115 
nativeSetBackgroundBlurRadius(JNIEnv * env,jclass clazz,jlong transactionObj,jlong nativeObject,jint blurRadius)1116 static void nativeSetBackgroundBlurRadius(JNIEnv* env, jclass clazz, jlong transactionObj,
1117          jlong nativeObject, jint blurRadius) {
1118     auto transaction = reinterpret_cast<SurfaceComposerClient::Transaction*>(transactionObj);
1119 
1120     SurfaceControl* const ctrl = reinterpret_cast<SurfaceControl *>(nativeObject);
1121     transaction->setBackgroundBlurRadius(ctrl, blurRadius);
1122 }
1123 
nativeSetLayerStack(JNIEnv * env,jclass clazz,jlong transactionObj,jlong nativeObject,jint layerStack)1124 static void nativeSetLayerStack(JNIEnv* env, jclass clazz, jlong transactionObj,
1125         jlong nativeObject, jint layerStack) {
1126     auto transaction = reinterpret_cast<SurfaceComposerClient::Transaction*>(transactionObj);
1127 
1128     SurfaceControl* const ctrl = reinterpret_cast<SurfaceControl *>(nativeObject);
1129     transaction->setLayerStack(ctrl, ui::LayerStack::fromValue(layerStack));
1130 }
1131 
nativeSetShadowRadius(JNIEnv * env,jclass clazz,jlong transactionObj,jlong nativeObject,jfloat shadowRadius)1132 static void nativeSetShadowRadius(JNIEnv* env, jclass clazz, jlong transactionObj,
1133          jlong nativeObject, jfloat shadowRadius) {
1134     auto transaction = reinterpret_cast<SurfaceComposerClient::Transaction*>(transactionObj);
1135 
1136     const auto ctrl = reinterpret_cast<SurfaceControl *>(nativeObject);
1137     transaction->setShadowRadius(ctrl, shadowRadius);
1138 }
1139 
nativeSetTrustedOverlay(JNIEnv * env,jclass clazz,jlong transactionObj,jlong nativeObject,jint trustedOverlay)1140 static void nativeSetTrustedOverlay(JNIEnv* env, jclass clazz, jlong transactionObj,
1141                                     jlong nativeObject, jint trustedOverlay) {
1142     auto transaction = reinterpret_cast<SurfaceComposerClient::Transaction*>(transactionObj);
1143 
1144     SurfaceControl* const ctrl = reinterpret_cast<SurfaceControl *>(nativeObject);
1145     transaction->setTrustedOverlay(ctrl, static_cast<gui::TrustedOverlay>(trustedOverlay));
1146 }
1147 
nativeSetFrameRate(JNIEnv * env,jclass clazz,jlong transactionObj,jlong nativeObject,jfloat frameRate,jint compatibility,jint changeFrameRateStrategy)1148 static void nativeSetFrameRate(JNIEnv* env, jclass clazz, jlong transactionObj, jlong nativeObject,
1149                                jfloat frameRate, jint compatibility, jint changeFrameRateStrategy) {
1150     auto transaction = reinterpret_cast<SurfaceComposerClient::Transaction*>(transactionObj);
1151 
1152     const auto ctrl = reinterpret_cast<SurfaceControl*>(nativeObject);
1153     // Our compatibility is a Surface.FRAME_RATE_COMPATIBILITY_* value, and
1154     // Transaction::setFrameRate() takes an ANATIVEWINDOW_FRAME_RATE_COMPATIBILITY_* value. The
1155     // values are identical though, so no need to convert anything.
1156     transaction->setFrameRate(ctrl, frameRate, static_cast<int8_t>(compatibility),
1157                               static_cast<int8_t>(changeFrameRateStrategy));
1158 }
1159 
nativeSetDefaultFrameRateCompatibility(JNIEnv * env,jclass clazz,jlong transactionObj,jlong nativeObject,jint compatibility)1160 static void nativeSetDefaultFrameRateCompatibility(JNIEnv* env, jclass clazz, jlong transactionObj,
1161                                                    jlong nativeObject, jint compatibility) {
1162     auto transaction = reinterpret_cast<SurfaceComposerClient::Transaction*>(transactionObj);
1163 
1164     const auto ctrl = reinterpret_cast<SurfaceControl*>(nativeObject);
1165 
1166     transaction->setDefaultFrameRateCompatibility(ctrl, static_cast<int8_t>(compatibility));
1167 }
1168 
nativeSetFrameRateCategory(JNIEnv * env,jclass clazz,jlong transactionObj,jlong nativeObject,jint category,jboolean smoothSwitchOnly)1169 static void nativeSetFrameRateCategory(JNIEnv* env, jclass clazz, jlong transactionObj,
1170                                        jlong nativeObject, jint category,
1171                                        jboolean smoothSwitchOnly) {
1172     auto transaction = reinterpret_cast<SurfaceComposerClient::Transaction*>(transactionObj);
1173     const auto ctrl = reinterpret_cast<SurfaceControl*>(nativeObject);
1174     transaction->setFrameRateCategory(ctrl, static_cast<int8_t>(category), smoothSwitchOnly);
1175 }
1176 
nativeSetFrameRateSelectionStrategy(JNIEnv * env,jclass clazz,jlong transactionObj,jlong nativeObject,jint strategy)1177 static void nativeSetFrameRateSelectionStrategy(JNIEnv* env, jclass clazz, jlong transactionObj,
1178                                                 jlong nativeObject, jint strategy) {
1179     auto transaction = reinterpret_cast<SurfaceComposerClient::Transaction*>(transactionObj);
1180     const auto ctrl = reinterpret_cast<SurfaceControl*>(nativeObject);
1181     transaction->setFrameRateSelectionStrategy(ctrl, static_cast<int8_t>(strategy));
1182 }
1183 
nativeSetFixedTransformHint(JNIEnv * env,jclass clazz,jlong transactionObj,jlong nativeObject,jint transformHint)1184 static void nativeSetFixedTransformHint(JNIEnv* env, jclass clazz, jlong transactionObj,
1185                                         jlong nativeObject, jint transformHint) {
1186     auto transaction = reinterpret_cast<SurfaceComposerClient::Transaction*>(transactionObj);
1187 
1188     SurfaceControl* const ctrl = reinterpret_cast<SurfaceControl*>(nativeObject);
1189     transaction->setFixedTransformHint(ctrl, transformHint);
1190 }
1191 
nativeSetDropInputMode(JNIEnv * env,jclass clazz,jlong transactionObj,jlong nativeObject,jint mode)1192 static void nativeSetDropInputMode(JNIEnv* env, jclass clazz, jlong transactionObj,
1193                                    jlong nativeObject, jint mode) {
1194     auto transaction = reinterpret_cast<SurfaceComposerClient::Transaction*>(transactionObj);
1195     SurfaceControl* const ctrl = reinterpret_cast<SurfaceControl*>(nativeObject);
1196     transaction->setDropInputMode(ctrl, static_cast<gui::DropInputMode>(mode));
1197 }
1198 
nativeSurfaceFlushJankData(JNIEnv * env,jclass clazz,jlong nativeObject)1199 static void nativeSurfaceFlushJankData(JNIEnv* env, jclass clazz, jlong nativeObject) {
1200     SurfaceControl* const ctrl = reinterpret_cast<SurfaceControl*>(nativeObject);
1201     SurfaceComposerClient::Transaction::sendSurfaceFlushJankDataTransaction(ctrl);
1202 }
1203 
nativeSanitize(JNIEnv * env,jclass clazz,jlong transactionObj,jint pid,jint uid)1204 static void nativeSanitize(JNIEnv* env, jclass clazz, jlong transactionObj, jint pid, jint uid) {
1205     auto transaction = reinterpret_cast<SurfaceComposerClient::Transaction*>(transactionObj);
1206     transaction->sanitize(pid, uid);
1207 }
1208 
nativeSetDestinationFrame(JNIEnv * env,jclass clazz,jlong transactionObj,jlong nativeObject,jint l,jint t,jint r,jint b)1209 static void nativeSetDestinationFrame(JNIEnv* env, jclass clazz, jlong transactionObj,
1210                                       jlong nativeObject, jint l, jint t, jint r, jint b) {
1211     auto transaction = reinterpret_cast<SurfaceComposerClient::Transaction*>(transactionObj);
1212     SurfaceControl* const ctrl = reinterpret_cast<SurfaceControl*>(nativeObject);
1213     Rect crop(l, t, r, b);
1214     transaction->setDestinationFrame(ctrl, crop);
1215 }
1216 
nativeGetDisplayedContentSamplingAttributes(JNIEnv * env,jclass clazz,jobject tokenObj)1217 static jobject nativeGetDisplayedContentSamplingAttributes(JNIEnv* env, jclass clazz,
1218         jobject tokenObj) {
1219     sp<IBinder> token(ibinderForJavaObject(env, tokenObj));
1220 
1221     ui::PixelFormat format;
1222     ui::Dataspace dataspace;
1223     uint8_t componentMask;
1224     status_t err = SurfaceComposerClient::getDisplayedContentSamplingAttributes(
1225             token, &format, &dataspace, &componentMask);
1226     if (err != OK) {
1227         return nullptr;
1228     }
1229     return env->NewObject(gDisplayedContentSamplingAttributesClassInfo.clazz,
1230                           gDisplayedContentSamplingAttributesClassInfo.ctor,
1231                           format, dataspace, componentMask);
1232 }
1233 
nativeSetDisplayedContentSamplingEnabled(JNIEnv * env,jclass clazz,jobject tokenObj,jboolean enable,jint componentMask,jint maxFrames)1234 static jboolean nativeSetDisplayedContentSamplingEnabled(JNIEnv* env, jclass clazz,
1235         jobject tokenObj, jboolean enable, jint componentMask, jint maxFrames) {
1236     sp<IBinder> token(ibinderForJavaObject(env, tokenObj));
1237     status_t rc = SurfaceComposerClient::setDisplayContentSamplingEnabled(
1238             token, enable, componentMask, maxFrames);
1239     return rc == OK;
1240 }
1241 
nativeGetDisplayedContentSample(JNIEnv * env,jclass clazz,jobject tokenObj,jlong maxFrames,jlong timestamp)1242 static jobject nativeGetDisplayedContentSample(JNIEnv* env, jclass clazz, jobject tokenObj,
1243     jlong maxFrames, jlong timestamp) {
1244     sp<IBinder> token(ibinderForJavaObject(env, tokenObj));
1245 
1246     DisplayedFrameStats stats;
1247     status_t err = SurfaceComposerClient::getDisplayedContentSample(
1248             token, maxFrames, timestamp, &stats);
1249     if (err != OK) {
1250         return nullptr;
1251     }
1252 
1253     jlongArray histogramComponent0 = env->NewLongArray(stats.component_0_sample.size());
1254     jlongArray histogramComponent1 = env->NewLongArray(stats.component_1_sample.size());
1255     jlongArray histogramComponent2 = env->NewLongArray(stats.component_2_sample.size());
1256     jlongArray histogramComponent3 = env->NewLongArray(stats.component_3_sample.size());
1257     if ((histogramComponent0 == nullptr) ||
1258         (histogramComponent1 == nullptr) ||
1259         (histogramComponent2 == nullptr) ||
1260         (histogramComponent3 == nullptr)) {
1261         return JNI_FALSE;
1262     }
1263 
1264     env->SetLongArrayRegion(histogramComponent0, 0,
1265             stats.component_0_sample.size(),
1266             reinterpret_cast<jlong*>(stats.component_0_sample.data()));
1267     env->SetLongArrayRegion(histogramComponent1, 0,
1268             stats.component_1_sample.size(),
1269             reinterpret_cast<jlong*>(stats.component_1_sample.data()));
1270     env->SetLongArrayRegion(histogramComponent2, 0,
1271             stats.component_2_sample.size(),
1272             reinterpret_cast<jlong*>(stats.component_2_sample.data()));
1273     env->SetLongArrayRegion(histogramComponent3, 0,
1274             stats.component_3_sample.size(),
1275             reinterpret_cast<jlong*>(stats.component_3_sample.data()));
1276     return env->NewObject(gDisplayedContentSampleClassInfo.clazz,
1277                           gDisplayedContentSampleClassInfo.ctor,
1278                           stats.numFrames,
1279                           histogramComponent0,
1280                           histogramComponent1,
1281                           histogramComponent2,
1282                           histogramComponent3);
1283 }
1284 
nativeSetDisplaySurface(JNIEnv * env,jclass clazz,jlong transactionObj,jobject tokenObj,jlong nativeSurfaceObject)1285 static void nativeSetDisplaySurface(JNIEnv* env, jclass clazz,
1286         jlong transactionObj,
1287         jobject tokenObj, jlong nativeSurfaceObject) {
1288     sp<IBinder> token(ibinderForJavaObject(env, tokenObj));
1289     if (token == NULL) return;
1290     sp<IGraphicBufferProducer> bufferProducer;
1291     sp<Surface> sur(reinterpret_cast<Surface *>(nativeSurfaceObject));
1292     if (sur != NULL) {
1293         bufferProducer = sur->getIGraphicBufferProducer();
1294     }
1295 
1296 
1297     status_t err = NO_ERROR;
1298     {
1299         auto transaction = reinterpret_cast<SurfaceComposerClient::Transaction*>(transactionObj);
1300         err = transaction->setDisplaySurface(token,
1301                 bufferProducer);
1302     }
1303     if (err != NO_ERROR) {
1304         doThrowIAE(env, "Illegal Surface, could not enable async mode. Was this"
1305                 " Surface created with singleBufferMode?");
1306     }
1307 }
1308 
nativeSetDisplayLayerStack(JNIEnv * env,jclass clazz,jlong transactionObj,jobject tokenObj,jint layerStack)1309 static void nativeSetDisplayLayerStack(JNIEnv* env, jclass clazz,
1310         jlong transactionObj,
1311         jobject tokenObj, jint layerStack) {
1312 
1313     sp<IBinder> token(ibinderForJavaObject(env, tokenObj));
1314     if (token == NULL) return;
1315 
1316     {
1317         auto transaction = reinterpret_cast<SurfaceComposerClient::Transaction*>(transactionObj);
1318         transaction->setDisplayLayerStack(token, ui::LayerStack::fromValue(layerStack));
1319     }
1320 }
1321 
nativeSetDisplayFlags(JNIEnv * env,jclass clazz,jlong transactionObj,jobject tokenObj,jint flags)1322 static void nativeSetDisplayFlags(JNIEnv* env, jclass clazz, jlong transactionObj, jobject tokenObj,
1323                                   jint flags) {
1324     sp<IBinder> token(ibinderForJavaObject(env, tokenObj));
1325     if (token == NULL) return;
1326 
1327     {
1328         auto transaction = reinterpret_cast<SurfaceComposerClient::Transaction*>(transactionObj);
1329         transaction->setDisplayFlags(token, flags);
1330     }
1331 }
1332 
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)1333 static void nativeSetDisplayProjection(JNIEnv* env, jclass clazz,
1334         jlong transactionObj,
1335         jobject tokenObj, jint orientation,
1336         jint layerStackRect_left, jint layerStackRect_top, jint layerStackRect_right, jint layerStackRect_bottom,
1337         jint displayRect_left, jint displayRect_top, jint displayRect_right, jint displayRect_bottom) {
1338     sp<IBinder> token(ibinderForJavaObject(env, tokenObj));
1339     if (token == NULL) return;
1340     Rect layerStackRect(layerStackRect_left, layerStackRect_top, layerStackRect_right, layerStackRect_bottom);
1341     Rect displayRect(displayRect_left, displayRect_top, displayRect_right, displayRect_bottom);
1342 
1343     {
1344         auto transaction = reinterpret_cast<SurfaceComposerClient::Transaction*>(transactionObj);
1345         transaction->setDisplayProjection(token, static_cast<ui::Rotation>(orientation),
1346                                           layerStackRect, displayRect);
1347     }
1348 }
1349 
nativeSetDisplaySize(JNIEnv * env,jclass clazz,jlong transactionObj,jobject tokenObj,jint width,jint height)1350 static void nativeSetDisplaySize(JNIEnv* env, jclass clazz,
1351         jlong transactionObj,
1352         jobject tokenObj, jint width, jint height) {
1353     sp<IBinder> token(ibinderForJavaObject(env, tokenObj));
1354     if (token == NULL) return;
1355 
1356     {
1357         auto transaction = reinterpret_cast<SurfaceComposerClient::Transaction*>(transactionObj);
1358         transaction->setDisplaySize(token, width, height);
1359     }
1360 }
1361 
convertDeviceProductInfoToJavaObject(JNIEnv * env,const std::optional<DeviceProductInfo> & info,bool isInternal)1362 static jobject convertDeviceProductInfoToJavaObject(JNIEnv* env,
1363                                                     const std::optional<DeviceProductInfo>& info,
1364                                                     bool isInternal) {
1365     using ModelYear = android::DeviceProductInfo::ModelYear;
1366     using ManufactureYear = android::DeviceProductInfo::ManufactureYear;
1367     using ManufactureWeekAndYear = android::DeviceProductInfo::ManufactureWeekAndYear;
1368 
1369     if (!info) return nullptr;
1370     jstring name = env->NewStringUTF(info->name.data());
1371     jstring manufacturerPnpId = env->NewStringUTF(info->manufacturerPnpId.data());
1372     jobject productId = env->NewStringUTF(info->productId.data());
1373     const auto& date = info->manufactureOrModelDate;
1374     jobject modelYear, manufactureDate;
1375     if (const auto* model = std::get_if<ModelYear>(&date)) {
1376         modelYear = toInteger(env, model->year);
1377         manufactureDate = nullptr;
1378     } else if (const auto* manufactureWeekAndYear = std::get_if<ManufactureWeekAndYear>(&date)) {
1379         modelYear = nullptr;
1380         manufactureDate = env->NewObject(gDeviceProductInfoManufactureDateClassInfo.clazz,
1381                                                gDeviceProductInfoManufactureDateClassInfo.ctor,
1382                                                toInteger(env, manufactureWeekAndYear->week),
1383                                                toInteger(env, manufactureWeekAndYear->year));
1384     } else if (const auto* manufactureYear = std::get_if<ManufactureYear>(&date)) {
1385         modelYear = nullptr;
1386         manufactureDate = env->NewObject(gDeviceProductInfoManufactureDateClassInfo.clazz,
1387                                        gDeviceProductInfoManufactureDateClassInfo.ctor,
1388                                        nullptr,
1389                                        toInteger(env, manufactureYear->year));
1390     } else {
1391         LOG_FATAL("Unknown alternative for variant DeviceProductInfo::ManufactureOrModelDate");
1392     }
1393     jint connectionToSinkType;
1394     // Relative address maps to HDMI physical address. All addresses are 4 digits long allowing
1395     // for a 5–device-deep hierarchy. For more information, refer:
1396     // Section 8.7 - Physical Address of HDMI Specification Version 1.3a
1397     using android::hardware::display::IDeviceProductInfoConstants;
1398     if (info->relativeAddress.size() != 4) {
1399         connectionToSinkType = isInternal ? IDeviceProductInfoConstants::CONNECTION_TO_SINK_BUILT_IN
1400                                           : IDeviceProductInfoConstants::CONNECTION_TO_SINK_UNKNOWN;
1401     } else if (info->relativeAddress[0] == 0) {
1402         connectionToSinkType = IDeviceProductInfoConstants::CONNECTION_TO_SINK_BUILT_IN;
1403     } else if (info->relativeAddress[1] == 0) {
1404         connectionToSinkType = IDeviceProductInfoConstants::CONNECTION_TO_SINK_DIRECT;
1405     } else {
1406         connectionToSinkType = IDeviceProductInfoConstants::CONNECTION_TO_SINK_TRANSITIVE;
1407     }
1408 
1409     return env->NewObject(gDeviceProductInfoClassInfo.clazz, gDeviceProductInfoClassInfo.ctor, name,
1410                           manufacturerPnpId, productId, modelYear, manufactureDate,
1411                           connectionToSinkType);
1412 }
1413 
nativeGetStaticDisplayInfo(JNIEnv * env,jclass clazz,jlong id)1414 static jobject nativeGetStaticDisplayInfo(JNIEnv* env, jclass clazz, jlong id) {
1415     ui::StaticDisplayInfo info;
1416     if (SurfaceComposerClient::getStaticDisplayInfo(id, &info) != NO_ERROR) {
1417         return nullptr;
1418     }
1419 
1420     jobject object =
1421             env->NewObject(gStaticDisplayInfoClassInfo.clazz, gStaticDisplayInfoClassInfo.ctor);
1422 
1423     const bool isInternal = info.connectionType == ui::DisplayConnectionType::Internal;
1424     env->SetBooleanField(object, gStaticDisplayInfoClassInfo.isInternal, isInternal);
1425     env->SetFloatField(object, gStaticDisplayInfoClassInfo.density, info.density);
1426     env->SetBooleanField(object, gStaticDisplayInfoClassInfo.secure, info.secure);
1427     env->SetObjectField(object, gStaticDisplayInfoClassInfo.deviceProductInfo,
1428                         convertDeviceProductInfoToJavaObject(env, info.deviceProductInfo,
1429                                                              isInternal));
1430     env->SetIntField(object, gStaticDisplayInfoClassInfo.installOrientation,
1431                      static_cast<uint32_t>(info.installOrientation));
1432     return object;
1433 }
1434 
convertFrameRateCategoryRateToJavaObject(JNIEnv * env,const ui::FrameRateCategoryRate & frameRateCategoryRate)1435 static jobject convertFrameRateCategoryRateToJavaObject(
1436         JNIEnv* env, const ui::FrameRateCategoryRate& frameRateCategoryRate) {
1437     return env->NewObject(gFrameRateCategoryRateClassInfo.clazz,
1438                           gFrameRateCategoryRateClassInfo.ctor, frameRateCategoryRate.getNormal(),
1439                           frameRateCategoryRate.getHigh());
1440 }
1441 
convertDisplayModeToJavaObject(JNIEnv * env,const ui::DisplayMode & config)1442 static jobject convertDisplayModeToJavaObject(JNIEnv* env, const ui::DisplayMode& config) {
1443     jobject object = env->NewObject(gDisplayModeClassInfo.clazz, gDisplayModeClassInfo.ctor);
1444     env->SetIntField(object, gDisplayModeClassInfo.id, config.id);
1445     env->SetIntField(object, gDisplayModeClassInfo.width, config.resolution.getWidth());
1446     env->SetIntField(object, gDisplayModeClassInfo.height, config.resolution.getHeight());
1447     env->SetFloatField(object, gDisplayModeClassInfo.xDpi, config.xDpi);
1448     env->SetFloatField(object, gDisplayModeClassInfo.yDpi, config.yDpi);
1449 
1450     env->SetFloatField(object, gDisplayModeClassInfo.peakRefreshRate, config.peakRefreshRate);
1451     env->SetFloatField(object, gDisplayModeClassInfo.vsyncRate, config.vsyncRate);
1452     env->SetLongField(object, gDisplayModeClassInfo.appVsyncOffsetNanos, config.appVsyncOffset);
1453     env->SetLongField(object, gDisplayModeClassInfo.presentationDeadlineNanos,
1454                       config.presentationDeadline);
1455     env->SetIntField(object, gDisplayModeClassInfo.group, config.group);
1456 
1457     const auto& types = config.supportedHdrTypes;
1458     std::vector<jint> intTypes;
1459     for (auto type : types) {
1460         intTypes.push_back(static_cast<jint>(type));
1461     }
1462     auto typesArray = env->NewIntArray(types.size());
1463     env->SetIntArrayRegion(typesArray, 0, intTypes.size(), intTypes.data());
1464     env->SetObjectField(object, gDisplayModeClassInfo.supportedHdrTypes, typesArray);
1465 
1466     return object;
1467 }
1468 
convertHdrCapabilitiesToJavaObject(JNIEnv * env,const HdrCapabilities & capabilities)1469 jobject convertHdrCapabilitiesToJavaObject(JNIEnv* env, const HdrCapabilities& capabilities) {
1470     const auto& types = capabilities.getSupportedHdrTypes();
1471     std::vector<int32_t> intTypes;
1472     for (auto type : types) {
1473         intTypes.push_back(static_cast<int32_t>(type));
1474     }
1475     auto typesArray = env->NewIntArray(types.size());
1476     env->SetIntArrayRegion(typesArray, 0, intTypes.size(), intTypes.data());
1477 
1478     return env->NewObject(gHdrCapabilitiesClassInfo.clazz, gHdrCapabilitiesClassInfo.ctor,
1479                           typesArray, capabilities.getDesiredMaxLuminance(),
1480                           capabilities.getDesiredMaxAverageLuminance(),
1481                           capabilities.getDesiredMinLuminance());
1482 }
1483 
nativeGetDynamicDisplayInfo(JNIEnv * env,jclass clazz,jlong displayId)1484 static jobject nativeGetDynamicDisplayInfo(JNIEnv* env, jclass clazz, jlong displayId) {
1485     ui::DynamicDisplayInfo info;
1486     if (SurfaceComposerClient::getDynamicDisplayInfoFromId(displayId, &info) != NO_ERROR) {
1487         return nullptr;
1488     }
1489 
1490     jobject object =
1491             env->NewObject(gDynamicDisplayInfoClassInfo.clazz, gDynamicDisplayInfoClassInfo.ctor);
1492     if (object == NULL) {
1493         jniThrowException(env, "java/lang/OutOfMemoryError", NULL);
1494         return NULL;
1495     }
1496 
1497     const auto numModes = info.supportedDisplayModes.size();
1498     jobjectArray modesArray = env->NewObjectArray(numModes, gDisplayModeClassInfo.clazz, nullptr);
1499     for (size_t i = 0; i < numModes; i++) {
1500         const ui::DisplayMode& mode = info.supportedDisplayModes[i];
1501         jobject displayModeObj = convertDisplayModeToJavaObject(env, mode);
1502         env->SetObjectArrayElement(modesArray, static_cast<jsize>(i), displayModeObj);
1503         env->DeleteLocalRef(displayModeObj);
1504     }
1505     env->SetObjectField(object, gDynamicDisplayInfoClassInfo.supportedDisplayModes, modesArray);
1506     env->SetIntField(object, gDynamicDisplayInfoClassInfo.activeDisplayModeId,
1507                      info.activeDisplayModeId);
1508     env->SetFloatField(object, gDynamicDisplayInfoClassInfo.renderFrameRate, info.renderFrameRate);
1509     env->SetBooleanField(object, gDynamicDisplayInfoClassInfo.hasArrSupport, info.hasArrSupport);
1510     env->SetObjectField(object, gDynamicDisplayInfoClassInfo.frameRateCategoryRate,
1511                         convertFrameRateCategoryRateToJavaObject(env, info.frameRateCategoryRate));
1512 
1513     jfloatArray supportedRefreshRatesArray = env->NewFloatArray(info.supportedRefreshRates.size());
1514     if (supportedRefreshRatesArray == NULL) {
1515         jniThrowException(env, "java/lang/OutOfMemoryError", NULL);
1516         return NULL;
1517     }
1518     jfloat* supportedRefreshRatesArrayValues =
1519             env->GetFloatArrayElements(supportedRefreshRatesArray, 0);
1520     for (size_t i = 0; i < info.supportedRefreshRates.size(); i++) {
1521         supportedRefreshRatesArrayValues[i] = static_cast<jfloat>(info.supportedRefreshRates[i]);
1522     }
1523     env->ReleaseFloatArrayElements(supportedRefreshRatesArray, supportedRefreshRatesArrayValues, 0);
1524     env->SetObjectField(object, gDynamicDisplayInfoClassInfo.supportedRefreshRates,
1525                         supportedRefreshRatesArray);
1526 
1527     jintArray colorModesArray = env->NewIntArray(info.supportedColorModes.size());
1528     if (colorModesArray == NULL) {
1529         jniThrowException(env, "java/lang/OutOfMemoryError", NULL);
1530         return NULL;
1531     }
1532     jint* colorModesArrayValues = env->GetIntArrayElements(colorModesArray, 0);
1533     for (size_t i = 0; i < info.supportedColorModes.size(); i++) {
1534         colorModesArrayValues[i] = static_cast<jint>(info.supportedColorModes[i]);
1535     }
1536     env->ReleaseIntArrayElements(colorModesArray, colorModesArrayValues, 0);
1537     env->SetObjectField(object, gDynamicDisplayInfoClassInfo.supportedColorModes, colorModesArray);
1538 
1539     env->SetIntField(object, gDynamicDisplayInfoClassInfo.activeColorMode,
1540                      static_cast<jint>(info.activeColorMode));
1541 
1542     env->SetObjectField(object, gDynamicDisplayInfoClassInfo.hdrCapabilities,
1543                         convertHdrCapabilitiesToJavaObject(env, info.hdrCapabilities));
1544 
1545     env->SetBooleanField(object, gDynamicDisplayInfoClassInfo.autoLowLatencyModeSupported,
1546                          info.autoLowLatencyModeSupported);
1547 
1548     env->SetBooleanField(object, gDynamicDisplayInfoClassInfo.gameContentTypeSupported,
1549                          info.gameContentTypeSupported);
1550 
1551     env->SetIntField(object, gDynamicDisplayInfoClassInfo.preferredBootDisplayMode,
1552                      info.preferredBootDisplayMode);
1553     return object;
1554 }
1555 
nativeSetDesiredDisplayModeSpecs(JNIEnv * env,jclass clazz,jobject tokenObj,jobject DesiredDisplayModeSpecs)1556 static jboolean nativeSetDesiredDisplayModeSpecs(JNIEnv* env, jclass clazz, jobject tokenObj,
1557                                                  jobject DesiredDisplayModeSpecs) {
1558     sp<IBinder> token(ibinderForJavaObject(env, tokenObj));
1559     if (token == nullptr) return JNI_FALSE;
1560 
1561     const auto makeRanges = [env](jobject obj) {
1562         const auto makeRange = [env](jobject obj) {
1563             gui::DisplayModeSpecs::RefreshRateRanges::RefreshRateRange range;
1564             range.min = env->GetFloatField(obj, gRefreshRateRangeClassInfo.min);
1565             range.max = env->GetFloatField(obj, gRefreshRateRangeClassInfo.max);
1566             return range;
1567         };
1568 
1569         gui::DisplayModeSpecs::RefreshRateRanges ranges;
1570         ranges.physical = makeRange(env->GetObjectField(obj, gRefreshRateRangesClassInfo.physical));
1571         ranges.render = makeRange(env->GetObjectField(obj, gRefreshRateRangesClassInfo.render));
1572         return ranges;
1573     };
1574 
1575     const auto makeIdleScreenRefreshRateConfig = [env](jobject obj)
1576             -> std::optional<gui::DisplayModeSpecs::IdleScreenRefreshRateConfig> {
1577         if (obj == NULL) {
1578             return std::nullopt;
1579         }
1580         gui::DisplayModeSpecs::IdleScreenRefreshRateConfig idleScreenRefreshRateConfig;
1581         idleScreenRefreshRateConfig.timeoutMillis =
1582                 env->GetIntField(obj, gIdleScreenRefreshRateConfigClassInfo.timeoutMillis);
1583 
1584         return idleScreenRefreshRateConfig;
1585     };
1586 
1587     gui::DisplayModeSpecs specs;
1588     specs.defaultMode = env->GetIntField(DesiredDisplayModeSpecs,
1589                                          gDesiredDisplayModeSpecsClassInfo.defaultMode);
1590     specs.allowGroupSwitching =
1591             env->GetBooleanField(DesiredDisplayModeSpecs,
1592                                  gDesiredDisplayModeSpecsClassInfo.allowGroupSwitching);
1593 
1594     specs.primaryRanges =
1595             makeRanges(env->GetObjectField(DesiredDisplayModeSpecs,
1596                                            gDesiredDisplayModeSpecsClassInfo.primaryRanges));
1597     specs.appRequestRanges =
1598             makeRanges(env->GetObjectField(DesiredDisplayModeSpecs,
1599                                            gDesiredDisplayModeSpecsClassInfo.appRequestRanges));
1600 
1601     specs.idleScreenRefreshRateConfig = makeIdleScreenRefreshRateConfig(
1602             env->GetObjectField(DesiredDisplayModeSpecs,
1603                                 gDesiredDisplayModeSpecsClassInfo.idleScreenRefreshRateConfig));
1604 
1605     size_t result = SurfaceComposerClient::setDesiredDisplayModeSpecs(token, specs);
1606     return result == NO_ERROR ? JNI_TRUE : JNI_FALSE;
1607 }
1608 
nativeGetDesiredDisplayModeSpecs(JNIEnv * env,jclass clazz,jobject tokenObj)1609 static jobject nativeGetDesiredDisplayModeSpecs(JNIEnv* env, jclass clazz, jobject tokenObj) {
1610     sp<IBinder> token(ibinderForJavaObject(env, tokenObj));
1611     if (token == nullptr) return nullptr;
1612 
1613     const auto rangesToJava = [env](const gui::DisplayModeSpecs::RefreshRateRanges& ranges) {
1614         const auto rangeToJava =
1615                 [env](const gui::DisplayModeSpecs::RefreshRateRanges::RefreshRateRange& range) {
1616                     return env->NewObject(gRefreshRateRangeClassInfo.clazz,
1617                                           gRefreshRateRangeClassInfo.ctor, range.min, range.max);
1618                 };
1619 
1620         return env->NewObject(gRefreshRateRangesClassInfo.clazz, gRefreshRateRangesClassInfo.ctor,
1621                               rangeToJava(ranges.physical), rangeToJava(ranges.render));
1622     };
1623 
1624     const auto idleScreenRefreshRateConfigToJava =
1625             [env](const std::optional<gui::DisplayModeSpecs::IdleScreenRefreshRateConfig>&
1626                           idleScreenRefreshRateConfig) -> jobject {
1627         if (!idleScreenRefreshRateConfig.has_value()) {
1628             return NULL; // Return null if input config is null
1629         }
1630         return env->NewObject(gIdleScreenRefreshRateConfigClassInfo.clazz,
1631                               gIdleScreenRefreshRateConfigClassInfo.ctor,
1632                               idleScreenRefreshRateConfig->timeoutMillis);
1633     };
1634 
1635     gui::DisplayModeSpecs specs;
1636     if (SurfaceComposerClient::getDesiredDisplayModeSpecs(token, &specs) != NO_ERROR) {
1637         return nullptr;
1638     }
1639 
1640     return env->NewObject(gDesiredDisplayModeSpecsClassInfo.clazz,
1641                           gDesiredDisplayModeSpecsClassInfo.ctor, specs.defaultMode,
1642                           specs.allowGroupSwitching, rangesToJava(specs.primaryRanges),
1643                           rangesToJava(specs.appRequestRanges),
1644                           idleScreenRefreshRateConfigToJava(specs.idleScreenRefreshRateConfig));
1645 }
1646 
nativeGetDisplayNativePrimaries(JNIEnv * env,jclass,jobject tokenObj)1647 static jobject nativeGetDisplayNativePrimaries(JNIEnv* env, jclass, jobject tokenObj) {
1648     sp<IBinder> token(ibinderForJavaObject(env, tokenObj));
1649     if (token == NULL) return NULL;
1650 
1651     ui::DisplayPrimaries primaries;
1652     if (SurfaceComposerClient::getDisplayNativePrimaries(token, primaries) != NO_ERROR) {
1653         return NULL;
1654     }
1655 
1656     jobject jred = env->NewObject(gCieXyzClassInfo.clazz, gCieXyzClassInfo.ctor);
1657     if (jred == NULL) {
1658         jniThrowException(env, "java/lang/OutOfMemoryError", NULL);
1659         return NULL;
1660     }
1661 
1662     jobject jgreen = env->NewObject(gCieXyzClassInfo.clazz, gCieXyzClassInfo.ctor);
1663     if (jgreen == NULL) {
1664         jniThrowException(env, "java/lang/OutOfMemoryError", NULL);
1665         return NULL;
1666     }
1667 
1668     jobject jblue = env->NewObject(gCieXyzClassInfo.clazz, gCieXyzClassInfo.ctor);
1669     if (jblue == NULL) {
1670         jniThrowException(env, "java/lang/OutOfMemoryError", NULL);
1671         return NULL;
1672     }
1673 
1674     jobject jwhite = env->NewObject(gCieXyzClassInfo.clazz, gCieXyzClassInfo.ctor);
1675     if (jwhite == NULL) {
1676         jniThrowException(env, "java/lang/OutOfMemoryError", NULL);
1677         return NULL;
1678     }
1679 
1680     jobject jprimaries = env->NewObject(gDisplayPrimariesClassInfo.clazz,
1681             gDisplayPrimariesClassInfo.ctor);
1682     if (jprimaries == NULL) {
1683         jniThrowException(env, "java/lang/OutOfMemoryError", NULL);
1684         return NULL;
1685     }
1686 
1687     env->SetFloatField(jred, gCieXyzClassInfo.X, primaries.red.X);
1688     env->SetFloatField(jred, gCieXyzClassInfo.Y, primaries.red.Y);
1689     env->SetFloatField(jred, gCieXyzClassInfo.Z, primaries.red.Z);
1690     env->SetFloatField(jgreen, gCieXyzClassInfo.X, primaries.green.X);
1691     env->SetFloatField(jgreen, gCieXyzClassInfo.Y, primaries.green.Y);
1692     env->SetFloatField(jgreen, gCieXyzClassInfo.Z, primaries.green.Z);
1693     env->SetFloatField(jblue, gCieXyzClassInfo.X, primaries.blue.X);
1694     env->SetFloatField(jblue, gCieXyzClassInfo.Y, primaries.blue.Y);
1695     env->SetFloatField(jblue, gCieXyzClassInfo.Z, primaries.blue.Z);
1696     env->SetFloatField(jwhite, gCieXyzClassInfo.X, primaries.white.X);
1697     env->SetFloatField(jwhite, gCieXyzClassInfo.Y, primaries.white.Y);
1698     env->SetFloatField(jwhite, gCieXyzClassInfo.Z, primaries.white.Z);
1699     env->SetObjectField(jprimaries, gDisplayPrimariesClassInfo.red, jred);
1700     env->SetObjectField(jprimaries, gDisplayPrimariesClassInfo.green, jgreen);
1701     env->SetObjectField(jprimaries, gDisplayPrimariesClassInfo.blue, jblue);
1702     env->SetObjectField(jprimaries, gDisplayPrimariesClassInfo.white, jwhite);
1703 
1704     return jprimaries;
1705 }
1706 
nativeGetCompositionDataspaces(JNIEnv * env,jclass)1707 static jintArray nativeGetCompositionDataspaces(JNIEnv* env, jclass) {
1708     ui::Dataspace defaultDataspace, wcgDataspace;
1709     ui::PixelFormat defaultPixelFormat, wcgPixelFormat;
1710     if (SurfaceComposerClient::getCompositionPreference(&defaultDataspace,
1711                                                         &defaultPixelFormat,
1712                                                         &wcgDataspace,
1713                                                         &wcgPixelFormat) != NO_ERROR) {
1714         return nullptr;
1715     }
1716     jintArray array = env->NewIntArray(2);
1717     if (array == nullptr) {
1718         jniThrowException(env, "java/lang/OutOfMemoryError", nullptr);
1719         return nullptr;
1720     }
1721     jint* arrayValues = env->GetIntArrayElements(array, 0);
1722     arrayValues[0] = static_cast<jint>(defaultDataspace);
1723     arrayValues[1] = static_cast<jint>(wcgDataspace);
1724     env->ReleaseIntArrayElements(array, arrayValues, 0);
1725     return array;
1726 }
1727 
nativeGetOverlaySupport(JNIEnv * env,jclass)1728 static jobject nativeGetOverlaySupport(JNIEnv* env, jclass) {
1729     gui::OverlayProperties* overlayProperties = new gui::OverlayProperties;
1730     if (SurfaceComposerClient::getOverlaySupport(overlayProperties) != NO_ERROR) {
1731         delete overlayProperties;
1732         return nullptr;
1733     }
1734     return android_hardware_OverlayProperties_convertToJavaObject(env, overlayProperties);
1735 }
1736 
nativeSetActiveColorMode(JNIEnv * env,jclass,jobject tokenObj,jint colorMode)1737 static jboolean nativeSetActiveColorMode(JNIEnv* env, jclass,
1738         jobject tokenObj, jint colorMode) {
1739     sp<IBinder> token(ibinderForJavaObject(env, tokenObj));
1740     if (token == NULL) return JNI_FALSE;
1741     status_t err = SurfaceComposerClient::setActiveColorMode(token,
1742             static_cast<ui::ColorMode>(colorMode));
1743     return err == NO_ERROR ? JNI_TRUE : JNI_FALSE;
1744 }
1745 
nativeSetDisplayPowerMode(JNIEnv * env,jclass clazz,jobject tokenObj,jint mode)1746 static void nativeSetDisplayPowerMode(JNIEnv* env, jclass clazz, jobject tokenObj, jint mode) {
1747     sp<IBinder> token(ibinderForJavaObject(env, tokenObj));
1748     if (token == NULL) return;
1749 
1750     android::base::Timer t;
1751     SurfaceComposerClient::setDisplayPowerMode(token, mode);
1752     if (t.duration() > 100ms) ALOGD("Excessive delay in setPowerMode()");
1753 }
1754 
nativeGetProtectedContentSupport(JNIEnv * env,jclass)1755 static jboolean nativeGetProtectedContentSupport(JNIEnv* env, jclass) {
1756     return static_cast<jboolean>(SurfaceComposerClient::getProtectedContentSupport());
1757 }
1758 
nativeClearContentFrameStats(JNIEnv * env,jclass clazz,jlong nativeObject)1759 static jboolean nativeClearContentFrameStats(JNIEnv* env, jclass clazz, jlong nativeObject) {
1760     SurfaceControl* const ctrl = reinterpret_cast<SurfaceControl *>(nativeObject);
1761     status_t err = ctrl->clearLayerFrameStats();
1762 
1763     if (err < 0 && err != NO_INIT) {
1764         doThrowIAE(env);
1765     }
1766 
1767     // The other end is not ready, just report we failed.
1768     if (err == NO_INIT) {
1769         return JNI_FALSE;
1770     }
1771 
1772     return JNI_TRUE;
1773 }
1774 
nativeGetContentFrameStats(JNIEnv * env,jclass clazz,jlong nativeObject,jobject outStats)1775 static jboolean nativeGetContentFrameStats(JNIEnv* env, jclass clazz, jlong nativeObject,
1776     jobject outStats) {
1777     FrameStats stats;
1778 
1779     SurfaceControl* const ctrl = reinterpret_cast<SurfaceControl *>(nativeObject);
1780     status_t err = ctrl->getLayerFrameStats(&stats);
1781     if (err < 0 && err != NO_INIT) {
1782         doThrowIAE(env);
1783     }
1784 
1785     // The other end is not ready, fine just return empty stats.
1786     if (err == NO_INIT) {
1787         return JNI_FALSE;
1788     }
1789 
1790     jlong refreshPeriodNano = static_cast<jlong>(stats.refreshPeriodNano);
1791     size_t frameCount = stats.desiredPresentTimesNano.size();
1792 
1793     jlongArray postedTimesNanoDst = env->NewLongArray(frameCount);
1794     if (postedTimesNanoDst == NULL) {
1795         return JNI_FALSE;
1796     }
1797 
1798     jlongArray presentedTimesNanoDst = env->NewLongArray(frameCount);
1799     if (presentedTimesNanoDst == NULL) {
1800         return JNI_FALSE;
1801     }
1802 
1803     jlongArray readyTimesNanoDst = env->NewLongArray(frameCount);
1804     if (readyTimesNanoDst == NULL) {
1805         return JNI_FALSE;
1806     }
1807 
1808     nsecs_t postedTimesNanoSrc[frameCount];
1809     nsecs_t presentedTimesNanoSrc[frameCount];
1810     nsecs_t readyTimesNanoSrc[frameCount];
1811 
1812     for (size_t i = 0; i < frameCount; i++) {
1813         nsecs_t postedTimeNano = stats.desiredPresentTimesNano[i];
1814         if (postedTimeNano == INT64_MAX) {
1815             postedTimeNano = gWindowContentFrameStatsClassInfo.UNDEFINED_TIME_NANO;
1816         }
1817         postedTimesNanoSrc[i] = postedTimeNano;
1818 
1819         nsecs_t presentedTimeNano = stats.actualPresentTimesNano[i];
1820         if (presentedTimeNano == INT64_MAX) {
1821             presentedTimeNano = gWindowContentFrameStatsClassInfo.UNDEFINED_TIME_NANO;
1822         }
1823         presentedTimesNanoSrc[i] = presentedTimeNano;
1824 
1825         nsecs_t readyTimeNano = stats.frameReadyTimesNano[i];
1826         if (readyTimeNano == INT64_MAX) {
1827             readyTimeNano = gWindowContentFrameStatsClassInfo.UNDEFINED_TIME_NANO;
1828         }
1829         readyTimesNanoSrc[i] = readyTimeNano;
1830     }
1831 
1832     env->SetLongArrayRegion(postedTimesNanoDst, 0, frameCount, postedTimesNanoSrc);
1833     env->SetLongArrayRegion(presentedTimesNanoDst, 0, frameCount, presentedTimesNanoSrc);
1834     env->SetLongArrayRegion(readyTimesNanoDst, 0, frameCount, readyTimesNanoSrc);
1835 
1836     env->CallVoidMethod(outStats, gWindowContentFrameStatsClassInfo.init, refreshPeriodNano,
1837             postedTimesNanoDst, presentedTimesNanoDst, readyTimesNanoDst);
1838 
1839     if (env->ExceptionCheck()) {
1840         return JNI_FALSE;
1841     }
1842 
1843     return JNI_TRUE;
1844 }
1845 
nativeClearAnimationFrameStats(JNIEnv * env,jclass clazz)1846 static jboolean nativeClearAnimationFrameStats(JNIEnv* env, jclass clazz) {
1847     status_t err = SurfaceComposerClient::clearAnimationFrameStats();
1848 
1849     if (err < 0 && err != NO_INIT) {
1850         doThrowIAE(env);
1851     }
1852 
1853     // The other end is not ready, just report we failed.
1854     if (err == NO_INIT) {
1855         return JNI_FALSE;
1856     }
1857 
1858     return JNI_TRUE;
1859 }
1860 
nativeGetAnimationFrameStats(JNIEnv * env,jclass clazz,jobject outStats)1861 static jboolean nativeGetAnimationFrameStats(JNIEnv* env, jclass clazz, jobject outStats) {
1862     FrameStats stats;
1863 
1864     status_t err = SurfaceComposerClient::getAnimationFrameStats(&stats);
1865     if (err < 0 && err != NO_INIT) {
1866         doThrowIAE(env);
1867     }
1868 
1869     // The other end is not ready, fine just return empty stats.
1870     if (err == NO_INIT) {
1871         return JNI_FALSE;
1872     }
1873 
1874     jlong refreshPeriodNano = static_cast<jlong>(stats.refreshPeriodNano);
1875     size_t frameCount = stats.desiredPresentTimesNano.size();
1876 
1877     jlongArray presentedTimesNanoDst = env->NewLongArray(frameCount);
1878     if (presentedTimesNanoDst == NULL) {
1879         return JNI_FALSE;
1880     }
1881 
1882     nsecs_t presentedTimesNanoSrc[frameCount];
1883 
1884     for (size_t i = 0; i < frameCount; i++) {
1885         nsecs_t presentedTimeNano = stats.actualPresentTimesNano[i];
1886         if (presentedTimeNano == INT64_MAX) {
1887             presentedTimeNano = gWindowContentFrameStatsClassInfo.UNDEFINED_TIME_NANO;
1888         }
1889         presentedTimesNanoSrc[i] = presentedTimeNano;
1890     }
1891 
1892     env->SetLongArrayRegion(presentedTimesNanoDst, 0, frameCount, presentedTimesNanoSrc);
1893 
1894     env->CallVoidMethod(outStats, gWindowAnimationFrameStatsClassInfo.init, refreshPeriodNano,
1895             presentedTimesNanoDst);
1896 
1897     if (env->ExceptionCheck()) {
1898         return JNI_FALSE;
1899     }
1900 
1901     return JNI_TRUE;
1902 }
1903 
nativeReparent(JNIEnv * env,jclass clazz,jlong transactionObj,jlong nativeObject,jlong newParentObject)1904 static void nativeReparent(JNIEnv* env, jclass clazz, jlong transactionObj,
1905         jlong nativeObject,
1906         jlong newParentObject) {
1907     auto ctrl = reinterpret_cast<SurfaceControl *>(nativeObject);
1908     auto newParent = reinterpret_cast<SurfaceControl *>(newParentObject);
1909     auto transaction = reinterpret_cast<SurfaceComposerClient::Transaction*>(transactionObj);
1910     transaction->reparent(ctrl, newParent);
1911 }
1912 
nativeGetBootDisplayModeSupport(JNIEnv * env,jclass clazz)1913 static jboolean nativeGetBootDisplayModeSupport(JNIEnv* env, jclass clazz) {
1914     bool isBootDisplayModeSupported = false;
1915     SurfaceComposerClient::getBootDisplayModeSupport(&isBootDisplayModeSupported);
1916     return static_cast<jboolean>(isBootDisplayModeSupported);
1917 }
1918 
nativeSetBootDisplayMode(JNIEnv * env,jclass clazz,jobject tokenObject,jint displayModId)1919 static void nativeSetBootDisplayMode(JNIEnv* env, jclass clazz, jobject tokenObject,
1920                                      jint displayModId) {
1921     sp<IBinder> token(ibinderForJavaObject(env, tokenObject));
1922     if (token == NULL) return;
1923 
1924     SurfaceComposerClient::setBootDisplayMode(token, displayModId);
1925 }
1926 
nativeClearBootDisplayMode(JNIEnv * env,jclass clazz,jobject tokenObject)1927 static void nativeClearBootDisplayMode(JNIEnv* env, jclass clazz, jobject tokenObject) {
1928     sp<IBinder> token(ibinderForJavaObject(env, tokenObject));
1929     if (token == NULL) return;
1930 
1931     SurfaceComposerClient::clearBootDisplayMode(token);
1932 }
1933 
nativeSetAutoLowLatencyMode(JNIEnv * env,jclass clazz,jobject tokenObject,jboolean on)1934 static void nativeSetAutoLowLatencyMode(JNIEnv* env, jclass clazz, jobject tokenObject, jboolean on) {
1935     sp<IBinder> token(ibinderForJavaObject(env, tokenObject));
1936     if (token == NULL) return;
1937 
1938     SurfaceComposerClient::setAutoLowLatencyMode(token, on);
1939 }
1940 
nativeSetGameContentType(JNIEnv * env,jclass clazz,jobject tokenObject,jboolean on)1941 static void nativeSetGameContentType(JNIEnv* env, jclass clazz, jobject tokenObject, jboolean on) {
1942     sp<IBinder> token(ibinderForJavaObject(env, tokenObject));
1943     if (token == NULL) return;
1944 
1945     SurfaceComposerClient::setGameContentType(token, on);
1946 }
1947 
nativeReadFromParcel(JNIEnv * env,jclass clazz,jobject parcelObj)1948 static jlong nativeReadFromParcel(JNIEnv* env, jclass clazz, jobject parcelObj) {
1949     Parcel* parcel = parcelForJavaObject(env, parcelObj);
1950     if (parcel == NULL) {
1951         doThrowNPE(env);
1952         return 0;
1953     }
1954     sp<SurfaceControl> surface;
1955     SurfaceControl::readFromParcel(*parcel, &surface);
1956     if (surface == nullptr) {
1957         return 0;
1958     }
1959     surface->incStrong((void *)nativeCreate);
1960     return reinterpret_cast<jlong>(surface.get());
1961 }
1962 
nativeCopyFromSurfaceControl(JNIEnv * env,jclass clazz,jlong surfaceControlNativeObj)1963 static jlong nativeCopyFromSurfaceControl(JNIEnv* env, jclass clazz, jlong surfaceControlNativeObj) {
1964     sp<SurfaceControl> surface(reinterpret_cast<SurfaceControl *>(surfaceControlNativeObj));
1965     if (surface == nullptr) {
1966         return 0;
1967     }
1968 
1969     sp<SurfaceControl> newSurface = new SurfaceControl(surface);
1970     newSurface->incStrong((void *)nativeCreate);
1971     return reinterpret_cast<jlong>(newSurface.get());
1972 }
1973 
nativeWriteToParcel(JNIEnv * env,jclass clazz,jlong nativeObject,jobject parcelObj)1974 static void nativeWriteToParcel(JNIEnv* env, jclass clazz,
1975         jlong nativeObject, jobject parcelObj) {
1976     Parcel* parcel = parcelForJavaObject(env, parcelObj);
1977     if (parcel == NULL) {
1978         doThrowNPE(env);
1979         return;
1980     }
1981     SurfaceControl* const self = reinterpret_cast<SurfaceControl *>(nativeObject);
1982     if (self != nullptr) {
1983         self->writeToParcel(*parcel);
1984     }
1985 }
1986 
nativeGetDisplayBrightnessSupport(JNIEnv * env,jclass clazz,jobject displayTokenObject)1987 static jboolean nativeGetDisplayBrightnessSupport(JNIEnv* env, jclass clazz,
1988         jobject displayTokenObject) {
1989     sp<IBinder> displayToken(ibinderForJavaObject(env, displayTokenObject));
1990     if (displayToken == nullptr) {
1991         return JNI_FALSE;
1992     }
1993     return static_cast<jboolean>(SurfaceComposerClient::getDisplayBrightnessSupport(displayToken));
1994 }
1995 
nativeSetDisplayBrightness(JNIEnv * env,jclass clazz,jobject displayTokenObject,jfloat sdrBrightness,jfloat sdrBrightnessNits,jfloat displayBrightness,jfloat displayBrightnessNits)1996 static jboolean nativeSetDisplayBrightness(JNIEnv* env, jclass clazz, jobject displayTokenObject,
1997                                            jfloat sdrBrightness, jfloat sdrBrightnessNits,
1998                                            jfloat displayBrightness, jfloat displayBrightnessNits) {
1999     sp<IBinder> displayToken(ibinderForJavaObject(env, displayTokenObject));
2000     if (displayToken == nullptr) {
2001         return JNI_FALSE;
2002     }
2003     gui::DisplayBrightness brightness;
2004     brightness.sdrWhitePoint = sdrBrightness;
2005     brightness.sdrWhitePointNits = sdrBrightnessNits;
2006     brightness.displayBrightness = displayBrightness;
2007     brightness.displayBrightnessNits = displayBrightnessNits;
2008     status_t error = SurfaceComposerClient::setDisplayBrightness(displayToken, brightness);
2009     return error == OK ? JNI_TRUE : JNI_FALSE;
2010 }
2011 
nativeWriteTransactionToParcel(JNIEnv * env,jclass clazz,jlong nativeObject,jobject parcelObj)2012 static void nativeWriteTransactionToParcel(JNIEnv* env, jclass clazz, jlong nativeObject,
2013         jobject parcelObj) {
2014     Parcel* parcel = parcelForJavaObject(env, parcelObj);
2015     if (parcel == NULL) {
2016         doThrowNPE(env);
2017         return;
2018     }
2019     SurfaceComposerClient::Transaction* const self =
2020             reinterpret_cast<SurfaceComposerClient::Transaction *>(nativeObject);
2021     if (self != nullptr) {
2022         self->writeToParcel(parcel);
2023     }
2024 }
2025 
nativeClearTransaction(JNIEnv * env,jclass clazz,jlong nativeObject)2026 static void nativeClearTransaction(JNIEnv* env, jclass clazz, jlong nativeObject) {
2027     SurfaceComposerClient::Transaction* const self =
2028             reinterpret_cast<SurfaceComposerClient::Transaction*>(nativeObject);
2029     if (self != nullptr) {
2030         self->clear();
2031     }
2032 }
2033 
nativeReadTransactionFromParcel(JNIEnv * env,jclass clazz,jobject parcelObj)2034 static jlong nativeReadTransactionFromParcel(JNIEnv* env, jclass clazz, jobject parcelObj) {
2035     Parcel* parcel = parcelForJavaObject(env, parcelObj);
2036     if (parcel == NULL) {
2037         doThrowNPE(env);
2038         return 0;
2039     }
2040     std::unique_ptr<SurfaceComposerClient::Transaction> transaction =
2041             SurfaceComposerClient::Transaction::createFromParcel(parcel);
2042 
2043     return reinterpret_cast<jlong>(transaction.release());
2044 }
2045 
nativeMirrorSurface(JNIEnv * env,jclass clazz,jlong mirrorOfObj)2046 static jlong nativeMirrorSurface(JNIEnv* env, jclass clazz, jlong mirrorOfObj) {
2047     sp<SurfaceComposerClient> client = SurfaceComposerClient::getDefault();
2048     SurfaceControl *mirrorOf = reinterpret_cast<SurfaceControl*>(mirrorOfObj);
2049     sp<SurfaceControl> surface = client->mirrorSurface(mirrorOf);
2050 
2051     surface->incStrong((void *)nativeCreate);
2052     return reinterpret_cast<jlong>(surface.get());
2053 }
2054 
nativeSetGlobalShadowSettings(JNIEnv * env,jclass clazz,jfloatArray jAmbientColor,jfloatArray jSpotColor,jfloat lightPosY,jfloat lightPosZ,jfloat lightRadius)2055 static void nativeSetGlobalShadowSettings(JNIEnv* env, jclass clazz, jfloatArray jAmbientColor,
2056         jfloatArray jSpotColor, jfloat lightPosY, jfloat lightPosZ, jfloat lightRadius) {
2057     sp<SurfaceComposerClient> client = SurfaceComposerClient::getDefault();
2058 
2059     float* floatAmbientColor = env->GetFloatArrayElements(jAmbientColor, 0);
2060     half4 ambientColor = half4(floatAmbientColor[0], floatAmbientColor[1], floatAmbientColor[2],
2061             floatAmbientColor[3]);
2062     env->ReleaseFloatArrayElements(jAmbientColor, floatAmbientColor, 0);
2063 
2064     float* floatSpotColor = env->GetFloatArrayElements(jSpotColor, 0);
2065     half4 spotColor = half4(floatSpotColor[0], floatSpotColor[1], floatSpotColor[2],
2066             floatSpotColor[3]);
2067     env->ReleaseFloatArrayElements(jSpotColor, floatSpotColor, 0);
2068 
2069     client->setGlobalShadowSettings(ambientColor, spotColor, lightPosY, lightPosZ, lightRadius);
2070 }
2071 
nativeGetDisplayDecorationSupport(JNIEnv * env,jclass clazz,jobject displayTokenObject)2072 static jobject nativeGetDisplayDecorationSupport(JNIEnv* env, jclass clazz,
2073                                                  jobject displayTokenObject) {
2074     sp<IBinder> displayToken(ibinderForJavaObject(env, displayTokenObject));
2075     if (displayToken == nullptr) {
2076         return nullptr;
2077     }
2078     const auto support = SurfaceComposerClient::getDisplayDecorationSupport(displayToken);
2079     if (!support) {
2080         return nullptr;
2081     }
2082 
2083     using aidl::android::hardware::graphics::common::PixelFormat;
2084     if (support.value().format == PixelFormat::R_8 && !hwui_uses_vulkan()) {
2085         return nullptr;
2086     }
2087 
2088     jobject jDisplayDecorationSupport =
2089             env->NewObject(gDisplayDecorationSupportInfo.clazz, gDisplayDecorationSupportInfo.ctor);
2090     if (jDisplayDecorationSupport == nullptr) {
2091         jniThrowException(env, "java/lang/OutOfMemoryError", nullptr);
2092         return nullptr;
2093     }
2094 
2095     env->SetIntField(jDisplayDecorationSupport, gDisplayDecorationSupportInfo.format,
2096                      static_cast<jint>(support.value().format));
2097     env->SetIntField(jDisplayDecorationSupport, gDisplayDecorationSupportInfo.alphaInterpretation,
2098                      static_cast<jint>(support.value().alphaInterpretation));
2099     return jDisplayDecorationSupport;
2100 }
2101 
nativeGetHandle(JNIEnv * env,jclass clazz,jlong nativeObject)2102 static jlong nativeGetHandle(JNIEnv* env, jclass clazz, jlong nativeObject) {
2103     SurfaceControl *surfaceControl = reinterpret_cast<SurfaceControl*>(nativeObject);
2104     return reinterpret_cast<jlong>(surfaceControl->getHandle().get());
2105 }
2106 
nativeRemoveCurrentInputFocus(JNIEnv * env,jclass clazz,jlong transactionObj,jint displayId)2107 static void nativeRemoveCurrentInputFocus(JNIEnv* env, jclass clazz, jlong transactionObj,
2108                                           jint displayId) {
2109     auto transaction = reinterpret_cast<SurfaceComposerClient::Transaction*>(transactionObj);
2110     FocusRequest request;
2111     request.timestamp = systemTime(SYSTEM_TIME_MONOTONIC);
2112     request.displayId = displayId;
2113     request.windowName = "<null>";
2114     transaction->setFocusedWindow(request);
2115 }
2116 
nativeSetFocusedWindow(JNIEnv * env,jclass clazz,jlong transactionObj,jobject toTokenObj,jstring windowNameJstr,jint displayId)2117 static void nativeSetFocusedWindow(JNIEnv* env, jclass clazz, jlong transactionObj,
2118                                    jobject toTokenObj, jstring windowNameJstr, jint displayId) {
2119     auto transaction = reinterpret_cast<SurfaceComposerClient::Transaction*>(transactionObj);
2120     if (toTokenObj == NULL) return;
2121 
2122     sp<IBinder> toToken(ibinderForJavaObject(env, toTokenObj));
2123 
2124     FocusRequest request;
2125     request.token = toToken;
2126     if (windowNameJstr != NULL) {
2127         ScopedUtfChars windowName(env, windowNameJstr);
2128         request.windowName = windowName.c_str();
2129     }
2130 
2131     request.timestamp = systemTime(SYSTEM_TIME_MONOTONIC);
2132     request.displayId = displayId;
2133     transaction->setFocusedWindow(request);
2134 }
2135 
nativeSetFrameTimelineVsync(JNIEnv * env,jclass clazz,jlong transactionObj,jlong frameTimelineVsyncId)2136 static void nativeSetFrameTimelineVsync(JNIEnv* env, jclass clazz, jlong transactionObj,
2137                                         jlong frameTimelineVsyncId) {
2138     auto transaction = reinterpret_cast<SurfaceComposerClient::Transaction*>(transactionObj);
2139 
2140     FrameTimelineInfo ftInfo;
2141     ftInfo.vsyncId = frameTimelineVsyncId;
2142     transaction->setFrameTimelineInfo(ftInfo);
2143 }
2144 
nativeSetDesiredPresentTimeNanos(JNIEnv * env,jclass clazz,jlong transactionObj,jlong desiredPresentTimeNanos)2145 static void nativeSetDesiredPresentTimeNanos(JNIEnv* env, jclass clazz, jlong transactionObj,
2146                                              jlong desiredPresentTimeNanos) {
2147     auto transaction = reinterpret_cast<SurfaceComposerClient::Transaction*>(transactionObj);
2148 
2149     transaction->setDesiredPresentTime(desiredPresentTimeNanos);
2150 }
2151 
nativeAddTransactionCommittedListener(JNIEnv * env,jclass clazz,jlong transactionObj,jobject transactionCommittedListenerObject)2152 static void nativeAddTransactionCommittedListener(JNIEnv* env, jclass clazz, jlong transactionObj,
2153                                                   jobject transactionCommittedListenerObject) {
2154     auto transaction = reinterpret_cast<SurfaceComposerClient::Transaction*>(transactionObj);
2155 
2156     void* context =
2157             new TransactionCommittedListenerWrapper(env, transactionCommittedListenerObject);
2158     transaction->addTransactionCommittedCallback(TransactionCommittedListenerWrapper::
2159                                                          transactionCallbackThunk,
2160                                                  context);
2161 }
2162 
nativeAddTransactionCompletedListener(JNIEnv * env,jclass clazz,jlong transactionObj,jobject transactionCompletedListenerObject)2163 static void nativeAddTransactionCompletedListener(JNIEnv* env, jclass clazz, jlong transactionObj,
2164                                                   jobject transactionCompletedListenerObject) {
2165     auto transaction = reinterpret_cast<SurfaceComposerClient::Transaction*>(transactionObj);
2166 
2167     void* context =
2168             new TransactionCompletedListenerWrapper(env, transactionCompletedListenerObject);
2169     transaction->addTransactionCompletedCallback(TransactionCompletedListenerWrapper::
2170                                                          transactionCallbackThunk,
2171                                                  context);
2172 }
2173 
nativeSetTrustedPresentationCallback(JNIEnv * env,jclass clazz,jlong transactionObj,jlong nativeObject,jlong trustedPresentationCallbackObject,jobject trustedPresentationThresholds)2174 static void nativeSetTrustedPresentationCallback(JNIEnv* env, jclass clazz, jlong transactionObj,
2175                                                  jlong nativeObject,
2176                                                  jlong trustedPresentationCallbackObject,
2177                                                  jobject trustedPresentationThresholds) {
2178     auto transaction = reinterpret_cast<SurfaceComposerClient::Transaction*>(transactionObj);
2179     auto ctrl = reinterpret_cast<SurfaceControl*>(nativeObject);
2180 
2181     TrustedPresentationThresholds thresholds;
2182     thresholds.minAlpha = env->GetFloatField(trustedPresentationThresholds,
2183                                              gTrustedPresentationThresholdsClassInfo.mMinAlpha);
2184     thresholds.minFractionRendered =
2185             env->GetFloatField(trustedPresentationThresholds,
2186                                gTrustedPresentationThresholdsClassInfo.mMinFractionRendered);
2187     thresholds.stabilityRequirementMs =
2188             env->GetIntField(trustedPresentationThresholds,
2189                              gTrustedPresentationThresholdsClassInfo.mStabilityRequirementMs);
2190 
2191     sp<SurfaceComposerClient::PresentationCallbackRAII> callbackRef;
2192     TrustedPresentationCallbackWrapper* wrapper =
2193             reinterpret_cast<TrustedPresentationCallbackWrapper*>(
2194                     trustedPresentationCallbackObject);
2195     transaction->setTrustedPresentationCallback(ctrl,
2196                                                 TrustedPresentationCallbackWrapper::
2197                                                         onTrustedPresentationChangedThunk,
2198                                                 thresholds, wrapper, callbackRef);
2199     wrapper->addCallbackRef(callbackRef);
2200 }
2201 
nativeClearTrustedPresentationCallback(JNIEnv * env,jclass clazz,jlong transactionObj,jlong nativeObject)2202 static void nativeClearTrustedPresentationCallback(JNIEnv* env, jclass clazz, jlong transactionObj,
2203                                                    jlong nativeObject) {
2204     auto transaction = reinterpret_cast<SurfaceComposerClient::Transaction*>(transactionObj);
2205     auto ctrl = reinterpret_cast<SurfaceControl*>(nativeObject);
2206 
2207     transaction->clearTrustedPresentationCallback(ctrl);
2208 }
2209 
2210 class JankDataListenerWrapper : public JankDataListener {
2211 public:
JankDataListenerWrapper(JNIEnv * env,jobject onJankDataListenerObject)2212     JankDataListenerWrapper(JNIEnv* env, jobject onJankDataListenerObject) : mRemovedVsyncId(-1) {
2213         mOnJankDataListenerWeak = env->NewWeakGlobalRef(onJankDataListenerObject);
2214         env->GetJavaVM(&mVm);
2215     }
2216 
~JankDataListenerWrapper()2217     ~JankDataListenerWrapper() {
2218         JNIEnv* env = getEnv();
2219         env->DeleteWeakGlobalRef(mOnJankDataListenerWeak);
2220     }
2221 
onJankDataAvailable(const std::vector<gui::JankData> & jankData)2222     bool onJankDataAvailable(const std::vector<gui::JankData>& jankData) override {
2223         // Don't invoke the listener if we've been force removed and got this
2224         // out-of-order callback.
2225         if (mRemovedVsyncId == 0) {
2226             return false;
2227         }
2228 
2229         JNIEnv* env = getEnv();
2230 
2231         jobject target = env->NewLocalRef(mOnJankDataListenerWeak);
2232         if (target == nullptr) {
2233             return false;
2234         }
2235 
2236         jobjectArray jJankDataArray =
2237                 env->NewObjectArray(jankData.size(), gJankDataClassInfo.clazz, nullptr);
2238         for (size_t i = 0; i < jankData.size(); i++) {
2239             // The exposed constants in SurfaceControl are simplified, so we need to translate the
2240             // jank type we get from SF to what is exposed in Java.
2241             int sfJankType = jankData[i].jankType;
2242             int javaJankType = 0x0; // SurfaceControl.JankData.JANK_NONE
2243             if (sfJankType &
2244                 (JankType::DisplayHAL | JankType::SurfaceFlingerCpuDeadlineMissed |
2245                  JankType::SurfaceFlingerGpuDeadlineMissed | JankType::PredictionError |
2246                  JankType::SurfaceFlingerScheduling)) {
2247                 javaJankType |= 0x1; // SurfaceControl.JankData.JANK_COMPOSER
2248             }
2249             if (sfJankType & JankType::AppDeadlineMissed) {
2250                 javaJankType |= 0x2; // SurfaceControl.JankData.JANK_APPLICATION
2251             }
2252             if (sfJankType &
2253                 ~(JankType::DisplayHAL | JankType::SurfaceFlingerCpuDeadlineMissed |
2254                   JankType::SurfaceFlingerGpuDeadlineMissed | JankType::AppDeadlineMissed |
2255                   JankType::PredictionError | JankType::SurfaceFlingerScheduling |
2256                   JankType::BufferStuffing | JankType::SurfaceFlingerStuffing)) {
2257                 javaJankType |= 0x4; // SurfaceControl.JankData.JANK_OTHER
2258             }
2259 
2260             jobject jJankData =
2261                     env->NewObject(gJankDataClassInfo.clazz, gJankDataClassInfo.ctor,
2262                                    jankData[i].frameVsyncId, javaJankType,
2263                                    jankData[i].frameIntervalNs, jankData[i].scheduledAppFrameTimeNs,
2264                                    jankData[i].actualAppFrameTimeNs);
2265             env->SetObjectArrayElement(jJankDataArray, i, jJankData);
2266             env->DeleteLocalRef(jJankData);
2267         }
2268 
2269         jobject jJankDataList =
2270                 env->CallStaticObjectMethod(gUtilArrays.clazz, gUtilArrays.asList, jJankDataArray);
2271         env->DeleteLocalRef(jJankDataArray);
2272 
2273         env->CallVoidMethod(target, gJankDataListenerClassInfo.onJankDataAvailable, jJankDataList);
2274         env->DeleteLocalRef(jJankDataList);
2275         env->DeleteLocalRef(target);
2276 
2277         return true;
2278     }
2279 
removeListener(int64_t afterVsyncId)2280     void removeListener(int64_t afterVsyncId) {
2281         mRemovedVsyncId = (afterVsyncId <= 0) ? 0 : afterVsyncId;
2282         JankDataListener::removeListener(afterVsyncId);
2283     }
2284 
2285 private:
2286 
getEnv()2287     JNIEnv* getEnv() {
2288         JNIEnv* env;
2289         mVm->GetEnv(reinterpret_cast<void**>(&env), JNI_VERSION_1_6);
2290         return env;
2291     }
2292 
2293     JavaVM* mVm;
2294     jobject mOnJankDataListenerWeak;
2295     int64_t mRemovedVsyncId;
2296 };
2297 
nativeCreateJankDataListenerWrapper(JNIEnv * env,jclass clazz,jlong nativeSurfaceControl,jobject listener)2298 static jlong nativeCreateJankDataListenerWrapper(JNIEnv* env, jclass clazz,
2299                                                  jlong nativeSurfaceControl, jobject listener) {
2300     sp<SurfaceControl> surface(reinterpret_cast<SurfaceControl *>(nativeSurfaceControl));
2301     if (surface == nullptr) {
2302         return 0;
2303     }
2304 
2305     sp<JankDataListenerWrapper> wrapper = sp<JankDataListenerWrapper>::make(env, listener);
2306     if (wrapper->addListener(std::move(surface)) != OK) {
2307         return 0;
2308     }
2309 
2310     wrapper->incStrong((void*)nativeCreateJankDataListenerWrapper);
2311     return reinterpret_cast<jlong>(wrapper.get());
2312 }
2313 
destroyJankDatalistenerWrapper(void * ptr)2314 static void destroyJankDatalistenerWrapper(void* ptr) {
2315     JankDataListenerWrapper* wrapper = reinterpret_cast<JankDataListenerWrapper*>(ptr);
2316     if (wrapper == nullptr) {
2317         return;
2318     }
2319     wrapper->decStrong((void*)nativeCreateJankDataListenerWrapper);
2320 }
2321 
nativeGetJankDataListenerWrapperFinalizer()2322 static jlong nativeGetJankDataListenerWrapperFinalizer() {
2323     return reinterpret_cast<jlong>(&destroyJankDatalistenerWrapper);
2324 }
2325 
nativeFlushJankData(JNIEnv * env,jclass clazz,jlong listener)2326 static void nativeFlushJankData(JNIEnv* env, jclass clazz, jlong listener) {
2327     sp<JankDataListenerWrapper> wrapper = reinterpret_cast<JankDataListenerWrapper*>(listener);
2328     if (wrapper == nullptr) {
2329         return;
2330     }
2331     wrapper->flushJankData();
2332 }
2333 
nativeRemoveJankDataListener(JNIEnv * env,jclass clazz,jlong listener,jlong afterVsync)2334 static void nativeRemoveJankDataListener(JNIEnv* env, jclass clazz, jlong listener,
2335                                          jlong afterVsync) {
2336     sp<JankDataListenerWrapper> wrapper = reinterpret_cast<JankDataListenerWrapper*>(listener);
2337     if (wrapper == nullptr) {
2338         return;
2339     }
2340     wrapper->removeListener(afterVsync);
2341 }
2342 
nativeGetGPUContextPriority(JNIEnv * env,jclass clazz)2343 static jint nativeGetGPUContextPriority(JNIEnv* env, jclass clazz) {
2344     return static_cast<jint>(SurfaceComposerClient::getGpuContextPriority());
2345 }
2346 
nativeSetTransformHint(JNIEnv * env,jclass clazz,jlong nativeSurfaceControl,jint transformHint)2347 static void nativeSetTransformHint(JNIEnv* env, jclass clazz, jlong nativeSurfaceControl,
2348                                    jint transformHint) {
2349     sp<SurfaceControl> surface(reinterpret_cast<SurfaceControl*>(nativeSurfaceControl));
2350     if (surface == nullptr) {
2351         return;
2352     }
2353     surface->setTransformHint(transformHint);
2354 }
2355 
nativeGetTransformHint(JNIEnv * env,jclass clazz,jlong nativeSurfaceControl)2356 static jint nativeGetTransformHint(JNIEnv* env, jclass clazz, jlong nativeSurfaceControl) {
2357     sp<SurfaceControl> surface(reinterpret_cast<SurfaceControl*>(nativeSurfaceControl));
2358     return surface->getTransformHint();
2359 }
2360 
nativeGetLayerId(JNIEnv * env,jclass clazz,jlong nativeSurfaceControl)2361 static jint nativeGetLayerId(JNIEnv* env, jclass clazz, jlong nativeSurfaceControl) {
2362     sp<SurfaceControl> surface(reinterpret_cast<SurfaceControl*>(nativeSurfaceControl));
2363 
2364     return surface->getLayerId();
2365 }
2366 
nativeSetDefaultApplyToken(JNIEnv * env,jclass clazz,jobject applyToken)2367 static void nativeSetDefaultApplyToken(JNIEnv* env, jclass clazz, jobject applyToken) {
2368     sp<IBinder> token(ibinderForJavaObject(env, applyToken));
2369     if (token == nullptr) {
2370         ALOGE("Null apply token provided.");
2371         return;
2372     }
2373     SurfaceComposerClient::Transaction::setDefaultApplyToken(token);
2374 }
2375 
nativeGetDefaultApplyToken(JNIEnv * env,jclass clazz)2376 static jobject nativeGetDefaultApplyToken(JNIEnv* env, jclass clazz) {
2377     sp<IBinder> token = SurfaceComposerClient::Transaction::getDefaultApplyToken();
2378     return javaObjectForIBinder(env, token);
2379 }
2380 
nativeBootFinished(JNIEnv * env,jclass clazz)2381 static jboolean nativeBootFinished(JNIEnv* env, jclass clazz) {
2382     status_t error = SurfaceComposerClient::bootFinished();
2383     return error == OK ? JNI_TRUE : JNI_FALSE;
2384 }
2385 
nativeGetMaxPictureProfiles(JNIEnv * env,jclass clazz)2386 static jint nativeGetMaxPictureProfiles(JNIEnv* env, jclass clazz) {
2387     const auto displayIds = SurfaceComposerClient::SurfaceComposerClient::getPhysicalDisplayIds();
2388     int largestMaxProfiles = 0;
2389     for (auto displayId : displayIds) {
2390         sp<IBinder> token = SurfaceComposerClient::getPhysicalDisplayToken(displayId);
2391         int32_t maxProfiles = 0;
2392         SurfaceComposerClient::getMaxLayerPictureProfiles(token, &maxProfiles);
2393         if (maxProfiles > largestMaxProfiles) {
2394             largestMaxProfiles = maxProfiles;
2395         }
2396     }
2397     return largestMaxProfiles;
2398 }
2399 
nativeCreateTpc(JNIEnv * env,jclass clazz,jobject trustedPresentationCallback)2400 jlong nativeCreateTpc(JNIEnv* env, jclass clazz, jobject trustedPresentationCallback) {
2401     return reinterpret_cast<jlong>(
2402             new TrustedPresentationCallbackWrapper(env, trustedPresentationCallback));
2403 }
2404 
destroyNativeTpc(void * ptr)2405 void destroyNativeTpc(void* ptr) {
2406     TrustedPresentationCallbackWrapper* callback =
2407             reinterpret_cast<TrustedPresentationCallbackWrapper*>(ptr);
2408     delete callback;
2409 }
2410 
getNativeTrustedPresentationCallbackFinalizer(JNIEnv * env,jclass clazz)2411 static jlong getNativeTrustedPresentationCallbackFinalizer(JNIEnv* env, jclass clazz) {
2412     return static_cast<jlong>(reinterpret_cast<uintptr_t>(&destroyNativeTpc));
2413 }
2414 
nativeGetStalledTransactionInfo(JNIEnv * env,jclass clazz,jint pid)2415 static jobject nativeGetStalledTransactionInfo(JNIEnv* env, jclass clazz, jint pid) {
2416     std::optional<gui::StalledTransactionInfo> stalledTransactionInfo =
2417             SurfaceComposerClient::getStalledTransactionInfo(pid);
2418     if (!stalledTransactionInfo) {
2419         return nullptr;
2420     }
2421 
2422     jobject jStalledTransactionInfo = env->NewObject(gStalledTransactionInfoClassInfo.clazz,
2423                                                      gStalledTransactionInfoClassInfo.ctor);
2424     if (!jStalledTransactionInfo) {
2425         jniThrowException(env, "java/lang/OutOfMemoryError", nullptr);
2426         return nullptr;
2427     }
2428 
2429     env->SetObjectField(jStalledTransactionInfo, gStalledTransactionInfoClassInfo.layerName,
2430                         env->NewStringUTF(String8{stalledTransactionInfo->layerName}));
2431     env->SetLongField(jStalledTransactionInfo, gStalledTransactionInfoClassInfo.bufferId,
2432                       static_cast<jlong>(stalledTransactionInfo->bufferId));
2433     env->SetLongField(jStalledTransactionInfo, gStalledTransactionInfoClassInfo.frameNumber,
2434                       static_cast<jlong>(stalledTransactionInfo->frameNumber));
2435     return jStalledTransactionInfo;
2436 }
2437 
nativeNotifyShutdown()2438 static void nativeNotifyShutdown() {
2439     SurfaceComposerClient::notifyShutdown();
2440 }
2441 
2442 // ----------------------------------------------------------------------------
2443 
android_view_SurfaceControl_getNativeSurfaceControl(JNIEnv * env,jobject surfaceControlObj)2444 SurfaceControl* android_view_SurfaceControl_getNativeSurfaceControl(JNIEnv* env,
2445                                                                     jobject surfaceControlObj) {
2446     if (!!surfaceControlObj &&
2447         env->IsInstanceOf(surfaceControlObj, gSurfaceControlClassInfo.clazz)) {
2448         return reinterpret_cast<SurfaceControl*>(
2449                 env->GetLongField(surfaceControlObj, gSurfaceControlClassInfo.mNativeObject));
2450     } else {
2451         return nullptr;
2452     }
2453 }
2454 
android_view_SurfaceControl_getJavaSurfaceControl(JNIEnv * env,const SurfaceControl & surfaceControl)2455 jobject android_view_SurfaceControl_getJavaSurfaceControl(JNIEnv* env,
2456                                                           const SurfaceControl& surfaceControl) {
2457     jobject surfaceControlObj =
2458             env->NewObject(gSurfaceControlClassInfo.clazz, gSurfaceControlClassInfo.ctor);
2459     env->SetLongField(surfaceControlObj, gSurfaceControlClassInfo.mNativeObject,
2460                       reinterpret_cast<jlong>(&surfaceControl));
2461     env->SetObjectField(surfaceControlObj, gSurfaceControlClassInfo.mName,
2462                         ScopedLocalRef<jobject>(env,
2463                                                 env->NewStringUTF(surfaceControl.getName().c_str()))
2464                                 .get());
2465     surfaceControl.incStrong((void*)nativeCreate);
2466     return surfaceControlObj;
2467 }
2468 
android_view_SurfaceTransaction_getNativeSurfaceTransaction(JNIEnv * env,jobject surfaceTransactionObj)2469 SurfaceComposerClient::Transaction* android_view_SurfaceTransaction_getNativeSurfaceTransaction(
2470         JNIEnv* env, jobject surfaceTransactionObj) {
2471     if (!!surfaceTransactionObj &&
2472         env->IsInstanceOf(surfaceTransactionObj, gTransactionClassInfo.clazz)) {
2473         return reinterpret_cast<SurfaceComposerClient::Transaction*>(
2474                 env->GetLongField(surfaceTransactionObj, gTransactionClassInfo.mNativeObject));
2475     } else {
2476         return nullptr;
2477     }
2478 }
2479 
nativeEnableDebugLogCallPoints(JNIEnv * env,jclass clazz,jlong transactionObj)2480 static void nativeEnableDebugLogCallPoints(JNIEnv* env, jclass clazz, jlong transactionObj) {
2481     auto transaction = reinterpret_cast<SurfaceComposerClient::Transaction*>(transactionObj);
2482     transaction->enableDebugLogCallPoints();
2483 }
2484 
2485 static const JNINativeMethod sSurfaceControlMethods[] = {
2486         // clang-format off
2487     {"nativeCreate", "(Landroid/view/SurfaceSession;Ljava/lang/String;IIIIJLandroid/os/Parcel;)J",
2488             (void*)nativeCreate },
2489     {"nativeReadFromParcel", "(Landroid/os/Parcel;)J",
2490             (void*)nativeReadFromParcel },
2491     {"nativeCopyFromSurfaceControl", "(J)J" ,
2492             (void*)nativeCopyFromSurfaceControl },
2493     {"nativeWriteToParcel", "(JLandroid/os/Parcel;)V",
2494             (void*)nativeWriteToParcel },
2495     {"nativeGetNativeSurfaceControlFinalizer", "()J",
2496             (void*) nativeGetNativeSurfaceControlFinalizer },
2497     {"nativeDisconnect", "(J)V",
2498             (void*)nativeDisconnect },
2499     {"nativeUpdateDefaultBufferSize", "(JII)V",
2500             (void*)nativeSetDefaultBufferSize},
2501     {"nativeCreateTransaction", "()J",
2502             (void*)nativeCreateTransaction },
2503     {"nativeApplyTransaction", "(JZZ)V",
2504             (void*)nativeApplyTransaction },
2505     {"nativeGetNativeTransactionFinalizer", "()J",
2506             (void*)nativeGetNativeTransactionFinalizer },
2507     {"nativeMergeTransaction", "(JJ)V",
2508             (void*)nativeMergeTransaction },
2509     {"nativeSetAnimationTransaction", "(J)V",
2510             (void*)nativeSetAnimationTransaction },
2511     {"nativeSetEarlyWakeupStart", "(J)V",
2512             (void*)nativeSetEarlyWakeupStart },
2513     {"nativeSetEarlyWakeupEnd", "(J)V",
2514             (void*)nativeSetEarlyWakeupEnd },
2515     {"nativeGetTransactionId", "(J)J",
2516                 (void*)nativeGetTransactionId },
2517     {"nativeSetLayer", "(JJI)V",
2518             (void*)nativeSetLayer },
2519     {"nativeSetRelativeLayer", "(JJJI)V",
2520             (void*)nativeSetRelativeLayer },
2521     {"nativeSetPosition", "(JJFF)V",
2522             (void*)nativeSetPosition },
2523     {"nativeSetScale", "(JJFF)V",
2524             (void*)nativeSetScale },
2525     {"nativeSetTransparentRegionHint", "(JJLandroid/graphics/Region;)V",
2526             (void*)nativeSetTransparentRegionHint },
2527     {"nativeSetDamageRegion", "(JJLandroid/graphics/Region;)V",
2528             (void*)nativeSetDamageRegion },
2529     {"nativeSetDimmingEnabled", "(JJZ)V", (void*)nativeSetDimmingEnabled },
2530     {"nativeSetAlpha", "(JJF)V",
2531             (void*)nativeSetAlpha },
2532     {"nativeSetColor", "(JJ[F)V",
2533             (void*)nativeSetColor },
2534     {"nativeSetMatrix", "(JJFFFF)V",
2535             (void*)nativeSetMatrix },
2536     {"nativeSetColorTransform", "(JJ[F[F)V",
2537             (void*)nativeSetColorTransform },
2538     {"nativeSetColorSpaceAgnostic", "(JJZ)V",
2539             (void*)nativeSetColorSpaceAgnostic },
2540     {"nativeSetFlags", "(JJII)V",
2541             (void*)nativeSetFlags },
2542     {"nativeSetFrameRateSelectionPriority", "(JJI)V",
2543             (void*)nativeSetFrameRateSelectionPriority },
2544     {"nativeSetWindowCrop", "(JJIIII)V",
2545             (void*)nativeSetWindowCrop },
2546     {"nativeSetCrop", "(JJFFFF)V",
2547             (void*)nativeSetCrop },
2548     {"nativeSetCornerRadius", "(JJF)V",
2549             (void*)nativeSetCornerRadius },
2550     {"nativeSetBackgroundBlurRadius", "(JJI)V",
2551             (void*)nativeSetBackgroundBlurRadius },
2552     {"nativeSetLayerStack", "(JJI)V",
2553             (void*)nativeSetLayerStack },
2554     {"nativeSetBlurRegions", "(JJ[[FI)V",
2555             (void*)nativeSetBlurRegions },
2556     {"nativeSetStretchEffect", "(JJFFFFFFFFFF)V",
2557             (void*) nativeSetStretchEffect },
2558     {"nativeSetEdgeExtensionEffect", "(JJZZZZ)V",
2559             (void*) nativeSetEdgeExtensionEffect },
2560     {"nativeSetShadowRadius", "(JJF)V",
2561             (void*)nativeSetShadowRadius },
2562     {"nativeSetFrameRate", "(JJFII)V",
2563             (void*)nativeSetFrameRate },
2564     {"nativeSetDefaultFrameRateCompatibility", "(JJI)V",
2565             (void*)nativeSetDefaultFrameRateCompatibility},
2566     {"nativeSetFrameRateCategory", "(JJIZ)V",
2567             (void*)nativeSetFrameRateCategory},
2568     {"nativeSetFrameRateSelectionStrategy", "(JJI)V",
2569             (void*)nativeSetFrameRateSelectionStrategy},
2570     {"nativeSetDisplaySurface", "(JLandroid/os/IBinder;J)V",
2571             (void*)nativeSetDisplaySurface },
2572     {"nativeSetDisplayLayerStack", "(JLandroid/os/IBinder;I)V",
2573             (void*)nativeSetDisplayLayerStack },
2574     {"nativeSetDisplayFlags", "(JLandroid/os/IBinder;I)V",
2575             (void*)nativeSetDisplayFlags },
2576     {"nativeSetDisplayProjection", "(JLandroid/os/IBinder;IIIIIIIII)V",
2577             (void*)nativeSetDisplayProjection },
2578     {"nativeSetDisplaySize", "(JLandroid/os/IBinder;II)V",
2579             (void*)nativeSetDisplaySize },
2580     {"nativeGetStaticDisplayInfo",
2581             "(J)Landroid/view/SurfaceControl$StaticDisplayInfo;",
2582             (void*)nativeGetStaticDisplayInfo },
2583     {"nativeGetDynamicDisplayInfo",
2584             "(J)Landroid/view/SurfaceControl$DynamicDisplayInfo;",
2585             (void*)nativeGetDynamicDisplayInfo },
2586     {"nativeSetDesiredDisplayModeSpecs",
2587             "(Landroid/os/IBinder;Landroid/view/SurfaceControl$DesiredDisplayModeSpecs;)Z",
2588             (void*)nativeSetDesiredDisplayModeSpecs },
2589     {"nativeGetDesiredDisplayModeSpecs",
2590             "(Landroid/os/IBinder;)Landroid/view/SurfaceControl$DesiredDisplayModeSpecs;",
2591             (void*)nativeGetDesiredDisplayModeSpecs },
2592     {"nativeGetDisplayNativePrimaries",
2593             "(Landroid/os/IBinder;)Landroid/view/SurfaceControl$DisplayPrimaries;",
2594             (void*)nativeGetDisplayNativePrimaries },
2595     {"nativeSetActiveColorMode", "(Landroid/os/IBinder;I)Z",
2596             (void*)nativeSetActiveColorMode},
2597      {"nativeGetBootDisplayModeSupport", "()Z",
2598                 (void*)nativeGetBootDisplayModeSupport },
2599     {"nativeSetBootDisplayMode", "(Landroid/os/IBinder;I)V",
2600             (void*)nativeSetBootDisplayMode },
2601     {"nativeClearBootDisplayMode", "(Landroid/os/IBinder;)V",
2602             (void*)nativeClearBootDisplayMode },
2603     {"nativeSetAutoLowLatencyMode", "(Landroid/os/IBinder;Z)V",
2604             (void*)nativeSetAutoLowLatencyMode },
2605     {"nativeSetGameContentType", "(Landroid/os/IBinder;Z)V",
2606             (void*)nativeSetGameContentType },
2607     {"nativeGetCompositionDataspaces", "()[I",
2608             (void*)nativeGetCompositionDataspaces},
2609     {"nativeGetOverlaySupport", "()Landroid/hardware/OverlayProperties;",
2610             (void*) nativeGetOverlaySupport},
2611     {"nativeClearContentFrameStats", "(J)Z",
2612             (void*)nativeClearContentFrameStats },
2613     {"nativeGetContentFrameStats", "(JLandroid/view/WindowContentFrameStats;)Z",
2614             (void*)nativeGetContentFrameStats },
2615     {"nativeClearAnimationFrameStats", "()Z",
2616             (void*)nativeClearAnimationFrameStats },
2617     {"nativeGetAnimationFrameStats", "(Landroid/view/WindowAnimationFrameStats;)Z",
2618             (void*)nativeGetAnimationFrameStats },
2619     {"nativeSetDisplayPowerMode", "(Landroid/os/IBinder;I)V",
2620             (void*)nativeSetDisplayPowerMode },
2621     {"nativeGetProtectedContentSupport", "()Z",
2622             (void*)nativeGetProtectedContentSupport },
2623     {"nativeReparent", "(JJJ)V",
2624             (void*)nativeReparent },
2625     {"nativeSetInputWindowInfo", "(JJLandroid/view/InputWindowHandle;)V",
2626             (void*)nativeSetInputWindowInfo },
2627     {"nativeSetMetadata", "(JJILandroid/os/Parcel;)V",
2628             (void*)nativeSetMetadata },
2629     {"nativeGetDisplayedContentSamplingAttributes",
2630             "(Landroid/os/IBinder;)Landroid/hardware/display/DisplayedContentSamplingAttributes;",
2631             (void*)nativeGetDisplayedContentSamplingAttributes },
2632     {"nativeSetDisplayedContentSamplingEnabled", "(Landroid/os/IBinder;ZII)Z",
2633             (void*)nativeSetDisplayedContentSamplingEnabled },
2634     {"nativeGetDisplayedContentSample",
2635             "(Landroid/os/IBinder;JJ)Landroid/hardware/display/DisplayedContentSample;",
2636             (void*)nativeGetDisplayedContentSample },
2637     {"nativeSetGeometry", "(JJLandroid/graphics/Rect;Landroid/graphics/Rect;J)V",
2638             (void*)nativeSetGeometry },
2639     {"nativeSetBuffer", "(JJLandroid/hardware/HardwareBuffer;JLjava/util/function/Consumer;)V",
2640             (void*)nativeSetBuffer },
2641     {"nativeUnsetBuffer", "(JJ)V", (void*)nativeUnsetBuffer },
2642 
2643     {"nativeSetBufferTransform", "(JJI)V", (void*) nativeSetBufferTransform},
2644     {"nativeSetDataSpace", "(JJI)V",
2645             (void*)nativeSetDataSpace },
2646     {"nativeSetExtendedRangeBrightness", "(JJFF)V",
2647             (void*)nativeSetExtendedRangeBrightness },
2648     {"nativeSetDesiredHdrHeadroom", "(JJF)V",
2649             (void*)nativeSetDesiredHdrHeadroom },
2650     {"nativeSetCachingHint", "(JJI)V",
2651             (void*)nativeSetCachingHint },
2652     {"nativeAddWindowInfosReportedListener", "(JLjava/lang/Runnable;)V",
2653             (void*)nativeAddWindowInfosReportedListener },
2654     {"nativeGetDisplayBrightnessSupport", "(Landroid/os/IBinder;)Z",
2655             (void*)nativeGetDisplayBrightnessSupport },
2656     {"nativeSetDisplayBrightness", "(Landroid/os/IBinder;FFFF)Z",
2657             (void*)nativeSetDisplayBrightness },
2658     {"nativeReadTransactionFromParcel", "(Landroid/os/Parcel;)J",
2659             (void*)nativeReadTransactionFromParcel },
2660     {"nativeWriteTransactionToParcel", "(JLandroid/os/Parcel;)V",
2661             (void*)nativeWriteTransactionToParcel },
2662     {"nativeClearTransaction", "(J)V",
2663             (void*)nativeClearTransaction },
2664     {"nativeMirrorSurface", "(J)J",
2665             (void*)nativeMirrorSurface },
2666     {"nativeSetGlobalShadowSettings", "([F[FFFF)V",
2667             (void*)nativeSetGlobalShadowSettings },
2668     {"nativeGetDisplayDecorationSupport",
2669             "(Landroid/os/IBinder;)Landroid/hardware/graphics/common/DisplayDecorationSupport;",
2670             (void*)nativeGetDisplayDecorationSupport},
2671     {"nativeGetHandle", "(J)J",
2672             (void*)nativeGetHandle },
2673     {"nativeSetFixedTransformHint", "(JJI)V",
2674             (void*)nativeSetFixedTransformHint},
2675     {"nativeSetFocusedWindow", "(JLandroid/os/IBinder;Ljava/lang/String;I)V",
2676             (void*)nativeSetFocusedWindow},
2677     {"nativeRemoveCurrentInputFocus", "(JI)V",
2678             (void*)nativeRemoveCurrentInputFocus},
2679     {"nativeSetFrameTimelineVsync", "(JJ)V",
2680             (void*)nativeSetFrameTimelineVsync },
2681     {"nativeFlushJankData", "(J)V",
2682             (void*)nativeFlushJankData },
2683     {"nativeRemoveJankDataListener", "(JJ)V",
2684             (void*)nativeRemoveJankDataListener },
2685     {"nativeCreateJankDataListenerWrapper", "(JLandroid/view/SurfaceControl$OnJankDataListener;)J",
2686             (void*)nativeCreateJankDataListenerWrapper },
2687     {"nativeGetJankDataListenerWrapperFinalizer", "()J",
2688             (void*)nativeGetJankDataListenerWrapperFinalizer },
2689     {"nativeGetGPUContextPriority", "()I",
2690             (void*)nativeGetGPUContextPriority },
2691     {"nativeSetTransformHint", "(JI)V",
2692             (void*)nativeSetTransformHint },
2693     {"nativeGetTransformHint", "(J)I",
2694             (void*)nativeGetTransformHint },
2695     {"nativeSetTrustedOverlay", "(JJI)V",
2696             (void*)nativeSetTrustedOverlay },
2697     {"nativeGetLayerId", "(J)I",
2698             (void*)nativeGetLayerId },
2699     {"nativeSetDropInputMode", "(JJI)V",
2700              (void*)nativeSetDropInputMode },
2701     {"nativeSurfaceFlushJankData", "(J)V",
2702             (void*)nativeSurfaceFlushJankData },
2703     {"nativeAddTransactionCommittedListener", "(JLandroid/view/SurfaceControl$TransactionCommittedListener;)V",
2704             (void*) nativeAddTransactionCommittedListener },
2705     {"nativeAddTransactionCompletedListener", "(JLjava/util/function/Consumer;)V",
2706             (void*) nativeAddTransactionCompletedListener },
2707     {"nativeSetTrustedPresentationCallback", "(JJJLandroid/view/SurfaceControl$TrustedPresentationThresholds;)V",
2708             (void*) nativeSetTrustedPresentationCallback },
2709     {"nativeClearTrustedPresentationCallback", "(JJ)V",
2710             (void*) nativeClearTrustedPresentationCallback },
2711     {"nativeSanitize", "(JII)V",
2712             (void*) nativeSanitize },
2713     {"nativeSetDestinationFrame", "(JJIIII)V",
2714                 (void*)nativeSetDestinationFrame },
2715     {"nativeSetDefaultApplyToken", "(Landroid/os/IBinder;)V",
2716                 (void*)nativeSetDefaultApplyToken },
2717     {"nativeGetDefaultApplyToken", "()Landroid/os/IBinder;",
2718                 (void*)nativeGetDefaultApplyToken },
2719     {"nativeBootFinished", "()Z",
2720             (void*)nativeBootFinished },
2721     {"nativeGetMaxPictureProfiles", "()I",
2722             (void*)nativeGetMaxPictureProfiles },
2723     {"nativeCreateTpc", "(Landroid/view/SurfaceControl$TrustedPresentationCallback;)J",
2724             (void*)nativeCreateTpc},
2725     {"getNativeTrustedPresentationCallbackFinalizer", "()J", (void*)getNativeTrustedPresentationCallbackFinalizer },
2726     {"nativeGetStalledTransactionInfo", "(I)Landroid/gui/StalledTransactionInfo;",
2727             (void*) nativeGetStalledTransactionInfo },
2728     {"nativeSetDesiredPresentTimeNanos", "(JJ)V",
2729             (void*) nativeSetDesiredPresentTimeNanos },
2730     {"nativeNotifyShutdown", "()V",
2731             (void*)nativeNotifyShutdown },
2732     {"nativeSetLuts", "(JJ[F[I[I[I[I)V", (void*)nativeSetLuts },
2733     {"nativeEnableDebugLogCallPoints", "(J)V", (void*)nativeEnableDebugLogCallPoints },
2734     {"nativeSetPictureProfileId", "(JJJ)V", (void*)nativeSetPictureProfileId },
2735     {"nativeSetContentPriority", "(JJI)V", (void*)nativeSetContentPriority },
2736         // clang-format on
2737 };
2738 
register_android_view_SurfaceControl(JNIEnv * env)2739 int register_android_view_SurfaceControl(JNIEnv* env)
2740 {
2741     int err = RegisterMethodsOrDie(env, "android/view/SurfaceControl",
2742             sSurfaceControlMethods, NELEM(sSurfaceControlMethods));
2743 
2744     jclass integerClass = FindClassOrDie(env, "java/lang/Integer");
2745     gIntegerClassInfo.clazz = MakeGlobalRefOrDie(env, integerClass);
2746     gIntegerClassInfo.ctor = GetMethodIDOrDie(env, gIntegerClassInfo.clazz, "<init>", "(I)V");
2747 
2748     jclass runnableClazz = FindClassOrDie(env, "java/lang/Runnable");
2749     gRunnableClassInfo.clazz = MakeGlobalRefOrDie(env, runnableClazz);
2750     gRunnableClassInfo.run = GetMethodIDOrDie(env, runnableClazz, "run", "()V");
2751 
2752     jclass infoClazz = FindClassOrDie(env, "android/view/SurfaceControl$StaticDisplayInfo");
2753     gStaticDisplayInfoClassInfo.clazz = MakeGlobalRefOrDie(env, infoClazz);
2754     gStaticDisplayInfoClassInfo.ctor = GetMethodIDOrDie(env, infoClazz, "<init>", "()V");
2755     gStaticDisplayInfoClassInfo.isInternal = GetFieldIDOrDie(env, infoClazz, "isInternal", "Z");
2756     gStaticDisplayInfoClassInfo.density = GetFieldIDOrDie(env, infoClazz, "density", "F");
2757     gStaticDisplayInfoClassInfo.secure = GetFieldIDOrDie(env, infoClazz, "secure", "Z");
2758     gStaticDisplayInfoClassInfo.deviceProductInfo =
2759             GetFieldIDOrDie(env, infoClazz, "deviceProductInfo",
2760                             "Landroid/hardware/display/DeviceProductInfo;");
2761     gStaticDisplayInfoClassInfo.installOrientation =
2762             GetFieldIDOrDie(env, infoClazz, "installOrientation", "I");
2763 
2764     jclass dynamicInfoClazz = FindClassOrDie(env, "android/view/SurfaceControl$DynamicDisplayInfo");
2765     gDynamicDisplayInfoClassInfo.clazz = MakeGlobalRefOrDie(env, dynamicInfoClazz);
2766     gDynamicDisplayInfoClassInfo.ctor = GetMethodIDOrDie(env, dynamicInfoClazz, "<init>", "()V");
2767     gDynamicDisplayInfoClassInfo.supportedDisplayModes =
2768             GetFieldIDOrDie(env, dynamicInfoClazz, "supportedDisplayModes",
2769                             "[Landroid/view/SurfaceControl$DisplayMode;");
2770     gDynamicDisplayInfoClassInfo.activeDisplayModeId =
2771             GetFieldIDOrDie(env, dynamicInfoClazz, "activeDisplayModeId", "I");
2772     gDynamicDisplayInfoClassInfo.renderFrameRate =
2773             GetFieldIDOrDie(env, dynamicInfoClazz, "renderFrameRate", "F");
2774     gDynamicDisplayInfoClassInfo.hasArrSupport =
2775             GetFieldIDOrDie(env, dynamicInfoClazz, "hasArrSupport", "Z");
2776 
2777     gDynamicDisplayInfoClassInfo.frameRateCategoryRate =
2778             GetFieldIDOrDie(env, dynamicInfoClazz, "frameRateCategoryRate",
2779                             "Landroid/view/FrameRateCategoryRate;");
2780     jclass frameRateCategoryRateClazz = FindClassOrDie(env, "android/view/FrameRateCategoryRate");
2781     gFrameRateCategoryRateClassInfo.clazz = MakeGlobalRefOrDie(env, frameRateCategoryRateClazz);
2782     gFrameRateCategoryRateClassInfo.ctor =
2783             GetMethodIDOrDie(env, frameRateCategoryRateClazz, "<init>", "(FF)V");
2784 
2785     gDynamicDisplayInfoClassInfo.supportedRefreshRates =
2786             GetFieldIDOrDie(env, dynamicInfoClazz, "supportedRefreshRates", "[F");
2787     gDynamicDisplayInfoClassInfo.supportedColorModes =
2788             GetFieldIDOrDie(env, dynamicInfoClazz, "supportedColorModes", "[I");
2789     gDynamicDisplayInfoClassInfo.activeColorMode =
2790             GetFieldIDOrDie(env, dynamicInfoClazz, "activeColorMode", "I");
2791     gDynamicDisplayInfoClassInfo.hdrCapabilities =
2792             GetFieldIDOrDie(env, dynamicInfoClazz, "hdrCapabilities",
2793                             "Landroid/view/Display$HdrCapabilities;");
2794     gDynamicDisplayInfoClassInfo.autoLowLatencyModeSupported =
2795             GetFieldIDOrDie(env, dynamicInfoClazz, "autoLowLatencyModeSupported", "Z");
2796     gDynamicDisplayInfoClassInfo.gameContentTypeSupported =
2797             GetFieldIDOrDie(env, dynamicInfoClazz, "gameContentTypeSupported", "Z");
2798     gDynamicDisplayInfoClassInfo.preferredBootDisplayMode =
2799             GetFieldIDOrDie(env, dynamicInfoClazz, "preferredBootDisplayMode", "I");
2800 
2801     jclass modeClazz = FindClassOrDie(env, "android/view/SurfaceControl$DisplayMode");
2802     gDisplayModeClassInfo.clazz = MakeGlobalRefOrDie(env, modeClazz);
2803     gDisplayModeClassInfo.ctor = GetMethodIDOrDie(env, modeClazz, "<init>", "()V");
2804     gDisplayModeClassInfo.id = GetFieldIDOrDie(env, modeClazz, "id", "I");
2805     gDisplayModeClassInfo.width = GetFieldIDOrDie(env, modeClazz, "width", "I");
2806     gDisplayModeClassInfo.height = GetFieldIDOrDie(env, modeClazz, "height", "I");
2807     gDisplayModeClassInfo.xDpi = GetFieldIDOrDie(env, modeClazz, "xDpi", "F");
2808     gDisplayModeClassInfo.yDpi = GetFieldIDOrDie(env, modeClazz, "yDpi", "F");
2809     gDisplayModeClassInfo.peakRefreshRate = GetFieldIDOrDie(env, modeClazz, "peakRefreshRate", "F");
2810     gDisplayModeClassInfo.vsyncRate = GetFieldIDOrDie(env, modeClazz, "vsyncRate", "F");
2811     gDisplayModeClassInfo.appVsyncOffsetNanos =
2812             GetFieldIDOrDie(env, modeClazz, "appVsyncOffsetNanos", "J");
2813     gDisplayModeClassInfo.presentationDeadlineNanos =
2814             GetFieldIDOrDie(env, modeClazz, "presentationDeadlineNanos", "J");
2815     gDisplayModeClassInfo.group = GetFieldIDOrDie(env, modeClazz, "group", "I");
2816     gDisplayModeClassInfo.supportedHdrTypes =
2817             GetFieldIDOrDie(env, modeClazz, "supportedHdrTypes", "[I");
2818 
2819     jclass frameStatsClazz = FindClassOrDie(env, "android/view/FrameStats");
2820     jfieldID undefined_time_nano_field = GetStaticFieldIDOrDie(env,
2821             frameStatsClazz, "UNDEFINED_TIME_NANO", "J");
2822     nsecs_t undefined_time_nano = env->GetStaticLongField(frameStatsClazz, undefined_time_nano_field);
2823 
2824     jclass contFrameStatsClazz = FindClassOrDie(env, "android/view/WindowContentFrameStats");
2825     gWindowContentFrameStatsClassInfo.init = GetMethodIDOrDie(env,
2826             contFrameStatsClazz, "init", "(J[J[J[J)V");
2827     gWindowContentFrameStatsClassInfo.UNDEFINED_TIME_NANO = undefined_time_nano;
2828 
2829     jclass animFrameStatsClazz = FindClassOrDie(env, "android/view/WindowAnimationFrameStats");
2830     gWindowAnimationFrameStatsClassInfo.init =  GetMethodIDOrDie(env,
2831             animFrameStatsClazz, "init", "(J[J)V");
2832     gWindowAnimationFrameStatsClassInfo.UNDEFINED_TIME_NANO = undefined_time_nano;
2833 
2834     jclass hdrCapabilitiesClazz = FindClassOrDie(env, "android/view/Display$HdrCapabilities");
2835     gHdrCapabilitiesClassInfo.clazz = MakeGlobalRefOrDie(env, hdrCapabilitiesClazz);
2836     gHdrCapabilitiesClassInfo.ctor = GetMethodIDOrDie(env, hdrCapabilitiesClazz, "<init>",
2837             "([IFFF)V");
2838 
2839     jclass deviceProductInfoClazz =
2840             FindClassOrDie(env, "android/hardware/display/DeviceProductInfo");
2841     gDeviceProductInfoClassInfo.clazz = MakeGlobalRefOrDie(env, deviceProductInfoClazz);
2842     gDeviceProductInfoClassInfo.ctor =
2843             GetMethodIDOrDie(env, deviceProductInfoClazz, "<init>",
2844                              "(Ljava/lang/String;"
2845                              "Ljava/lang/String;"
2846                              "Ljava/lang/String;"
2847                              "Ljava/lang/Integer;"
2848                              "Landroid/hardware/display/DeviceProductInfo$ManufactureDate;"
2849                              "I)V");
2850 
2851     jclass deviceProductInfoManufactureDateClazz =
2852             FindClassOrDie(env, "android/hardware/display/DeviceProductInfo$ManufactureDate");
2853     gDeviceProductInfoManufactureDateClassInfo.clazz =
2854             MakeGlobalRefOrDie(env, deviceProductInfoManufactureDateClazz);
2855     gDeviceProductInfoManufactureDateClassInfo.ctor =
2856             GetMethodIDOrDie(env, deviceProductInfoManufactureDateClazz, "<init>",
2857                              "(Ljava/lang/Integer;Ljava/lang/Integer;)V");
2858 
2859     jclass displayedContentSampleClazz = FindClassOrDie(env,
2860             "android/hardware/display/DisplayedContentSample");
2861     gDisplayedContentSampleClassInfo.clazz = MakeGlobalRefOrDie(env, displayedContentSampleClazz);
2862     gDisplayedContentSampleClassInfo.ctor = GetMethodIDOrDie(env,
2863             displayedContentSampleClazz, "<init>", "(J[J[J[J[J)V");
2864 
2865     jclass displayedContentSamplingAttributesClazz = FindClassOrDie(env,
2866             "android/hardware/display/DisplayedContentSamplingAttributes");
2867     gDisplayedContentSamplingAttributesClassInfo.clazz = MakeGlobalRefOrDie(env,
2868             displayedContentSamplingAttributesClazz);
2869     gDisplayedContentSamplingAttributesClassInfo.ctor = GetMethodIDOrDie(env,
2870             displayedContentSamplingAttributesClazz, "<init>", "(III)V");
2871 
2872     jclass cieXyzClazz = FindClassOrDie(env, "android/view/SurfaceControl$CieXyz");
2873     gCieXyzClassInfo.clazz = MakeGlobalRefOrDie(env, cieXyzClazz);
2874     gCieXyzClassInfo.ctor = GetMethodIDOrDie(env, gCieXyzClassInfo.clazz, "<init>", "()V");
2875     gCieXyzClassInfo.X = GetFieldIDOrDie(env, cieXyzClazz, "X", "F");
2876     gCieXyzClassInfo.Y = GetFieldIDOrDie(env, cieXyzClazz, "Y", "F");
2877     gCieXyzClassInfo.Z = GetFieldIDOrDie(env, cieXyzClazz, "Z", "F");
2878 
2879     jclass displayPrimariesClazz = FindClassOrDie(env,
2880             "android/view/SurfaceControl$DisplayPrimaries");
2881     gDisplayPrimariesClassInfo.clazz = MakeGlobalRefOrDie(env, displayPrimariesClazz);
2882     gDisplayPrimariesClassInfo.ctor = GetMethodIDOrDie(env, gDisplayPrimariesClassInfo.clazz,
2883             "<init>", "()V");
2884     gDisplayPrimariesClassInfo.red = GetFieldIDOrDie(env, displayPrimariesClazz, "red",
2885             "Landroid/view/SurfaceControl$CieXyz;");
2886     gDisplayPrimariesClassInfo.green = GetFieldIDOrDie(env, displayPrimariesClazz, "green",
2887             "Landroid/view/SurfaceControl$CieXyz;");
2888     gDisplayPrimariesClassInfo.blue = GetFieldIDOrDie(env, displayPrimariesClazz, "blue",
2889             "Landroid/view/SurfaceControl$CieXyz;");
2890     gDisplayPrimariesClassInfo.white = GetFieldIDOrDie(env, displayPrimariesClazz, "white",
2891             "Landroid/view/SurfaceControl$CieXyz;");
2892 
2893     jclass RefreshRateRangeClazz =
2894             FindClassOrDie(env, "android/view/SurfaceControl$RefreshRateRange");
2895     gRefreshRateRangeClassInfo.clazz = MakeGlobalRefOrDie(env, RefreshRateRangeClazz);
2896     gRefreshRateRangeClassInfo.ctor =
2897             GetMethodIDOrDie(env, gRefreshRateRangeClassInfo.clazz, "<init>", "(FF)V");
2898     gRefreshRateRangeClassInfo.min = GetFieldIDOrDie(env, RefreshRateRangeClazz, "min", "F");
2899     gRefreshRateRangeClassInfo.max = GetFieldIDOrDie(env, RefreshRateRangeClazz, "max", "F");
2900 
2901     jclass RefreshRateRangesClazz =
2902             FindClassOrDie(env, "android/view/SurfaceControl$RefreshRateRanges");
2903     gRefreshRateRangesClassInfo.clazz = MakeGlobalRefOrDie(env, RefreshRateRangesClazz);
2904     gRefreshRateRangesClassInfo.ctor =
2905             GetMethodIDOrDie(env, gRefreshRateRangesClassInfo.clazz, "<init>",
2906                              "(Landroid/view/SurfaceControl$RefreshRateRange;Landroid/view/"
2907                              "SurfaceControl$RefreshRateRange;)V");
2908     gRefreshRateRangesClassInfo.physical =
2909             GetFieldIDOrDie(env, RefreshRateRangesClazz, "physical",
2910                             "Landroid/view/SurfaceControl$RefreshRateRange;");
2911     gRefreshRateRangesClassInfo.render =
2912             GetFieldIDOrDie(env, RefreshRateRangesClazz, "render",
2913                             "Landroid/view/SurfaceControl$RefreshRateRange;");
2914 
2915     jclass IdleScreenRefreshRateConfigClazz =
2916             FindClassOrDie(env, "android/view/SurfaceControl$IdleScreenRefreshRateConfig");
2917     gIdleScreenRefreshRateConfigClassInfo.clazz =
2918             MakeGlobalRefOrDie(env, IdleScreenRefreshRateConfigClazz);
2919     gIdleScreenRefreshRateConfigClassInfo.ctor =
2920             GetMethodIDOrDie(env, gIdleScreenRefreshRateConfigClassInfo.clazz, "<init>", "(I)V");
2921     gIdleScreenRefreshRateConfigClassInfo.timeoutMillis =
2922             GetFieldIDOrDie(env, gIdleScreenRefreshRateConfigClassInfo.clazz, "timeoutMillis", "I");
2923 
2924     jclass DesiredDisplayModeSpecsClazz =
2925             FindClassOrDie(env, "android/view/SurfaceControl$DesiredDisplayModeSpecs");
2926     gDesiredDisplayModeSpecsClassInfo.clazz = MakeGlobalRefOrDie(env, DesiredDisplayModeSpecsClazz);
2927     gDesiredDisplayModeSpecsClassInfo.ctor =
2928             GetMethodIDOrDie(env, gDesiredDisplayModeSpecsClassInfo.clazz, "<init>",
2929                              "(IZLandroid/view/SurfaceControl$RefreshRateRanges;Landroid/view/"
2930                              "SurfaceControl$RefreshRateRanges;Landroid/view/"
2931                              "SurfaceControl$IdleScreenRefreshRateConfig;)V");
2932     gDesiredDisplayModeSpecsClassInfo.defaultMode =
2933             GetFieldIDOrDie(env, DesiredDisplayModeSpecsClazz, "defaultMode", "I");
2934     gDesiredDisplayModeSpecsClassInfo.allowGroupSwitching =
2935             GetFieldIDOrDie(env, DesiredDisplayModeSpecsClazz, "allowGroupSwitching", "Z");
2936     gDesiredDisplayModeSpecsClassInfo.primaryRanges =
2937             GetFieldIDOrDie(env, DesiredDisplayModeSpecsClazz, "primaryRanges",
2938                             "Landroid/view/SurfaceControl$RefreshRateRanges;");
2939     gDesiredDisplayModeSpecsClassInfo.appRequestRanges =
2940             GetFieldIDOrDie(env, DesiredDisplayModeSpecsClazz, "appRequestRanges",
2941                             "Landroid/view/SurfaceControl$RefreshRateRanges;");
2942     gDesiredDisplayModeSpecsClassInfo.idleScreenRefreshRateConfig =
2943             GetFieldIDOrDie(env, DesiredDisplayModeSpecsClazz, "idleScreenRefreshRateConfig",
2944                             "Landroid/view/SurfaceControl$IdleScreenRefreshRateConfig;");
2945 
2946     jclass jankDataClazz =
2947                 FindClassOrDie(env, "android/view/SurfaceControl$JankData");
2948     gJankDataClassInfo.clazz = MakeGlobalRefOrDie(env, jankDataClazz);
2949     gJankDataClassInfo.ctor = GetMethodIDOrDie(env, gJankDataClassInfo.clazz, "<init>", "(JIJJJ)V");
2950     jclass onJankDataListenerClazz =
2951             FindClassOrDie(env, "android/view/SurfaceControl$OnJankDataListener");
2952     gJankDataListenerClassInfo.clazz = MakeGlobalRefOrDie(env, onJankDataListenerClazz);
2953     gJankDataListenerClassInfo.onJankDataAvailable =
2954             GetMethodIDOrDie(env, onJankDataListenerClazz, "onJankDataAvailable",
2955                              "(Ljava/util/List;)V");
2956 
2957     jclass transactionCommittedListenerClazz =
2958             FindClassOrDie(env, "android/view/SurfaceControl$TransactionCommittedListener");
2959     gTransactionCommittedListenerClassInfo.clazz =
2960             MakeGlobalRefOrDie(env, transactionCommittedListenerClazz);
2961     gTransactionCommittedListenerClassInfo.onTransactionCommitted =
2962             GetMethodIDOrDie(env, transactionCommittedListenerClazz, "onTransactionCommitted",
2963                              "()V");
2964     jclass consumerClazz = FindClassOrDie(env, "java/util/function/Consumer");
2965     gConsumerClassInfo.clazz = MakeGlobalRefOrDie(env, consumerClazz);
2966     gConsumerClassInfo.accept =
2967             GetMethodIDOrDie(env, consumerClazz, "accept", "(Ljava/lang/Object;)V");
2968 
2969     jclass transactionStatsClazz =
2970             FindClassOrDie(env, "android/view/SurfaceControl$TransactionStats");
2971     gTransactionStatsClassInfo.clazz = MakeGlobalRefOrDie(env, transactionStatsClazz);
2972     gTransactionStatsClassInfo.ctor =
2973             GetMethodIDOrDie(env, gTransactionStatsClassInfo.clazz, "<init>", "(JJ)V");
2974 
2975     jclass displayDecorationSupportClazz =
2976             FindClassOrDie(env, "android/hardware/graphics/common/DisplayDecorationSupport");
2977     gDisplayDecorationSupportInfo.clazz = MakeGlobalRefOrDie(env, displayDecorationSupportClazz);
2978     gDisplayDecorationSupportInfo.ctor =
2979             GetMethodIDOrDie(env, displayDecorationSupportClazz, "<init>", "()V");
2980     gDisplayDecorationSupportInfo.format =
2981             GetFieldIDOrDie(env, displayDecorationSupportClazz, "format", "I");
2982     gDisplayDecorationSupportInfo.alphaInterpretation =
2983             GetFieldIDOrDie(env, displayDecorationSupportClazz, "alphaInterpretation", "I");
2984 
2985     jclass surfaceControlClazz = FindClassOrDie(env, "android/view/SurfaceControl");
2986     gSurfaceControlClassInfo.clazz = MakeGlobalRefOrDie(env, surfaceControlClazz);
2987     gSurfaceControlClassInfo.mNativeObject =
2988             GetFieldIDOrDie(env, gSurfaceControlClassInfo.clazz, "mNativeObject", "J");
2989     gSurfaceControlClassInfo.mName =
2990             GetFieldIDOrDie(env, gSurfaceControlClassInfo.clazz, "mName", "Ljava/lang/String;");
2991     gSurfaceControlClassInfo.ctor = GetMethodIDOrDie(env, surfaceControlClazz, "<init>", "()V");
2992     gSurfaceControlClassInfo.invokeReleaseCallback =
2993             GetStaticMethodIDOrDie(env, surfaceControlClazz, "invokeReleaseCallback",
2994                                    "(Ljava/util/function/Consumer;J)V");
2995 
2996     jclass surfaceTransactionClazz = FindClassOrDie(env, "android/view/SurfaceControl$Transaction");
2997     gTransactionClassInfo.clazz = MakeGlobalRefOrDie(env, surfaceTransactionClazz);
2998     gTransactionClassInfo.mNativeObject =
2999             GetFieldIDOrDie(env, gTransactionClassInfo.clazz, "mNativeObject", "J");
3000 
3001     jclass trustedPresentationThresholdsClazz =
3002             FindClassOrDie(env, "android/view/SurfaceControl$TrustedPresentationThresholds");
3003     gTrustedPresentationThresholdsClassInfo.clazz =
3004             MakeGlobalRefOrDie(env, trustedPresentationThresholdsClazz);
3005     gTrustedPresentationThresholdsClassInfo.mMinAlpha =
3006             GetFieldIDOrDie(env, trustedPresentationThresholdsClazz, "mMinAlpha", "F");
3007     gTrustedPresentationThresholdsClassInfo.mMinFractionRendered =
3008             GetFieldIDOrDie(env, trustedPresentationThresholdsClazz, "mMinFractionRendered", "F");
3009     gTrustedPresentationThresholdsClassInfo.mStabilityRequirementMs =
3010             GetFieldIDOrDie(env, trustedPresentationThresholdsClazz, "mStabilityRequirementMs",
3011                             "I");
3012 
3013     jclass trustedPresentationCallbackClazz =
3014             FindClassOrDie(env, "android/view/SurfaceControl$TrustedPresentationCallback");
3015     gTrustedPresentationCallbackClassInfo.onTrustedPresentationChanged =
3016             GetMethodIDOrDie(env, trustedPresentationCallbackClazz, "onTrustedPresentationChanged",
3017                              "(Z)V");
3018 
3019     jclass stalledTransactionInfoClazz = FindClassOrDie(env, "android/gui/StalledTransactionInfo");
3020     gStalledTransactionInfoClassInfo.clazz = MakeGlobalRefOrDie(env, stalledTransactionInfoClazz);
3021     gStalledTransactionInfoClassInfo.ctor =
3022             GetMethodIDOrDie(env, stalledTransactionInfoClazz, "<init>", "()V");
3023     gStalledTransactionInfoClassInfo.layerName =
3024             GetFieldIDOrDie(env, stalledTransactionInfoClazz, "layerName", "Ljava/lang/String;");
3025     gStalledTransactionInfoClassInfo.bufferId =
3026             GetFieldIDOrDie(env, stalledTransactionInfoClazz, "bufferId", "J");
3027     gStalledTransactionInfoClassInfo.frameNumber =
3028             GetFieldIDOrDie(env, stalledTransactionInfoClazz, "frameNumber", "J");
3029 
3030     jclass utilArrays = FindClassOrDie(env, "java/util/Arrays");
3031     gUtilArrays.clazz = MakeGlobalRefOrDie(env, utilArrays);
3032     gUtilArrays.asList = GetStaticMethodIDOrDie(env, utilArrays, "asList",
3033                                                 "([Ljava/lang/Object;)Ljava/util/List;");
3034     return err;
3035 }
3036 
3037 } // namespace android
3038