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