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