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