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