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