1 /*
2 * Copyright (C) 2013 The Android Open Source Project
3 *
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
7 *
8 * http://www.apache.org/licenses/LICENSE-2.0
9 *
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
15 */
16
17 #define LOG_TAG "SurfaceControl"
18 #define LOG_NDEBUG 0
19
20 #include "android_os_Parcel.h"
21 #include "android_util_Binder.h"
22 #include "android_hardware_input_InputWindowHandle.h"
23 #include "core_jni_helpers.h"
24
25 #include <memory>
26
27 #include <android-base/chrono_utils.h>
28 #include <android/graphics/region.h>
29 #include <android_runtime/AndroidRuntime.h>
30 #include <android_runtime/android_view_Surface.h>
31 #include <android_runtime/android_view_SurfaceSession.h>
32 #include <gui/ISurfaceComposer.h>
33 #include <gui/Surface.h>
34 #include <gui/SurfaceComposerClient.h>
35 #include <jni.h>
36 #include <nativehelper/JNIHelp.h>
37 #include <nativehelper/ScopedUtfChars.h>
38 #include <private/gui/ComposerService.h>
39 #include <stdio.h>
40 #include <system/graphics.h>
41 #include <ui/ConfigStoreTypes.h>
42 #include <ui/DeviceProductInfo.h>
43 #include <ui/DisplayConfig.h>
44 #include <ui/DisplayInfo.h>
45 #include <ui/DisplayedFrameStats.h>
46 #include <ui/FrameStats.h>
47 #include <ui/GraphicTypes.h>
48 #include <ui/HdrCapabilities.h>
49 #include <ui/Rect.h>
50 #include <ui/Region.h>
51 #include <utils/Log.h>
52
53 // ----------------------------------------------------------------------------
54
55 namespace android {
56
doThrowNPE(JNIEnv * env)57 static void doThrowNPE(JNIEnv* env) {
58 jniThrowNullPointerException(env, NULL);
59 }
60
doThrowIAE(JNIEnv * env,const char * msg=nullptr)61 static void doThrowIAE(JNIEnv* env, const char* msg = nullptr) {
62 jniThrowException(env, "java/lang/IllegalArgumentException", msg);
63 }
64
65 static const char* const OutOfResourcesException =
66 "android/view/Surface$OutOfResourcesException";
67
68 static struct {
69 jclass clazz;
70 jmethodID ctor;
71 } gIntegerClassInfo;
72
toInteger(JNIEnv * env,int32_t i)73 static jobject toInteger(JNIEnv* env, int32_t i) {
74 return env->NewObject(gIntegerClassInfo.clazz, gIntegerClassInfo.ctor, i);
75 }
76
77 static struct {
78 jclass clazz;
79 jmethodID ctor;
80 jfieldID isInternal;
81 jfieldID density;
82 jfieldID secure;
83 jfieldID deviceProductInfo;
84 } gDisplayInfoClassInfo;
85
86 static struct {
87 jclass clazz;
88 jmethodID ctor;
89 jfieldID width;
90 jfieldID height;
91 jfieldID xDpi;
92 jfieldID yDpi;
93 jfieldID refreshRate;
94 jfieldID appVsyncOffsetNanos;
95 jfieldID presentationDeadlineNanos;
96 jfieldID configGroup;
97 } gDisplayConfigClassInfo;
98
99 static struct {
100 jfieldID bottom;
101 jfieldID left;
102 jfieldID right;
103 jfieldID top;
104 } gRectClassInfo;
105
106 // Implements SkMallocPixelRef::ReleaseProc, to delete the screenshot on unref.
DeleteScreenshot(void * addr,void * context)107 void DeleteScreenshot(void* addr, void* context) {
108 delete ((ScreenshotClient*) context);
109 }
110
111 static struct {
112 nsecs_t UNDEFINED_TIME_NANO;
113 jmethodID init;
114 } gWindowContentFrameStatsClassInfo;
115
116 static struct {
117 nsecs_t UNDEFINED_TIME_NANO;
118 jmethodID init;
119 } gWindowAnimationFrameStatsClassInfo;
120
121 static struct {
122 jclass clazz;
123 jmethodID ctor;
124 } gHdrCapabilitiesClassInfo;
125
126 static struct {
127 jclass clazz;
128 jmethodID ctor;
129 } gDeviceProductInfoClassInfo;
130
131 static struct {
132 jclass clazz;
133 jmethodID ctor;
134 } gDeviceProductInfoManufactureDateClassInfo;
135
136 static struct {
137 jclass clazz;
138 jmethodID builder;
139 } gGraphicBufferClassInfo;
140
141 static struct {
142 jclass clazz;
143 jmethodID ctor;
144 } gDisplayedContentSampleClassInfo;
145
146 static struct {
147 jclass clazz;
148 jmethodID ctor;
149 } gDisplayedContentSamplingAttributesClassInfo;
150
151 static struct {
152 jclass clazz;
153 jmethodID ctor;
154 jfieldID X;
155 jfieldID Y;
156 jfieldID Z;
157 } gCieXyzClassInfo;
158
159 static struct {
160 jclass clazz;
161 jmethodID ctor;
162 jfieldID red;
163 jfieldID green;
164 jfieldID blue;
165 jfieldID white;
166 } gDisplayPrimariesClassInfo;
167
168 static struct {
169 jclass clazz;
170 jmethodID builder;
171 } gScreenshotGraphicBufferClassInfo;
172
173 static struct {
174 jclass clazz;
175 jmethodID ctor;
176 jfieldID defaultConfig;
177 jfieldID primaryRefreshRateMin;
178 jfieldID primaryRefreshRateMax;
179 jfieldID appRequestRefreshRateMin;
180 jfieldID appRequestRefreshRateMax;
181 } gDesiredDisplayConfigSpecsClassInfo;
182
183 class JNamedColorSpace {
184 public:
185 // ColorSpace.Named.SRGB.ordinal() = 0;
186 static constexpr jint SRGB = 0;
187
188 // ColorSpace.Named.DISPLAY_P3.ordinal() = 7;
189 static constexpr jint DISPLAY_P3 = 7;
190 };
191
fromDataspaceToNamedColorSpaceValue(const ui::Dataspace dataspace)192 constexpr jint fromDataspaceToNamedColorSpaceValue(const ui::Dataspace dataspace) {
193 switch (dataspace) {
194 case ui::Dataspace::DISPLAY_P3:
195 return JNamedColorSpace::DISPLAY_P3;
196 default:
197 return JNamedColorSpace::SRGB;
198 }
199 }
200
pickDataspaceFromColorMode(const ui::ColorMode colorMode)201 constexpr ui::Dataspace pickDataspaceFromColorMode(const ui::ColorMode colorMode) {
202 switch (colorMode) {
203 case ui::ColorMode::DISPLAY_P3:
204 case ui::ColorMode::BT2100_PQ:
205 case ui::ColorMode::BT2100_HLG:
206 case ui::ColorMode::DISPLAY_BT2020:
207 return ui::Dataspace::DISPLAY_P3;
208 default:
209 return ui::Dataspace::V0_SRGB;
210 }
211 }
212
213 // ----------------------------------------------------------------------------
214
nativeCreateTransaction(JNIEnv * env,jclass clazz)215 static jlong nativeCreateTransaction(JNIEnv* env, jclass clazz) {
216 return reinterpret_cast<jlong>(new SurfaceComposerClient::Transaction);
217 }
218
releaseTransaction(SurfaceComposerClient::Transaction * t)219 static void releaseTransaction(SurfaceComposerClient::Transaction* t) {
220 delete t;
221 }
222
nativeGetNativeTransactionFinalizer(JNIEnv * env,jclass clazz)223 static jlong nativeGetNativeTransactionFinalizer(JNIEnv* env, jclass clazz) {
224 return static_cast<jlong>(reinterpret_cast<uintptr_t>(&releaseTransaction));
225 }
226
nativeCreate(JNIEnv * env,jclass clazz,jobject sessionObj,jstring nameStr,jint w,jint h,jint format,jint flags,jlong parentObject,jobject metadataParcel)227 static jlong nativeCreate(JNIEnv* env, jclass clazz, jobject sessionObj,
228 jstring nameStr, jint w, jint h, jint format, jint flags, jlong parentObject,
229 jobject metadataParcel) {
230 ScopedUtfChars name(env, nameStr);
231 sp<SurfaceComposerClient> client;
232 if (sessionObj != NULL) {
233 client = android_view_SurfaceSession_getClient(env, sessionObj);
234 } else {
235 client = SurfaceComposerClient::getDefault();
236 }
237 SurfaceControl *parent = reinterpret_cast<SurfaceControl*>(parentObject);
238 sp<SurfaceControl> surface;
239 LayerMetadata metadata;
240 Parcel* parcel = parcelForJavaObject(env, metadataParcel);
241 if (parcel && !parcel->objectsCount()) {
242 status_t err = metadata.readFromParcel(parcel);
243 if (err != NO_ERROR) {
244 jniThrowException(env, "java/lang/IllegalArgumentException",
245 "Metadata parcel has wrong format");
246 }
247 }
248
249 status_t err = client->createSurfaceChecked(
250 String8(name.c_str()), w, h, format, &surface, flags, parent, std::move(metadata));
251 if (err == NAME_NOT_FOUND) {
252 jniThrowException(env, "java/lang/IllegalArgumentException", NULL);
253 return 0;
254 } else if (err != NO_ERROR) {
255 jniThrowException(env, OutOfResourcesException, NULL);
256 return 0;
257 }
258
259 surface->incStrong((void *)nativeCreate);
260 return reinterpret_cast<jlong>(surface.get());
261 }
262
nativeRelease(JNIEnv * env,jclass clazz,jlong nativeObject)263 static void nativeRelease(JNIEnv* env, jclass clazz, jlong nativeObject) {
264 sp<SurfaceControl> ctrl(reinterpret_cast<SurfaceControl *>(nativeObject));
265 ctrl->decStrong((void *)nativeCreate);
266 }
267
nativeDisconnect(JNIEnv * env,jclass clazz,jlong nativeObject)268 static void nativeDisconnect(JNIEnv* env, jclass clazz, jlong nativeObject) {
269 SurfaceControl* const ctrl = reinterpret_cast<SurfaceControl *>(nativeObject);
270 if (ctrl != NULL) {
271 ctrl->disconnect();
272 }
273 }
274
rectFromObj(JNIEnv * env,jobject rectObj)275 static Rect rectFromObj(JNIEnv* env, jobject rectObj) {
276 int left = env->GetIntField(rectObj, gRectClassInfo.left);
277 int top = env->GetIntField(rectObj, gRectClassInfo.top);
278 int right = env->GetIntField(rectObj, gRectClassInfo.right);
279 int bottom = env->GetIntField(rectObj, gRectClassInfo.bottom);
280 return Rect(left, top, right, bottom);
281 }
282
nativeScreenshot(JNIEnv * env,jclass clazz,jobject displayTokenObj,jobject sourceCropObj,jint width,jint height,bool useIdentityTransform,int rotation,bool captureSecureLayers)283 static jobject nativeScreenshot(JNIEnv* env, jclass clazz,
284 jobject displayTokenObj, jobject sourceCropObj, jint width, jint height,
285 bool useIdentityTransform, int rotation, bool captureSecureLayers) {
286 sp<IBinder> displayToken = ibinderForJavaObject(env, displayTokenObj);
287 if (displayToken == NULL) {
288 return NULL;
289 }
290 const ui::ColorMode colorMode = SurfaceComposerClient::getActiveColorMode(displayToken);
291 const ui::Dataspace dataspace = pickDataspaceFromColorMode(colorMode);
292
293 Rect sourceCrop = rectFromObj(env, sourceCropObj);
294 sp<GraphicBuffer> buffer;
295 bool capturedSecureLayers = false;
296 status_t res = ScreenshotClient::capture(displayToken, dataspace,
297 ui::PixelFormat::RGBA_8888,
298 sourceCrop, width, height,
299 useIdentityTransform, ui::toRotation(rotation),
300 captureSecureLayers, &buffer, capturedSecureLayers);
301 if (res != NO_ERROR) {
302 return NULL;
303 }
304
305 const jint namedColorSpace = fromDataspaceToNamedColorSpaceValue(dataspace);
306 return env->CallStaticObjectMethod(gScreenshotGraphicBufferClassInfo.clazz,
307 gScreenshotGraphicBufferClassInfo.builder,
308 buffer->getWidth(),
309 buffer->getHeight(),
310 buffer->getPixelFormat(),
311 (jint)buffer->getUsage(),
312 (jlong)buffer.get(),
313 namedColorSpace,
314 capturedSecureLayers);
315 }
316
nativeCaptureLayers(JNIEnv * env,jclass clazz,jobject displayTokenObj,jlong layerObject,jobject sourceCropObj,jfloat frameScale,jlongArray excludeObjectArray,jint format)317 static jobject nativeCaptureLayers(JNIEnv* env, jclass clazz, jobject displayTokenObj,
318 jlong layerObject, jobject sourceCropObj, jfloat frameScale,
319 jlongArray excludeObjectArray, jint format) {
320
321 auto layer = reinterpret_cast<SurfaceControl *>(layerObject);
322 if (layer == NULL) {
323 return NULL;
324 }
325
326 Rect sourceCrop;
327 if (sourceCropObj != NULL) {
328 sourceCrop = rectFromObj(env, sourceCropObj);
329 }
330
331 std::unordered_set<sp<IBinder>,ISurfaceComposer::SpHash<IBinder>> excludeHandles;
332 if (excludeObjectArray != NULL) {
333 const jsize len = env->GetArrayLength(excludeObjectArray);
334 excludeHandles.reserve(len);
335
336 const jlong* objects = env->GetLongArrayElements(excludeObjectArray, nullptr);
337 for (jsize i = 0; i < len; i++) {
338 auto excludeObject = reinterpret_cast<SurfaceControl *>(objects[i]);
339 if (excludeObject == nullptr) {
340 jniThrowNullPointerException(env, "Exclude layer is null");
341 return NULL;
342 }
343 excludeHandles.emplace(excludeObject->getHandle());
344 }
345 env->ReleaseLongArrayElements(excludeObjectArray, const_cast<jlong*>(objects), JNI_ABORT);
346 }
347
348 sp<GraphicBuffer> buffer;
349 ui::Dataspace dataspace = ui::Dataspace::V0_SRGB;
350 sp<IBinder> displayToken = ibinderForJavaObject(env, displayTokenObj);
351 if (displayToken != nullptr) {
352 const ui::ColorMode colorMode = SurfaceComposerClient::getActiveColorMode(displayToken);
353 dataspace = pickDataspaceFromColorMode(colorMode);
354 }
355 status_t res = ScreenshotClient::captureChildLayers(layer->getHandle(), dataspace,
356 static_cast<ui::PixelFormat>(format),
357 sourceCrop, excludeHandles, frameScale,
358 &buffer);
359 if (res != NO_ERROR) {
360 return NULL;
361 }
362
363 const jint namedColorSpace = fromDataspaceToNamedColorSpaceValue(dataspace);
364 return env->CallStaticObjectMethod(gScreenshotGraphicBufferClassInfo.clazz,
365 gScreenshotGraphicBufferClassInfo.builder,
366 buffer->getWidth(),
367 buffer->getHeight(),
368 buffer->getPixelFormat(),
369 (jint)buffer->getUsage(),
370 (jlong)buffer.get(),
371 namedColorSpace,
372 false /* capturedSecureLayers */);
373 }
374
nativeApplyTransaction(JNIEnv * env,jclass clazz,jlong transactionObj,jboolean sync)375 static void nativeApplyTransaction(JNIEnv* env, jclass clazz, jlong transactionObj, jboolean sync) {
376 auto transaction = reinterpret_cast<SurfaceComposerClient::Transaction*>(transactionObj);
377 transaction->apply(sync);
378 }
379
nativeMergeTransaction(JNIEnv * env,jclass clazz,jlong transactionObj,jlong otherTransactionObj)380 static void nativeMergeTransaction(JNIEnv* env, jclass clazz,
381 jlong transactionObj, jlong otherTransactionObj) {
382 auto transaction = reinterpret_cast<SurfaceComposerClient::Transaction*>(transactionObj);
383 auto otherTransaction = reinterpret_cast<SurfaceComposerClient::Transaction*>(
384 otherTransactionObj);
385 transaction->merge(std::move(*otherTransaction));
386 }
387
nativeSetAnimationTransaction(JNIEnv * env,jclass clazz,jlong transactionObj)388 static void nativeSetAnimationTransaction(JNIEnv* env, jclass clazz, jlong transactionObj) {
389 auto transaction = reinterpret_cast<SurfaceComposerClient::Transaction*>(transactionObj);
390 transaction->setAnimationTransaction();
391 }
392
nativeSetEarlyWakeup(JNIEnv * env,jclass clazz,jlong transactionObj)393 static void nativeSetEarlyWakeup(JNIEnv* env, jclass clazz, jlong transactionObj) {
394 auto transaction = reinterpret_cast<SurfaceComposerClient::Transaction*>(transactionObj);
395 transaction->setEarlyWakeup();
396 }
397
nativeSetEarlyWakeupStart(JNIEnv * env,jclass clazz,jlong transactionObj)398 static void nativeSetEarlyWakeupStart(JNIEnv* env, jclass clazz, jlong transactionObj) {
399 auto transaction = reinterpret_cast<SurfaceComposerClient::Transaction*>(transactionObj);
400 transaction->setExplicitEarlyWakeupStart();
401 }
402
nativeSetEarlyWakeupEnd(JNIEnv * env,jclass clazz,jlong transactionObj)403 static void nativeSetEarlyWakeupEnd(JNIEnv* env, jclass clazz, jlong transactionObj) {
404 auto transaction = reinterpret_cast<SurfaceComposerClient::Transaction*>(transactionObj);
405 transaction->setExplicitEarlyWakeupEnd();
406 }
407
nativeSetLayer(JNIEnv * env,jclass clazz,jlong transactionObj,jlong nativeObject,jint zorder)408 static void nativeSetLayer(JNIEnv* env, jclass clazz, jlong transactionObj,
409 jlong nativeObject, jint zorder) {
410 auto transaction = reinterpret_cast<SurfaceComposerClient::Transaction*>(transactionObj);
411
412 SurfaceControl* const ctrl = reinterpret_cast<SurfaceControl *>(nativeObject);
413 transaction->setLayer(ctrl, zorder);
414 }
415
nativeSetRelativeLayer(JNIEnv * env,jclass clazz,jlong transactionObj,jlong nativeObject,jlong relativeToObject,jint zorder)416 static void nativeSetRelativeLayer(JNIEnv* env, jclass clazz, jlong transactionObj,
417 jlong nativeObject,
418 jlong relativeToObject, jint zorder) {
419
420 auto ctrl = reinterpret_cast<SurfaceControl *>(nativeObject);
421 auto relative = reinterpret_cast<SurfaceControl *>(relativeToObject);
422 auto transaction = reinterpret_cast<SurfaceComposerClient::Transaction*>(transactionObj);
423 transaction->setRelativeLayer(ctrl, relative->getHandle(), zorder);
424 }
425
nativeSetPosition(JNIEnv * env,jclass clazz,jlong transactionObj,jlong nativeObject,jfloat x,jfloat y)426 static void nativeSetPosition(JNIEnv* env, jclass clazz, jlong transactionObj,
427 jlong nativeObject, jfloat x, jfloat y) {
428 auto transaction = reinterpret_cast<SurfaceComposerClient::Transaction*>(transactionObj);
429
430 SurfaceControl* const ctrl = reinterpret_cast<SurfaceControl *>(nativeObject);
431 transaction->setPosition(ctrl, x, y);
432 }
433
nativeSetGeometry(JNIEnv * env,jclass clazz,jlong transactionObj,jlong nativeObject,jobject sourceObj,jobject dstObj,jlong orientation)434 static void nativeSetGeometry(JNIEnv* env, jclass clazz, jlong transactionObj, jlong nativeObject,
435 jobject sourceObj, jobject dstObj, jlong orientation) {
436 auto transaction = reinterpret_cast<SurfaceComposerClient::Transaction*>(transactionObj);
437 SurfaceControl* const ctrl = reinterpret_cast<SurfaceControl *>(nativeObject);
438
439 Rect source, dst;
440 if (sourceObj != NULL) {
441 source = rectFromObj(env, sourceObj);
442 } else {
443 source.makeInvalid();
444 }
445 if (dstObj != NULL) {
446 dst = rectFromObj(env, dstObj);
447 } else {
448 dst.makeInvalid();
449 }
450 transaction->setGeometry(ctrl, source, dst, orientation);
451 }
452
nativeSetSize(JNIEnv * env,jclass clazz,jlong transactionObj,jlong nativeObject,jint w,jint h)453 static void nativeSetSize(JNIEnv* env, jclass clazz, jlong transactionObj,
454 jlong nativeObject, jint w, jint h) {
455 auto transaction = reinterpret_cast<SurfaceComposerClient::Transaction*>(transactionObj);
456
457 SurfaceControl* const ctrl = reinterpret_cast<SurfaceControl *>(nativeObject);
458 transaction->setSize(ctrl, w, h);
459 }
460
nativeSetFlags(JNIEnv * env,jclass clazz,jlong transactionObj,jlong nativeObject,jint flags,jint mask)461 static void nativeSetFlags(JNIEnv* env, jclass clazz, jlong transactionObj,
462 jlong nativeObject, jint flags, jint mask) {
463 auto transaction = reinterpret_cast<SurfaceComposerClient::Transaction*>(transactionObj);
464
465 SurfaceControl* const ctrl = reinterpret_cast<SurfaceControl *>(nativeObject);
466 transaction->setFlags(ctrl, flags, mask);
467 }
468
nativeSetFrameRateSelectionPriority(JNIEnv * env,jclass clazz,jlong transactionObj,jlong nativeObject,jint priority)469 static void nativeSetFrameRateSelectionPriority(JNIEnv* env, jclass clazz, jlong transactionObj,
470 jlong nativeObject, jint priority) {
471 auto transaction = reinterpret_cast<SurfaceComposerClient::Transaction*>(transactionObj);
472
473 SurfaceControl* const ctrl = reinterpret_cast<SurfaceControl *>(nativeObject);
474 transaction->setFrameRateSelectionPriority(ctrl, priority);
475 }
476
nativeSetTransparentRegionHint(JNIEnv * env,jclass clazz,jlong transactionObj,jlong nativeObject,jobject regionObj)477 static void nativeSetTransparentRegionHint(JNIEnv* env, jclass clazz, jlong transactionObj,
478 jlong nativeObject, jobject regionObj) {
479 SurfaceControl* const ctrl = reinterpret_cast<SurfaceControl *>(nativeObject);
480 graphics::RegionIterator iterator(env, regionObj);
481 if (!iterator.isValid()) {
482 doThrowIAE(env);
483 return;
484 }
485
486 ARect bounds = iterator.getTotalBounds();
487 Region reg({bounds.left, bounds.top, bounds.right, bounds.bottom});
488 if (iterator.isComplex()) {
489 while (!iterator.isDone()) {
490 ARect rect = iterator.getRect();
491 reg.addRectUnchecked(rect.left, rect.top, rect.right, rect.bottom);
492 iterator.next();
493 }
494 }
495
496 {
497 auto transaction = reinterpret_cast<SurfaceComposerClient::Transaction*>(transactionObj);
498 transaction->setTransparentRegionHint(ctrl, reg);
499 }
500 }
501
nativeSetAlpha(JNIEnv * env,jclass clazz,jlong transactionObj,jlong nativeObject,jfloat alpha)502 static void nativeSetAlpha(JNIEnv* env, jclass clazz, jlong transactionObj,
503 jlong nativeObject, jfloat alpha) {
504 auto transaction = reinterpret_cast<SurfaceComposerClient::Transaction*>(transactionObj);
505
506 SurfaceControl* const ctrl = reinterpret_cast<SurfaceControl *>(nativeObject);
507 transaction->setAlpha(ctrl, alpha);
508 }
509
nativeSetInputWindowInfo(JNIEnv * env,jclass clazz,jlong transactionObj,jlong nativeObject,jobject inputWindow)510 static void nativeSetInputWindowInfo(JNIEnv* env, jclass clazz, jlong transactionObj,
511 jlong nativeObject, jobject inputWindow) {
512 auto transaction = reinterpret_cast<SurfaceComposerClient::Transaction*>(transactionObj);
513
514 sp<NativeInputWindowHandle> handle = android_view_InputWindowHandle_getHandle(
515 env, inputWindow);
516 handle->updateInfo();
517
518 auto ctrl = reinterpret_cast<SurfaceControl *>(nativeObject);
519 transaction->setInputWindowInfo(ctrl, *handle->getInfo());
520 }
521
nativeSyncInputWindows(JNIEnv * env,jclass clazz,jlong transactionObj)522 static void nativeSyncInputWindows(JNIEnv* env, jclass clazz, jlong transactionObj) {
523 auto transaction = reinterpret_cast<SurfaceComposerClient::Transaction*>(transactionObj);
524 transaction->syncInputWindows();
525 }
526
nativeSetMetadata(JNIEnv * env,jclass clazz,jlong transactionObj,jlong nativeObject,jint id,jobject parcelObj)527 static void nativeSetMetadata(JNIEnv* env, jclass clazz, jlong transactionObj,
528 jlong nativeObject, jint id, jobject parcelObj) {
529 Parcel* parcel = parcelForJavaObject(env, parcelObj);
530 if (!parcel) {
531 jniThrowNullPointerException(env, "attribute data");
532 return;
533 }
534 if (parcel->objectsCount()) {
535 jniThrowException(env, "java/lang/RuntimeException",
536 "Tried to marshall a Parcel that contained Binder objects.");
537 return;
538 }
539
540 auto transaction = reinterpret_cast<SurfaceComposerClient::Transaction*>(transactionObj);
541
542 SurfaceControl* const ctrl = reinterpret_cast<SurfaceControl*>(nativeObject);
543 transaction->setMetadata(ctrl, id, *parcel);
544 }
545
nativeSetColor(JNIEnv * env,jclass clazz,jlong transactionObj,jlong nativeObject,jfloatArray fColor)546 static void nativeSetColor(JNIEnv* env, jclass clazz, jlong transactionObj,
547 jlong nativeObject, jfloatArray fColor) {
548 auto transaction = reinterpret_cast<SurfaceComposerClient::Transaction*>(transactionObj);
549 SurfaceControl* const ctrl = reinterpret_cast<SurfaceControl *>(nativeObject);
550
551 float* floatColors = env->GetFloatArrayElements(fColor, 0);
552 half3 color(floatColors[0], floatColors[1], floatColors[2]);
553 transaction->setColor(ctrl, color);
554 env->ReleaseFloatArrayElements(fColor, floatColors, 0);
555 }
556
nativeSetMatrix(JNIEnv * env,jclass clazz,jlong transactionObj,jlong nativeObject,jfloat dsdx,jfloat dtdx,jfloat dtdy,jfloat dsdy)557 static void nativeSetMatrix(JNIEnv* env, jclass clazz, jlong transactionObj,
558 jlong nativeObject,
559 jfloat dsdx, jfloat dtdx, jfloat dtdy, jfloat dsdy) {
560 auto transaction = reinterpret_cast<SurfaceComposerClient::Transaction*>(transactionObj);
561
562 SurfaceControl* const ctrl = reinterpret_cast<SurfaceControl *>(nativeObject);
563 transaction->setMatrix(ctrl, dsdx, dtdx, dtdy, dsdy);
564 }
565
nativeSetColorTransform(JNIEnv * env,jclass clazz,jlong transactionObj,jlong nativeObject,jfloatArray fMatrix,jfloatArray fTranslation)566 static void nativeSetColorTransform(JNIEnv* env, jclass clazz, jlong transactionObj,
567 jlong nativeObject, jfloatArray fMatrix, jfloatArray fTranslation) {
568 auto transaction = reinterpret_cast<SurfaceComposerClient::Transaction*>(transactionObj);
569 SurfaceControl* const surfaceControl = reinterpret_cast<SurfaceControl*>(nativeObject);
570 float* floatMatrix = env->GetFloatArrayElements(fMatrix, 0);
571 mat3 matrix(static_cast<float const*>(floatMatrix));
572 env->ReleaseFloatArrayElements(fMatrix, floatMatrix, 0);
573
574 float* floatTranslation = env->GetFloatArrayElements(fTranslation, 0);
575 vec3 translation(floatTranslation[0], floatTranslation[1], floatTranslation[2]);
576 env->ReleaseFloatArrayElements(fTranslation, floatTranslation, 0);
577
578 transaction->setColorTransform(surfaceControl, matrix, translation);
579 }
580
nativeSetColorSpaceAgnostic(JNIEnv * env,jclass clazz,jlong transactionObj,jlong nativeObject,jboolean agnostic)581 static void nativeSetColorSpaceAgnostic(JNIEnv* env, jclass clazz, jlong transactionObj,
582 jlong nativeObject, jboolean agnostic) {
583 auto transaction = reinterpret_cast<SurfaceComposerClient::Transaction*>(transactionObj);
584 SurfaceControl* const surfaceControl = reinterpret_cast<SurfaceControl*>(nativeObject);
585 transaction->setColorSpaceAgnostic(surfaceControl, agnostic);
586 }
587
nativeSetWindowCrop(JNIEnv * env,jclass clazz,jlong transactionObj,jlong nativeObject,jint l,jint t,jint r,jint b)588 static void nativeSetWindowCrop(JNIEnv* env, jclass clazz, jlong transactionObj,
589 jlong nativeObject,
590 jint l, jint t, jint r, jint b) {
591 auto transaction = reinterpret_cast<SurfaceComposerClient::Transaction*>(transactionObj);
592
593 SurfaceControl* const ctrl = reinterpret_cast<SurfaceControl *>(nativeObject);
594 Rect crop(l, t, r, b);
595 transaction->setCrop_legacy(ctrl, crop);
596 }
597
nativeSetCornerRadius(JNIEnv * env,jclass clazz,jlong transactionObj,jlong nativeObject,jfloat cornerRadius)598 static void nativeSetCornerRadius(JNIEnv* env, jclass clazz, jlong transactionObj,
599 jlong nativeObject, jfloat cornerRadius) {
600 auto transaction = reinterpret_cast<SurfaceComposerClient::Transaction*>(transactionObj);
601
602 SurfaceControl* const ctrl = reinterpret_cast<SurfaceControl *>(nativeObject);
603 transaction->setCornerRadius(ctrl, cornerRadius);
604 }
605
nativeSetBackgroundBlurRadius(JNIEnv * env,jclass clazz,jlong transactionObj,jlong nativeObject,jint blurRadius)606 static void nativeSetBackgroundBlurRadius(JNIEnv* env, jclass clazz, jlong transactionObj,
607 jlong nativeObject, jint blurRadius) {
608 auto transaction = reinterpret_cast<SurfaceComposerClient::Transaction*>(transactionObj);
609
610 SurfaceControl* const ctrl = reinterpret_cast<SurfaceControl *>(nativeObject);
611 transaction->setBackgroundBlurRadius(ctrl, blurRadius);
612 }
613
nativeSetLayerStack(JNIEnv * env,jclass clazz,jlong transactionObj,jlong nativeObject,jint layerStack)614 static void nativeSetLayerStack(JNIEnv* env, jclass clazz, jlong transactionObj,
615 jlong nativeObject, jint layerStack) {
616 auto transaction = reinterpret_cast<SurfaceComposerClient::Transaction*>(transactionObj);
617
618 SurfaceControl* const ctrl = reinterpret_cast<SurfaceControl *>(nativeObject);
619 transaction->setLayerStack(ctrl, layerStack);
620 }
621
nativeSetShadowRadius(JNIEnv * env,jclass clazz,jlong transactionObj,jlong nativeObject,jfloat shadowRadius)622 static void nativeSetShadowRadius(JNIEnv* env, jclass clazz, jlong transactionObj,
623 jlong nativeObject, jfloat shadowRadius) {
624 auto transaction = reinterpret_cast<SurfaceComposerClient::Transaction*>(transactionObj);
625
626 const auto ctrl = reinterpret_cast<SurfaceControl *>(nativeObject);
627 transaction->setShadowRadius(ctrl, shadowRadius);
628 }
629
nativeSetFrameRate(JNIEnv * env,jclass clazz,jlong transactionObj,jlong nativeObject,jfloat frameRate,jint compatibility)630 static void nativeSetFrameRate(JNIEnv* env, jclass clazz, jlong transactionObj, jlong nativeObject,
631 jfloat frameRate, jint compatibility) {
632 auto transaction = reinterpret_cast<SurfaceComposerClient::Transaction*>(transactionObj);
633
634 const auto ctrl = reinterpret_cast<SurfaceControl*>(nativeObject);
635 // Our compatibility is a Surface.FRAME_RATE_COMPATIBILITY_* value, and
636 // Transaction::setFrameRate() takes an ANATIVEWINDOW_FRAME_RATE_COMPATIBILITY_* value. The
637 // values are identical though, so no need to convert anything.
638 transaction->setFrameRate(ctrl, frameRate, static_cast<int8_t>(compatibility));
639 }
640
nativeAcquireFrameRateFlexibilityToken(JNIEnv * env,jclass clazz)641 static jlong nativeAcquireFrameRateFlexibilityToken(JNIEnv* env, jclass clazz) {
642 sp<ISurfaceComposer> composer = ComposerService::getComposerService();
643 sp<IBinder> token;
644 status_t result = composer->acquireFrameRateFlexibilityToken(&token);
645 if (result < 0) {
646 ALOGE("Failed acquiring frame rate flexibility token: %s (%d)", strerror(-result), result);
647 return 0;
648 }
649 token->incStrong((void*)nativeAcquireFrameRateFlexibilityToken);
650 return reinterpret_cast<jlong>(token.get());
651 }
652
nativeReleaseFrameRateFlexibilityToken(JNIEnv * env,jclass clazz,jlong tokenLong)653 static void nativeReleaseFrameRateFlexibilityToken(JNIEnv* env, jclass clazz, jlong tokenLong) {
654 sp<IBinder> token(reinterpret_cast<IBinder*>(tokenLong));
655 token->decStrong((void*)nativeAcquireFrameRateFlexibilityToken);
656 }
657
nativeSetFixedTransformHint(JNIEnv * env,jclass clazz,jlong transactionObj,jlong nativeObject,jint transformHint)658 static void nativeSetFixedTransformHint(JNIEnv* env, jclass clazz, jlong transactionObj,
659 jlong nativeObject, jint transformHint) {
660 auto transaction = reinterpret_cast<SurfaceComposerClient::Transaction*>(transactionObj);
661
662 SurfaceControl* const ctrl = reinterpret_cast<SurfaceControl*>(nativeObject);
663 transaction->setFixedTransformHint(ctrl, transformHint);
664 }
665
nativeGetPhysicalDisplayIds(JNIEnv * env,jclass clazz)666 static jlongArray nativeGetPhysicalDisplayIds(JNIEnv* env, jclass clazz) {
667 const auto displayIds = SurfaceComposerClient::getPhysicalDisplayIds();
668 jlongArray array = env->NewLongArray(displayIds.size());
669 if (array == nullptr) {
670 jniThrowException(env, "java/lang/OutOfMemoryError", nullptr);
671 return nullptr;
672 }
673
674 if (displayIds.empty()) {
675 return array;
676 }
677
678 jlong* values = env->GetLongArrayElements(array, 0);
679 for (size_t i = 0; i < displayIds.size(); ++i) {
680 values[i] = static_cast<jlong>(displayIds[i]);
681 }
682
683 env->ReleaseLongArrayElements(array, values, 0);
684 return array;
685 }
686
nativeGetPhysicalDisplayToken(JNIEnv * env,jclass clazz,jlong physicalDisplayId)687 static jobject nativeGetPhysicalDisplayToken(JNIEnv* env, jclass clazz, jlong physicalDisplayId) {
688 sp<IBinder> token = SurfaceComposerClient::getPhysicalDisplayToken(physicalDisplayId);
689 return javaObjectForIBinder(env, token);
690 }
691
nativeGetDisplayedContentSamplingAttributes(JNIEnv * env,jclass clazz,jobject tokenObj)692 static jobject nativeGetDisplayedContentSamplingAttributes(JNIEnv* env, jclass clazz,
693 jobject tokenObj) {
694 sp<IBinder> token(ibinderForJavaObject(env, tokenObj));
695
696 ui::PixelFormat format;
697 ui::Dataspace dataspace;
698 uint8_t componentMask;
699 status_t err = SurfaceComposerClient::getDisplayedContentSamplingAttributes(
700 token, &format, &dataspace, &componentMask);
701 if (err != OK) {
702 return nullptr;
703 }
704 return env->NewObject(gDisplayedContentSamplingAttributesClassInfo.clazz,
705 gDisplayedContentSamplingAttributesClassInfo.ctor,
706 format, dataspace, componentMask);
707 }
708
nativeSetDisplayedContentSamplingEnabled(JNIEnv * env,jclass clazz,jobject tokenObj,jboolean enable,jint componentMask,jint maxFrames)709 static jboolean nativeSetDisplayedContentSamplingEnabled(JNIEnv* env, jclass clazz,
710 jobject tokenObj, jboolean enable, jint componentMask, jint maxFrames) {
711 sp<IBinder> token(ibinderForJavaObject(env, tokenObj));
712 status_t rc = SurfaceComposerClient::setDisplayContentSamplingEnabled(
713 token, enable, componentMask, maxFrames);
714 return rc == OK;
715 }
716
nativeGetDisplayedContentSample(JNIEnv * env,jclass clazz,jobject tokenObj,jlong maxFrames,jlong timestamp)717 static jobject nativeGetDisplayedContentSample(JNIEnv* env, jclass clazz, jobject tokenObj,
718 jlong maxFrames, jlong timestamp) {
719 sp<IBinder> token(ibinderForJavaObject(env, tokenObj));
720
721 DisplayedFrameStats stats;
722 status_t err = SurfaceComposerClient::getDisplayedContentSample(
723 token, maxFrames, timestamp, &stats);
724 if (err != OK) {
725 return nullptr;
726 }
727
728 jlongArray histogramComponent0 = env->NewLongArray(stats.component_0_sample.size());
729 jlongArray histogramComponent1 = env->NewLongArray(stats.component_1_sample.size());
730 jlongArray histogramComponent2 = env->NewLongArray(stats.component_2_sample.size());
731 jlongArray histogramComponent3 = env->NewLongArray(stats.component_3_sample.size());
732 if ((histogramComponent0 == nullptr) ||
733 (histogramComponent1 == nullptr) ||
734 (histogramComponent2 == nullptr) ||
735 (histogramComponent3 == nullptr)) {
736 return JNI_FALSE;
737 }
738
739 env->SetLongArrayRegion(histogramComponent0, 0,
740 stats.component_0_sample.size(),
741 reinterpret_cast<jlong*>(stats.component_0_sample.data()));
742 env->SetLongArrayRegion(histogramComponent1, 0,
743 stats.component_1_sample.size(),
744 reinterpret_cast<jlong*>(stats.component_1_sample.data()));
745 env->SetLongArrayRegion(histogramComponent2, 0,
746 stats.component_2_sample.size(),
747 reinterpret_cast<jlong*>(stats.component_2_sample.data()));
748 env->SetLongArrayRegion(histogramComponent3, 0,
749 stats.component_3_sample.size(),
750 reinterpret_cast<jlong*>(stats.component_3_sample.data()));
751 return env->NewObject(gDisplayedContentSampleClassInfo.clazz,
752 gDisplayedContentSampleClassInfo.ctor,
753 stats.numFrames,
754 histogramComponent0,
755 histogramComponent1,
756 histogramComponent2,
757 histogramComponent3);
758 }
759
nativeCreateDisplay(JNIEnv * env,jclass clazz,jstring nameObj,jboolean secure)760 static jobject nativeCreateDisplay(JNIEnv* env, jclass clazz, jstring nameObj,
761 jboolean secure) {
762 ScopedUtfChars name(env, nameObj);
763 sp<IBinder> token(SurfaceComposerClient::createDisplay(
764 String8(name.c_str()), bool(secure)));
765 return javaObjectForIBinder(env, token);
766 }
767
nativeDestroyDisplay(JNIEnv * env,jclass clazz,jobject tokenObj)768 static void nativeDestroyDisplay(JNIEnv* env, jclass clazz, jobject tokenObj) {
769 sp<IBinder> token(ibinderForJavaObject(env, tokenObj));
770 if (token == NULL) return;
771 SurfaceComposerClient::destroyDisplay(token);
772 }
773
nativeSetDisplaySurface(JNIEnv * env,jclass clazz,jlong transactionObj,jobject tokenObj,jlong nativeSurfaceObject)774 static void nativeSetDisplaySurface(JNIEnv* env, jclass clazz,
775 jlong transactionObj,
776 jobject tokenObj, jlong nativeSurfaceObject) {
777 sp<IBinder> token(ibinderForJavaObject(env, tokenObj));
778 if (token == NULL) return;
779 sp<IGraphicBufferProducer> bufferProducer;
780 sp<Surface> sur(reinterpret_cast<Surface *>(nativeSurfaceObject));
781 if (sur != NULL) {
782 bufferProducer = sur->getIGraphicBufferProducer();
783 }
784
785
786 status_t err = NO_ERROR;
787 {
788 auto transaction = reinterpret_cast<SurfaceComposerClient::Transaction*>(transactionObj);
789 err = transaction->setDisplaySurface(token,
790 bufferProducer);
791 }
792 if (err != NO_ERROR) {
793 doThrowIAE(env, "Illegal Surface, could not enable async mode. Was this"
794 " Surface created with singleBufferMode?");
795 }
796 }
797
nativeSetDisplayLayerStack(JNIEnv * env,jclass clazz,jlong transactionObj,jobject tokenObj,jint layerStack)798 static void nativeSetDisplayLayerStack(JNIEnv* env, jclass clazz,
799 jlong transactionObj,
800 jobject tokenObj, jint layerStack) {
801
802 sp<IBinder> token(ibinderForJavaObject(env, tokenObj));
803 if (token == NULL) return;
804
805 {
806 auto transaction = reinterpret_cast<SurfaceComposerClient::Transaction*>(transactionObj);
807 transaction->setDisplayLayerStack(token, layerStack);
808 }
809 }
810
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)811 static void nativeSetDisplayProjection(JNIEnv* env, jclass clazz,
812 jlong transactionObj,
813 jobject tokenObj, jint orientation,
814 jint layerStackRect_left, jint layerStackRect_top, jint layerStackRect_right, jint layerStackRect_bottom,
815 jint displayRect_left, jint displayRect_top, jint displayRect_right, jint displayRect_bottom) {
816 sp<IBinder> token(ibinderForJavaObject(env, tokenObj));
817 if (token == NULL) return;
818 Rect layerStackRect(layerStackRect_left, layerStackRect_top, layerStackRect_right, layerStackRect_bottom);
819 Rect displayRect(displayRect_left, displayRect_top, displayRect_right, displayRect_bottom);
820
821 {
822 auto transaction = reinterpret_cast<SurfaceComposerClient::Transaction*>(transactionObj);
823 transaction->setDisplayProjection(token, static_cast<ui::Rotation>(orientation),
824 layerStackRect, displayRect);
825 }
826 }
827
nativeSetDisplaySize(JNIEnv * env,jclass clazz,jlong transactionObj,jobject tokenObj,jint width,jint height)828 static void nativeSetDisplaySize(JNIEnv* env, jclass clazz,
829 jlong transactionObj,
830 jobject tokenObj, jint width, jint height) {
831 sp<IBinder> token(ibinderForJavaObject(env, tokenObj));
832 if (token == NULL) return;
833
834 {
835 auto transaction = reinterpret_cast<SurfaceComposerClient::Transaction*>(transactionObj);
836 transaction->setDisplaySize(token, width, height);
837 }
838 }
839
convertDeviceProductInfoToJavaObject(JNIEnv * env,const std::optional<DeviceProductInfo> & info)840 static jobject convertDeviceProductInfoToJavaObject(
841 JNIEnv* env, const std::optional<DeviceProductInfo>& info) {
842 using ModelYear = android::DeviceProductInfo::ModelYear;
843 using ManufactureYear = android::DeviceProductInfo::ManufactureYear;
844 using ManufactureWeekAndYear = android::DeviceProductInfo::ManufactureWeekAndYear;
845
846 if (!info) return nullptr;
847 jstring name = env->NewStringUTF(info->name.data());
848 jstring manufacturerPnpId = env->NewStringUTF(info->manufacturerPnpId.data());
849 jobject productId = env->NewStringUTF(info->productId.data());
850 const auto& date = info->manufactureOrModelDate;
851 jobject modelYear, manufactureDate;
852 if (const auto* model = std::get_if<ModelYear>(&date)) {
853 modelYear = toInteger(env, model->year);
854 manufactureDate = nullptr;
855 } else if (const auto* manufactureWeekAndYear = std::get_if<ManufactureWeekAndYear>(&date)) {
856 modelYear = nullptr;
857 manufactureDate = env->NewObject(gDeviceProductInfoManufactureDateClassInfo.clazz,
858 gDeviceProductInfoManufactureDateClassInfo.ctor,
859 toInteger(env, manufactureWeekAndYear->week),
860 toInteger(env, manufactureWeekAndYear->year));
861 } else if (const auto* manufactureYear = std::get_if<ManufactureYear>(&date)) {
862 modelYear = nullptr;
863 manufactureDate = env->NewObject(gDeviceProductInfoManufactureDateClassInfo.clazz,
864 gDeviceProductInfoManufactureDateClassInfo.ctor,
865 nullptr,
866 toInteger(env, manufactureYear->year));
867 } else {
868 LOG_FATAL("Unknown alternative for variant DeviceProductInfo::ManufactureOrModelDate");
869 }
870
871 jintArray relativeAddress = nullptr;
872 if (info->relativeAddress != DeviceProductInfo::NO_RELATIVE_ADDRESS) {
873 relativeAddress = env->NewIntArray(info->relativeAddress.size());
874 jint* relativeAddressData = env->GetIntArrayElements(relativeAddress, nullptr);
875 for (size_t i = 0; i < info->relativeAddress.size(); i++) {
876 relativeAddressData[i] = static_cast<jint>(info->relativeAddress[i]);
877 }
878 env->ReleaseIntArrayElements(relativeAddress, relativeAddressData, 0);
879 }
880 return env->NewObject(gDeviceProductInfoClassInfo.clazz, gDeviceProductInfoClassInfo.ctor, name,
881 manufacturerPnpId, productId, modelYear, manufactureDate,
882 relativeAddress);
883 }
884
nativeGetDisplayInfo(JNIEnv * env,jclass clazz,jobject tokenObj)885 static jobject nativeGetDisplayInfo(JNIEnv* env, jclass clazz, jobject tokenObj) {
886 DisplayInfo info;
887 if (const auto token = ibinderForJavaObject(env, tokenObj);
888 !token || SurfaceComposerClient::getDisplayInfo(token, &info) != NO_ERROR) {
889 return nullptr;
890 }
891
892 jobject object = env->NewObject(gDisplayInfoClassInfo.clazz, gDisplayInfoClassInfo.ctor);
893 env->SetBooleanField(object, gDisplayInfoClassInfo.isInternal,
894 info.connectionType == DisplayConnectionType::Internal);
895 env->SetFloatField(object, gDisplayInfoClassInfo.density, info.density);
896 env->SetBooleanField(object, gDisplayInfoClassInfo.secure, info.secure);
897 env->SetObjectField(object, gDisplayInfoClassInfo.deviceProductInfo,
898 convertDeviceProductInfoToJavaObject(env, info.deviceProductInfo));
899 return object;
900 }
901
nativeGetDisplayConfigs(JNIEnv * env,jclass clazz,jobject tokenObj)902 static jobjectArray nativeGetDisplayConfigs(JNIEnv* env, jclass clazz, jobject tokenObj) {
903 Vector<DisplayConfig> configs;
904 if (const auto token = ibinderForJavaObject(env, tokenObj); !token ||
905 SurfaceComposerClient::getDisplayConfigs(token, &configs) != NO_ERROR ||
906 configs.isEmpty()) {
907 return nullptr;
908 }
909
910 jobjectArray configArray =
911 env->NewObjectArray(configs.size(), gDisplayConfigClassInfo.clazz, nullptr);
912
913 for (size_t c = 0; c < configs.size(); ++c) {
914 const DisplayConfig& config = configs[c];
915 jobject object =
916 env->NewObject(gDisplayConfigClassInfo.clazz, gDisplayConfigClassInfo.ctor);
917 env->SetIntField(object, gDisplayConfigClassInfo.width, config.resolution.getWidth());
918 env->SetIntField(object, gDisplayConfigClassInfo.height, config.resolution.getHeight());
919 env->SetFloatField(object, gDisplayConfigClassInfo.xDpi, config.xDpi);
920 env->SetFloatField(object, gDisplayConfigClassInfo.yDpi, config.yDpi);
921
922 env->SetFloatField(object, gDisplayConfigClassInfo.refreshRate, config.refreshRate);
923 env->SetLongField(object, gDisplayConfigClassInfo.appVsyncOffsetNanos,
924 config.appVsyncOffset);
925 env->SetLongField(object, gDisplayConfigClassInfo.presentationDeadlineNanos,
926 config.presentationDeadline);
927 env->SetIntField(object, gDisplayConfigClassInfo.configGroup, config.configGroup);
928 env->SetObjectArrayElement(configArray, static_cast<jsize>(c), object);
929 env->DeleteLocalRef(object);
930 }
931
932 return configArray;
933 }
934
nativeSetDesiredDisplayConfigSpecs(JNIEnv * env,jclass clazz,jobject tokenObj,jobject desiredDisplayConfigSpecs)935 static jboolean nativeSetDesiredDisplayConfigSpecs(JNIEnv* env, jclass clazz, jobject tokenObj,
936 jobject desiredDisplayConfigSpecs) {
937 sp<IBinder> token(ibinderForJavaObject(env, tokenObj));
938 if (token == nullptr) return JNI_FALSE;
939
940 jint defaultConfig = env->GetIntField(desiredDisplayConfigSpecs,
941 gDesiredDisplayConfigSpecsClassInfo.defaultConfig);
942 jfloat primaryRefreshRateMin =
943 env->GetFloatField(desiredDisplayConfigSpecs,
944 gDesiredDisplayConfigSpecsClassInfo.primaryRefreshRateMin);
945 jfloat primaryRefreshRateMax =
946 env->GetFloatField(desiredDisplayConfigSpecs,
947 gDesiredDisplayConfigSpecsClassInfo.primaryRefreshRateMax);
948 jfloat appRequestRefreshRateMin =
949 env->GetFloatField(desiredDisplayConfigSpecs,
950 gDesiredDisplayConfigSpecsClassInfo.appRequestRefreshRateMin);
951 jfloat appRequestRefreshRateMax =
952 env->GetFloatField(desiredDisplayConfigSpecs,
953 gDesiredDisplayConfigSpecsClassInfo.appRequestRefreshRateMax);
954
955 size_t result = SurfaceComposerClient::setDesiredDisplayConfigSpecs(token, defaultConfig,
956 primaryRefreshRateMin,
957 primaryRefreshRateMax,
958 appRequestRefreshRateMin,
959 appRequestRefreshRateMax);
960 return result == NO_ERROR ? JNI_TRUE : JNI_FALSE;
961 }
962
nativeGetDesiredDisplayConfigSpecs(JNIEnv * env,jclass clazz,jobject tokenObj)963 static jobject nativeGetDesiredDisplayConfigSpecs(JNIEnv* env, jclass clazz, jobject tokenObj) {
964 sp<IBinder> token(ibinderForJavaObject(env, tokenObj));
965 if (token == nullptr) return nullptr;
966
967 int32_t defaultConfig;
968 float primaryRefreshRateMin;
969 float primaryRefreshRateMax;
970 float appRequestRefreshRateMin;
971 float appRequestRefreshRateMax;
972 if (SurfaceComposerClient::getDesiredDisplayConfigSpecs(token, &defaultConfig,
973 &primaryRefreshRateMin,
974 &primaryRefreshRateMax,
975 &appRequestRefreshRateMin,
976 &appRequestRefreshRateMax) !=
977 NO_ERROR) {
978 return nullptr;
979 }
980
981 return env->NewObject(gDesiredDisplayConfigSpecsClassInfo.clazz,
982 gDesiredDisplayConfigSpecsClassInfo.ctor, defaultConfig,
983 primaryRefreshRateMin, primaryRefreshRateMax, appRequestRefreshRateMin,
984 appRequestRefreshRateMax);
985 }
986
nativeGetActiveConfig(JNIEnv * env,jclass clazz,jobject tokenObj)987 static jint nativeGetActiveConfig(JNIEnv* env, jclass clazz, jobject tokenObj) {
988 sp<IBinder> token(ibinderForJavaObject(env, tokenObj));
989 if (token == NULL) return -1;
990 return static_cast<jint>(SurfaceComposerClient::getActiveConfig(token));
991 }
992
nativeGetDisplayColorModes(JNIEnv * env,jclass,jobject tokenObj)993 static jintArray nativeGetDisplayColorModes(JNIEnv* env, jclass, jobject tokenObj) {
994 sp<IBinder> token(ibinderForJavaObject(env, tokenObj));
995 if (token == NULL) return NULL;
996 Vector<ui::ColorMode> colorModes;
997 if (SurfaceComposerClient::getDisplayColorModes(token, &colorModes) != NO_ERROR ||
998 colorModes.isEmpty()) {
999 return NULL;
1000 }
1001
1002 jintArray colorModesArray = env->NewIntArray(colorModes.size());
1003 if (colorModesArray == NULL) {
1004 jniThrowException(env, "java/lang/OutOfMemoryError", NULL);
1005 return NULL;
1006 }
1007 jint* colorModesArrayValues = env->GetIntArrayElements(colorModesArray, 0);
1008 for (size_t i = 0; i < colorModes.size(); i++) {
1009 colorModesArrayValues[i] = static_cast<jint>(colorModes[i]);
1010 }
1011 env->ReleaseIntArrayElements(colorModesArray, colorModesArrayValues, 0);
1012 return colorModesArray;
1013 }
1014
nativeGetDisplayNativePrimaries(JNIEnv * env,jclass,jobject tokenObj)1015 static jobject nativeGetDisplayNativePrimaries(JNIEnv* env, jclass, jobject tokenObj) {
1016 sp<IBinder> token(ibinderForJavaObject(env, tokenObj));
1017 if (token == NULL) return NULL;
1018
1019 ui::DisplayPrimaries primaries;
1020 if (SurfaceComposerClient::getDisplayNativePrimaries(token, primaries) != NO_ERROR) {
1021 return NULL;
1022 }
1023
1024 jobject jred = env->NewObject(gCieXyzClassInfo.clazz, gCieXyzClassInfo.ctor);
1025 if (jred == NULL) {
1026 jniThrowException(env, "java/lang/OutOfMemoryError", NULL);
1027 return NULL;
1028 }
1029
1030 jobject jgreen = env->NewObject(gCieXyzClassInfo.clazz, gCieXyzClassInfo.ctor);
1031 if (jgreen == NULL) {
1032 jniThrowException(env, "java/lang/OutOfMemoryError", NULL);
1033 return NULL;
1034 }
1035
1036 jobject jblue = env->NewObject(gCieXyzClassInfo.clazz, gCieXyzClassInfo.ctor);
1037 if (jblue == NULL) {
1038 jniThrowException(env, "java/lang/OutOfMemoryError", NULL);
1039 return NULL;
1040 }
1041
1042 jobject jwhite = env->NewObject(gCieXyzClassInfo.clazz, gCieXyzClassInfo.ctor);
1043 if (jwhite == NULL) {
1044 jniThrowException(env, "java/lang/OutOfMemoryError", NULL);
1045 return NULL;
1046 }
1047
1048 jobject jprimaries = env->NewObject(gDisplayPrimariesClassInfo.clazz,
1049 gDisplayPrimariesClassInfo.ctor);
1050 if (jprimaries == NULL) {
1051 jniThrowException(env, "java/lang/OutOfMemoryError", NULL);
1052 return NULL;
1053 }
1054
1055 env->SetFloatField(jred, gCieXyzClassInfo.X, primaries.red.X);
1056 env->SetFloatField(jred, gCieXyzClassInfo.Y, primaries.red.Y);
1057 env->SetFloatField(jred, gCieXyzClassInfo.Z, primaries.red.Z);
1058 env->SetFloatField(jgreen, gCieXyzClassInfo.X, primaries.green.X);
1059 env->SetFloatField(jgreen, gCieXyzClassInfo.Y, primaries.green.Y);
1060 env->SetFloatField(jgreen, gCieXyzClassInfo.Z, primaries.green.Z);
1061 env->SetFloatField(jblue, gCieXyzClassInfo.X, primaries.blue.X);
1062 env->SetFloatField(jblue, gCieXyzClassInfo.Y, primaries.blue.Y);
1063 env->SetFloatField(jblue, gCieXyzClassInfo.Z, primaries.blue.Z);
1064 env->SetFloatField(jwhite, gCieXyzClassInfo.X, primaries.white.X);
1065 env->SetFloatField(jwhite, gCieXyzClassInfo.Y, primaries.white.Y);
1066 env->SetFloatField(jwhite, gCieXyzClassInfo.Z, primaries.white.Z);
1067 env->SetObjectField(jprimaries, gDisplayPrimariesClassInfo.red, jred);
1068 env->SetObjectField(jprimaries, gDisplayPrimariesClassInfo.green, jgreen);
1069 env->SetObjectField(jprimaries, gDisplayPrimariesClassInfo.blue, jblue);
1070 env->SetObjectField(jprimaries, gDisplayPrimariesClassInfo.white, jwhite);
1071
1072 return jprimaries;
1073 }
1074
nativeGetActiveColorMode(JNIEnv * env,jclass,jobject tokenObj)1075 static jint nativeGetActiveColorMode(JNIEnv* env, jclass, jobject tokenObj) {
1076 sp<IBinder> token(ibinderForJavaObject(env, tokenObj));
1077 if (token == NULL) return -1;
1078 return static_cast<jint>(SurfaceComposerClient::getActiveColorMode(token));
1079 }
1080
nativeGetCompositionDataspaces(JNIEnv * env,jclass)1081 static jintArray nativeGetCompositionDataspaces(JNIEnv* env, jclass) {
1082 ui::Dataspace defaultDataspace, wcgDataspace;
1083 ui::PixelFormat defaultPixelFormat, wcgPixelFormat;
1084 if (SurfaceComposerClient::getCompositionPreference(&defaultDataspace,
1085 &defaultPixelFormat,
1086 &wcgDataspace,
1087 &wcgPixelFormat) != NO_ERROR) {
1088 return nullptr;
1089 }
1090 jintArray array = env->NewIntArray(2);
1091 if (array == nullptr) {
1092 jniThrowException(env, "java/lang/OutOfMemoryError", nullptr);
1093 return nullptr;
1094 }
1095 jint* arrayValues = env->GetIntArrayElements(array, 0);
1096 arrayValues[0] = static_cast<jint>(defaultDataspace);
1097 arrayValues[1] = static_cast<jint>(wcgDataspace);
1098 env->ReleaseIntArrayElements(array, arrayValues, 0);
1099 return array;
1100 }
1101
nativeSetActiveColorMode(JNIEnv * env,jclass,jobject tokenObj,jint colorMode)1102 static jboolean nativeSetActiveColorMode(JNIEnv* env, jclass,
1103 jobject tokenObj, jint colorMode) {
1104 sp<IBinder> token(ibinderForJavaObject(env, tokenObj));
1105 if (token == NULL) return JNI_FALSE;
1106 status_t err = SurfaceComposerClient::setActiveColorMode(token,
1107 static_cast<ui::ColorMode>(colorMode));
1108 return err == NO_ERROR ? JNI_TRUE : JNI_FALSE;
1109 }
1110
nativeSetDisplayPowerMode(JNIEnv * env,jclass clazz,jobject tokenObj,jint mode)1111 static void nativeSetDisplayPowerMode(JNIEnv* env, jclass clazz, jobject tokenObj, jint mode) {
1112 sp<IBinder> token(ibinderForJavaObject(env, tokenObj));
1113 if (token == NULL) return;
1114
1115 android::base::Timer t;
1116 SurfaceComposerClient::setDisplayPowerMode(token, mode);
1117 if (t.duration() > 100ms) ALOGD("Excessive delay in setPowerMode()");
1118 }
1119
nativeGetProtectedContentSupport(JNIEnv * env,jclass)1120 static jboolean nativeGetProtectedContentSupport(JNIEnv* env, jclass) {
1121 return static_cast<jboolean>(SurfaceComposerClient::getProtectedContentSupport());
1122 }
1123
nativeClearContentFrameStats(JNIEnv * env,jclass clazz,jlong nativeObject)1124 static jboolean nativeClearContentFrameStats(JNIEnv* env, jclass clazz, jlong nativeObject) {
1125 SurfaceControl* const ctrl = reinterpret_cast<SurfaceControl *>(nativeObject);
1126 status_t err = ctrl->clearLayerFrameStats();
1127
1128 if (err < 0 && err != NO_INIT) {
1129 doThrowIAE(env);
1130 }
1131
1132 // The other end is not ready, just report we failed.
1133 if (err == NO_INIT) {
1134 return JNI_FALSE;
1135 }
1136
1137 return JNI_TRUE;
1138 }
1139
nativeGetContentFrameStats(JNIEnv * env,jclass clazz,jlong nativeObject,jobject outStats)1140 static jboolean nativeGetContentFrameStats(JNIEnv* env, jclass clazz, jlong nativeObject,
1141 jobject outStats) {
1142 FrameStats stats;
1143
1144 SurfaceControl* const ctrl = reinterpret_cast<SurfaceControl *>(nativeObject);
1145 status_t err = ctrl->getLayerFrameStats(&stats);
1146 if (err < 0 && err != NO_INIT) {
1147 doThrowIAE(env);
1148 }
1149
1150 // The other end is not ready, fine just return empty stats.
1151 if (err == NO_INIT) {
1152 return JNI_FALSE;
1153 }
1154
1155 jlong refreshPeriodNano = static_cast<jlong>(stats.refreshPeriodNano);
1156 size_t frameCount = stats.desiredPresentTimesNano.size();
1157
1158 jlongArray postedTimesNanoDst = env->NewLongArray(frameCount);
1159 if (postedTimesNanoDst == NULL) {
1160 return JNI_FALSE;
1161 }
1162
1163 jlongArray presentedTimesNanoDst = env->NewLongArray(frameCount);
1164 if (presentedTimesNanoDst == NULL) {
1165 return JNI_FALSE;
1166 }
1167
1168 jlongArray readyTimesNanoDst = env->NewLongArray(frameCount);
1169 if (readyTimesNanoDst == NULL) {
1170 return JNI_FALSE;
1171 }
1172
1173 nsecs_t postedTimesNanoSrc[frameCount];
1174 nsecs_t presentedTimesNanoSrc[frameCount];
1175 nsecs_t readyTimesNanoSrc[frameCount];
1176
1177 for (size_t i = 0; i < frameCount; i++) {
1178 nsecs_t postedTimeNano = stats.desiredPresentTimesNano[i];
1179 if (postedTimeNano == INT64_MAX) {
1180 postedTimeNano = gWindowContentFrameStatsClassInfo.UNDEFINED_TIME_NANO;
1181 }
1182 postedTimesNanoSrc[i] = postedTimeNano;
1183
1184 nsecs_t presentedTimeNano = stats.actualPresentTimesNano[i];
1185 if (presentedTimeNano == INT64_MAX) {
1186 presentedTimeNano = gWindowContentFrameStatsClassInfo.UNDEFINED_TIME_NANO;
1187 }
1188 presentedTimesNanoSrc[i] = presentedTimeNano;
1189
1190 nsecs_t readyTimeNano = stats.frameReadyTimesNano[i];
1191 if (readyTimeNano == INT64_MAX) {
1192 readyTimeNano = gWindowContentFrameStatsClassInfo.UNDEFINED_TIME_NANO;
1193 }
1194 readyTimesNanoSrc[i] = readyTimeNano;
1195 }
1196
1197 env->SetLongArrayRegion(postedTimesNanoDst, 0, frameCount, postedTimesNanoSrc);
1198 env->SetLongArrayRegion(presentedTimesNanoDst, 0, frameCount, presentedTimesNanoSrc);
1199 env->SetLongArrayRegion(readyTimesNanoDst, 0, frameCount, readyTimesNanoSrc);
1200
1201 env->CallVoidMethod(outStats, gWindowContentFrameStatsClassInfo.init, refreshPeriodNano,
1202 postedTimesNanoDst, presentedTimesNanoDst, readyTimesNanoDst);
1203
1204 if (env->ExceptionCheck()) {
1205 return JNI_FALSE;
1206 }
1207
1208 return JNI_TRUE;
1209 }
1210
nativeClearAnimationFrameStats(JNIEnv * env,jclass clazz)1211 static jboolean nativeClearAnimationFrameStats(JNIEnv* env, jclass clazz) {
1212 status_t err = SurfaceComposerClient::clearAnimationFrameStats();
1213
1214 if (err < 0 && err != NO_INIT) {
1215 doThrowIAE(env);
1216 }
1217
1218 // The other end is not ready, just report we failed.
1219 if (err == NO_INIT) {
1220 return JNI_FALSE;
1221 }
1222
1223 return JNI_TRUE;
1224 }
1225
nativeGetAnimationFrameStats(JNIEnv * env,jclass clazz,jobject outStats)1226 static jboolean nativeGetAnimationFrameStats(JNIEnv* env, jclass clazz, jobject outStats) {
1227 FrameStats stats;
1228
1229 status_t err = SurfaceComposerClient::getAnimationFrameStats(&stats);
1230 if (err < 0 && err != NO_INIT) {
1231 doThrowIAE(env);
1232 }
1233
1234 // The other end is not ready, fine just return empty stats.
1235 if (err == NO_INIT) {
1236 return JNI_FALSE;
1237 }
1238
1239 jlong refreshPeriodNano = static_cast<jlong>(stats.refreshPeriodNano);
1240 size_t frameCount = stats.desiredPresentTimesNano.size();
1241
1242 jlongArray presentedTimesNanoDst = env->NewLongArray(frameCount);
1243 if (presentedTimesNanoDst == NULL) {
1244 return JNI_FALSE;
1245 }
1246
1247 nsecs_t presentedTimesNanoSrc[frameCount];
1248
1249 for (size_t i = 0; i < frameCount; i++) {
1250 nsecs_t presentedTimeNano = stats.actualPresentTimesNano[i];
1251 if (presentedTimeNano == INT64_MAX) {
1252 presentedTimeNano = gWindowContentFrameStatsClassInfo.UNDEFINED_TIME_NANO;
1253 }
1254 presentedTimesNanoSrc[i] = presentedTimeNano;
1255 }
1256
1257 env->SetLongArrayRegion(presentedTimesNanoDst, 0, frameCount, presentedTimesNanoSrc);
1258
1259 env->CallVoidMethod(outStats, gWindowAnimationFrameStatsClassInfo.init, refreshPeriodNano,
1260 presentedTimesNanoDst);
1261
1262 if (env->ExceptionCheck()) {
1263 return JNI_FALSE;
1264 }
1265
1266 return JNI_TRUE;
1267 }
1268
nativeDeferTransactionUntil(JNIEnv * env,jclass clazz,jlong transactionObj,jlong nativeObject,jlong barrierObject,jlong frameNumber)1269 static void nativeDeferTransactionUntil(JNIEnv* env, jclass clazz, jlong transactionObj,
1270 jlong nativeObject, jlong barrierObject, jlong frameNumber) {
1271 auto ctrl = reinterpret_cast<SurfaceControl *>(nativeObject);
1272 auto barrier = reinterpret_cast<SurfaceControl *>(barrierObject);
1273 auto transaction = reinterpret_cast<SurfaceComposerClient::Transaction*>(transactionObj);
1274 transaction->deferTransactionUntil_legacy(ctrl, barrier->getHandle(), frameNumber);
1275 }
1276
nativeDeferTransactionUntilSurface(JNIEnv * env,jclass clazz,jlong transactionObj,jlong nativeObject,jlong surfaceObject,jlong frameNumber)1277 static void nativeDeferTransactionUntilSurface(JNIEnv* env, jclass clazz, jlong transactionObj,
1278 jlong nativeObject,
1279 jlong surfaceObject, jlong frameNumber) {
1280 auto transaction = reinterpret_cast<SurfaceComposerClient::Transaction*>(transactionObj);
1281
1282 auto ctrl = reinterpret_cast<SurfaceControl *>(nativeObject);
1283 sp<Surface> barrier = reinterpret_cast<Surface *>(surfaceObject);
1284
1285 transaction->deferTransactionUntil_legacy(ctrl, barrier, frameNumber);
1286 }
1287
nativeReparentChildren(JNIEnv * env,jclass clazz,jlong transactionObj,jlong nativeObject,jlong newParentObject)1288 static void nativeReparentChildren(JNIEnv* env, jclass clazz, jlong transactionObj,
1289 jlong nativeObject,
1290 jlong newParentObject) {
1291
1292 auto ctrl = reinterpret_cast<SurfaceControl *>(nativeObject);
1293 auto newParent = reinterpret_cast<SurfaceControl *>(newParentObject);
1294 auto transaction = reinterpret_cast<SurfaceComposerClient::Transaction*>(transactionObj);
1295 transaction->reparentChildren(ctrl, newParent->getHandle());
1296 }
1297
nativeReparent(JNIEnv * env,jclass clazz,jlong transactionObj,jlong nativeObject,jlong newParentObject)1298 static void nativeReparent(JNIEnv* env, jclass clazz, jlong transactionObj,
1299 jlong nativeObject,
1300 jlong newParentObject) {
1301 auto ctrl = reinterpret_cast<SurfaceControl *>(nativeObject);
1302 auto newParent = reinterpret_cast<SurfaceControl *>(newParentObject);
1303 auto transaction = reinterpret_cast<SurfaceComposerClient::Transaction*>(transactionObj);
1304 transaction->reparent(ctrl, newParent != NULL ? newParent->getHandle() : NULL);
1305 }
1306
nativeSeverChildren(JNIEnv * env,jclass clazz,jlong transactionObj,jlong nativeObject)1307 static void nativeSeverChildren(JNIEnv* env, jclass clazz, jlong transactionObj,
1308 jlong nativeObject) {
1309 auto transaction = reinterpret_cast<SurfaceComposerClient::Transaction*>(transactionObj);
1310
1311 auto ctrl = reinterpret_cast<SurfaceControl *>(nativeObject);
1312 transaction->detachChildren(ctrl);
1313 }
1314
nativeSetOverrideScalingMode(JNIEnv * env,jclass clazz,jlong transactionObj,jlong nativeObject,jint scalingMode)1315 static void nativeSetOverrideScalingMode(JNIEnv* env, jclass clazz, jlong transactionObj,
1316 jlong nativeObject,
1317 jint scalingMode) {
1318 auto transaction = reinterpret_cast<SurfaceComposerClient::Transaction*>(transactionObj);
1319
1320 auto ctrl = reinterpret_cast<SurfaceControl *>(nativeObject);
1321 transaction->setOverrideScalingMode(ctrl, scalingMode);
1322 }
1323
nativeGetHdrCapabilities(JNIEnv * env,jclass clazz,jobject tokenObject)1324 static jobject nativeGetHdrCapabilities(JNIEnv* env, jclass clazz, jobject tokenObject) {
1325 sp<IBinder> token(ibinderForJavaObject(env, tokenObject));
1326 if (token == NULL) return NULL;
1327
1328 HdrCapabilities capabilities;
1329 SurfaceComposerClient::getHdrCapabilities(token, &capabilities);
1330
1331 const auto& types = capabilities.getSupportedHdrTypes();
1332 std::vector<int32_t> intTypes;
1333 for (auto type : types) {
1334 intTypes.push_back(static_cast<int32_t>(type));
1335 }
1336 auto typesArray = env->NewIntArray(types.size());
1337 env->SetIntArrayRegion(typesArray, 0, intTypes.size(), intTypes.data());
1338
1339 return env->NewObject(gHdrCapabilitiesClassInfo.clazz, gHdrCapabilitiesClassInfo.ctor,
1340 typesArray, capabilities.getDesiredMaxLuminance(),
1341 capabilities.getDesiredMaxAverageLuminance(), capabilities.getDesiredMinLuminance());
1342 }
1343
nativeGetAutoLowLatencyModeSupport(JNIEnv * env,jclass clazz,jobject tokenObject)1344 static jboolean nativeGetAutoLowLatencyModeSupport(JNIEnv* env, jclass clazz, jobject tokenObject) {
1345 sp<IBinder> token(ibinderForJavaObject(env, tokenObject));
1346 if (token == NULL) return NULL;
1347
1348 return SurfaceComposerClient::getAutoLowLatencyModeSupport(token);
1349 }
1350
nativeGetGameContentTypeSupport(JNIEnv * env,jclass clazz,jobject tokenObject)1351 static jboolean nativeGetGameContentTypeSupport(JNIEnv* env, jclass clazz, jobject tokenObject) {
1352 sp<IBinder> token(ibinderForJavaObject(env, tokenObject));
1353 if (token == NULL) return NULL;
1354
1355 return SurfaceComposerClient::getGameContentTypeSupport(token);
1356 }
1357
nativeSetAutoLowLatencyMode(JNIEnv * env,jclass clazz,jobject tokenObject,jboolean on)1358 static void nativeSetAutoLowLatencyMode(JNIEnv* env, jclass clazz, jobject tokenObject, jboolean on) {
1359 sp<IBinder> token(ibinderForJavaObject(env, tokenObject));
1360 if (token == NULL) return;
1361
1362 SurfaceComposerClient::setAutoLowLatencyMode(token, on);
1363 }
1364
nativeSetGameContentType(JNIEnv * env,jclass clazz,jobject tokenObject,jboolean on)1365 static void nativeSetGameContentType(JNIEnv* env, jclass clazz, jobject tokenObject, jboolean on) {
1366 sp<IBinder> token(ibinderForJavaObject(env, tokenObject));
1367 if (token == NULL) return;
1368
1369 SurfaceComposerClient::setGameContentType(token, on);
1370 }
1371
nativeReadFromParcel(JNIEnv * env,jclass clazz,jobject parcelObj)1372 static jlong nativeReadFromParcel(JNIEnv* env, jclass clazz, jobject parcelObj) {
1373 Parcel* parcel = parcelForJavaObject(env, parcelObj);
1374 if (parcel == NULL) {
1375 doThrowNPE(env);
1376 return 0;
1377 }
1378 sp<SurfaceControl> surface = SurfaceControl::readFromParcel(parcel);
1379 if (surface == nullptr) {
1380 return 0;
1381 }
1382 surface->incStrong((void *)nativeCreate);
1383 return reinterpret_cast<jlong>(surface.get());
1384 }
1385
nativeCopyFromSurfaceControl(JNIEnv * env,jclass clazz,jlong surfaceControlNativeObj)1386 static jlong nativeCopyFromSurfaceControl(JNIEnv* env, jclass clazz, jlong surfaceControlNativeObj) {
1387 sp<SurfaceControl> surface(reinterpret_cast<SurfaceControl *>(surfaceControlNativeObj));
1388 if (surface == nullptr) {
1389 return 0;
1390 }
1391
1392 sp<SurfaceControl> newSurface = new SurfaceControl(surface);
1393 newSurface->incStrong((void *)nativeCreate);
1394 return reinterpret_cast<jlong>(newSurface.get());
1395 }
1396
nativeWriteToParcel(JNIEnv * env,jclass clazz,jlong nativeObject,jobject parcelObj)1397 static void nativeWriteToParcel(JNIEnv* env, jclass clazz,
1398 jlong nativeObject, jobject parcelObj) {
1399 Parcel* parcel = parcelForJavaObject(env, parcelObj);
1400 if (parcel == NULL) {
1401 doThrowNPE(env);
1402 return;
1403 }
1404 SurfaceControl* const self = reinterpret_cast<SurfaceControl *>(nativeObject);
1405 if (self != nullptr) {
1406 self->writeToParcel(parcel);
1407 }
1408 }
1409
nativeGetDisplayBrightnessSupport(JNIEnv * env,jclass clazz,jobject displayTokenObject)1410 static jboolean nativeGetDisplayBrightnessSupport(JNIEnv* env, jclass clazz,
1411 jobject displayTokenObject) {
1412 sp<IBinder> displayToken(ibinderForJavaObject(env, displayTokenObject));
1413 if (displayToken == nullptr) {
1414 return JNI_FALSE;
1415 }
1416 return static_cast<jboolean>(SurfaceComposerClient::getDisplayBrightnessSupport(displayToken));
1417 }
1418
nativeSetDisplayBrightness(JNIEnv * env,jclass clazz,jobject displayTokenObject,jfloat brightness)1419 static jboolean nativeSetDisplayBrightness(JNIEnv* env, jclass clazz, jobject displayTokenObject,
1420 jfloat brightness) {
1421 sp<IBinder> displayToken(ibinderForJavaObject(env, displayTokenObject));
1422 if (displayToken == nullptr) {
1423 return JNI_FALSE;
1424 }
1425 status_t error = SurfaceComposerClient::setDisplayBrightness(displayToken, brightness);
1426 return error == OK ? JNI_TRUE : JNI_FALSE;
1427 }
1428
nativeWriteTransactionToParcel(JNIEnv * env,jclass clazz,jlong nativeObject,jobject parcelObj)1429 static void nativeWriteTransactionToParcel(JNIEnv* env, jclass clazz, jlong nativeObject,
1430 jobject parcelObj) {
1431 Parcel* parcel = parcelForJavaObject(env, parcelObj);
1432 if (parcel == NULL) {
1433 doThrowNPE(env);
1434 return;
1435 }
1436 SurfaceComposerClient::Transaction* const self =
1437 reinterpret_cast<SurfaceComposerClient::Transaction *>(nativeObject);
1438 if (self != nullptr) {
1439 self->writeToParcel(parcel);
1440 self->clear();
1441 }
1442 }
1443
nativeReadTransactionFromParcel(JNIEnv * env,jclass clazz,jobject parcelObj)1444 static jlong nativeReadTransactionFromParcel(JNIEnv* env, jclass clazz, jobject parcelObj) {
1445 Parcel* parcel = parcelForJavaObject(env, parcelObj);
1446 if (parcel == NULL) {
1447 doThrowNPE(env);
1448 return 0;
1449 }
1450 std::unique_ptr<SurfaceComposerClient::Transaction> transaction =
1451 SurfaceComposerClient::Transaction::createFromParcel(parcel);
1452
1453 return reinterpret_cast<jlong>(transaction.release());
1454 }
1455
nativeMirrorSurface(JNIEnv * env,jclass clazz,jlong mirrorOfObj)1456 static jlong nativeMirrorSurface(JNIEnv* env, jclass clazz, jlong mirrorOfObj) {
1457 sp<SurfaceComposerClient> client = SurfaceComposerClient::getDefault();
1458 SurfaceControl *mirrorOf = reinterpret_cast<SurfaceControl*>(mirrorOfObj);
1459 sp<SurfaceControl> surface = client->mirrorSurface(mirrorOf);
1460
1461 surface->incStrong((void *)nativeCreate);
1462 return reinterpret_cast<jlong>(surface.get());
1463 }
1464
nativeSetGlobalShadowSettings(JNIEnv * env,jclass clazz,jfloatArray jAmbientColor,jfloatArray jSpotColor,jfloat lightPosY,jfloat lightPosZ,jfloat lightRadius)1465 static void nativeSetGlobalShadowSettings(JNIEnv* env, jclass clazz, jfloatArray jAmbientColor,
1466 jfloatArray jSpotColor, jfloat lightPosY, jfloat lightPosZ, jfloat lightRadius) {
1467 sp<SurfaceComposerClient> client = SurfaceComposerClient::getDefault();
1468
1469 float* floatAmbientColor = env->GetFloatArrayElements(jAmbientColor, 0);
1470 half4 ambientColor = half4(floatAmbientColor[0], floatAmbientColor[1], floatAmbientColor[2],
1471 floatAmbientColor[3]);
1472 env->ReleaseFloatArrayElements(jAmbientColor, floatAmbientColor, 0);
1473
1474 float* floatSpotColor = env->GetFloatArrayElements(jSpotColor, 0);
1475 half4 spotColor = half4(floatSpotColor[0], floatSpotColor[1], floatSpotColor[2],
1476 floatSpotColor[3]);
1477 env->ReleaseFloatArrayElements(jSpotColor, floatSpotColor, 0);
1478
1479 client->setGlobalShadowSettings(ambientColor, spotColor, lightPosY, lightPosZ, lightRadius);
1480 }
1481
nativeGetHandle(JNIEnv * env,jclass clazz,jlong nativeObject)1482 static jlong nativeGetHandle(JNIEnv* env, jclass clazz, jlong nativeObject) {
1483 SurfaceControl *surfaceControl = reinterpret_cast<SurfaceControl*>(nativeObject);
1484 return reinterpret_cast<jlong>(surfaceControl->getHandle().get());
1485 }
1486
1487 // ----------------------------------------------------------------------------
1488
1489 static const JNINativeMethod sSurfaceControlMethods[] = {
1490 {"nativeCreate", "(Landroid/view/SurfaceSession;Ljava/lang/String;IIIIJLandroid/os/Parcel;)J",
1491 (void*)nativeCreate },
1492 {"nativeReadFromParcel", "(Landroid/os/Parcel;)J",
1493 (void*)nativeReadFromParcel },
1494 {"nativeCopyFromSurfaceControl", "(J)J" ,
1495 (void*)nativeCopyFromSurfaceControl },
1496 {"nativeWriteToParcel", "(JLandroid/os/Parcel;)V",
1497 (void*)nativeWriteToParcel },
1498 {"nativeRelease", "(J)V",
1499 (void*)nativeRelease },
1500 {"nativeDisconnect", "(J)V",
1501 (void*)nativeDisconnect },
1502 {"nativeCreateTransaction", "()J",
1503 (void*)nativeCreateTransaction },
1504 {"nativeApplyTransaction", "(JZ)V",
1505 (void*)nativeApplyTransaction },
1506 {"nativeGetNativeTransactionFinalizer", "()J",
1507 (void*)nativeGetNativeTransactionFinalizer },
1508 {"nativeMergeTransaction", "(JJ)V",
1509 (void*)nativeMergeTransaction },
1510 {"nativeSetAnimationTransaction", "(J)V",
1511 (void*)nativeSetAnimationTransaction },
1512 {"nativeSetEarlyWakeup", "(J)V",
1513 (void*)nativeSetEarlyWakeup },
1514 {"nativeSetEarlyWakeupStart", "(J)V",
1515 (void*)nativeSetEarlyWakeupStart },
1516 {"nativeSetEarlyWakeupEnd", "(J)V",
1517 (void*)nativeSetEarlyWakeupEnd },
1518 {"nativeSetLayer", "(JJI)V",
1519 (void*)nativeSetLayer },
1520 {"nativeSetRelativeLayer", "(JJJI)V",
1521 (void*)nativeSetRelativeLayer },
1522 {"nativeSetPosition", "(JJFF)V",
1523 (void*)nativeSetPosition },
1524 {"nativeSetSize", "(JJII)V",
1525 (void*)nativeSetSize },
1526 {"nativeSetTransparentRegionHint", "(JJLandroid/graphics/Region;)V",
1527 (void*)nativeSetTransparentRegionHint },
1528 {"nativeSetAlpha", "(JJF)V",
1529 (void*)nativeSetAlpha },
1530 {"nativeSetColor", "(JJ[F)V",
1531 (void*)nativeSetColor },
1532 {"nativeSetMatrix", "(JJFFFF)V",
1533 (void*)nativeSetMatrix },
1534 {"nativeSetColorTransform", "(JJ[F[F)V",
1535 (void*)nativeSetColorTransform },
1536 {"nativeSetColorSpaceAgnostic", "(JJZ)V",
1537 (void*)nativeSetColorSpaceAgnostic },
1538 {"nativeSetFlags", "(JJII)V",
1539 (void*)nativeSetFlags },
1540 {"nativeSetFrameRateSelectionPriority", "(JJI)V",
1541 (void*)nativeSetFrameRateSelectionPriority },
1542 {"nativeSetWindowCrop", "(JJIIII)V",
1543 (void*)nativeSetWindowCrop },
1544 {"nativeSetCornerRadius", "(JJF)V",
1545 (void*)nativeSetCornerRadius },
1546 {"nativeSetBackgroundBlurRadius", "(JJI)V",
1547 (void*)nativeSetBackgroundBlurRadius },
1548 {"nativeSetLayerStack", "(JJI)V",
1549 (void*)nativeSetLayerStack },
1550 {"nativeSetShadowRadius", "(JJF)V",
1551 (void*)nativeSetShadowRadius },
1552 {"nativeSetFrameRate", "(JJFI)V",
1553 (void*)nativeSetFrameRate },
1554 {"nativeAcquireFrameRateFlexibilityToken", "()J",
1555 (void*)nativeAcquireFrameRateFlexibilityToken },
1556 {"nativeReleaseFrameRateFlexibilityToken", "(J)V",
1557 (void*)nativeReleaseFrameRateFlexibilityToken },
1558 {"nativeGetPhysicalDisplayIds", "()[J",
1559 (void*)nativeGetPhysicalDisplayIds },
1560 {"nativeGetPhysicalDisplayToken", "(J)Landroid/os/IBinder;",
1561 (void*)nativeGetPhysicalDisplayToken },
1562 {"nativeCreateDisplay", "(Ljava/lang/String;Z)Landroid/os/IBinder;",
1563 (void*)nativeCreateDisplay },
1564 {"nativeDestroyDisplay", "(Landroid/os/IBinder;)V",
1565 (void*)nativeDestroyDisplay },
1566 {"nativeSetDisplaySurface", "(JLandroid/os/IBinder;J)V",
1567 (void*)nativeSetDisplaySurface },
1568 {"nativeSetDisplayLayerStack", "(JLandroid/os/IBinder;I)V",
1569 (void*)nativeSetDisplayLayerStack },
1570 {"nativeSetDisplayProjection", "(JLandroid/os/IBinder;IIIIIIIII)V",
1571 (void*)nativeSetDisplayProjection },
1572 {"nativeSetDisplaySize", "(JLandroid/os/IBinder;II)V",
1573 (void*)nativeSetDisplaySize },
1574 {"nativeGetDisplayInfo", "(Landroid/os/IBinder;)Landroid/view/SurfaceControl$DisplayInfo;",
1575 (void*)nativeGetDisplayInfo },
1576 {"nativeGetDisplayConfigs", "(Landroid/os/IBinder;)[Landroid/view/SurfaceControl$DisplayConfig;",
1577 (void*)nativeGetDisplayConfigs },
1578 {"nativeGetActiveConfig", "(Landroid/os/IBinder;)I",
1579 (void*)nativeGetActiveConfig },
1580 {"nativeSetDesiredDisplayConfigSpecs",
1581 "(Landroid/os/IBinder;Landroid/view/SurfaceControl$DesiredDisplayConfigSpecs;)Z",
1582 (void*)nativeSetDesiredDisplayConfigSpecs },
1583 {"nativeGetDesiredDisplayConfigSpecs",
1584 "(Landroid/os/IBinder;)Landroid/view/SurfaceControl$DesiredDisplayConfigSpecs;",
1585 (void*)nativeGetDesiredDisplayConfigSpecs },
1586 {"nativeGetDisplayColorModes", "(Landroid/os/IBinder;)[I",
1587 (void*)nativeGetDisplayColorModes},
1588 {"nativeGetDisplayNativePrimaries", "(Landroid/os/IBinder;)Landroid/view/SurfaceControl$DisplayPrimaries;",
1589 (void*)nativeGetDisplayNativePrimaries },
1590 {"nativeGetActiveColorMode", "(Landroid/os/IBinder;)I",
1591 (void*)nativeGetActiveColorMode},
1592 {"nativeSetActiveColorMode", "(Landroid/os/IBinder;I)Z",
1593 (void*)nativeSetActiveColorMode},
1594 {"nativeGetAutoLowLatencyModeSupport", "(Landroid/os/IBinder;)Z",
1595 (void*)nativeGetAutoLowLatencyModeSupport },
1596 {"nativeSetAutoLowLatencyMode", "(Landroid/os/IBinder;Z)V",
1597 (void*)nativeSetAutoLowLatencyMode },
1598 {"nativeGetGameContentTypeSupport", "(Landroid/os/IBinder;)Z",
1599 (void*)nativeGetGameContentTypeSupport },
1600 {"nativeSetGameContentType", "(Landroid/os/IBinder;Z)V",
1601 (void*)nativeSetGameContentType },
1602 {"nativeGetCompositionDataspaces", "()[I",
1603 (void*)nativeGetCompositionDataspaces},
1604 {"nativeGetHdrCapabilities", "(Landroid/os/IBinder;)Landroid/view/Display$HdrCapabilities;",
1605 (void*)nativeGetHdrCapabilities },
1606 {"nativeClearContentFrameStats", "(J)Z",
1607 (void*)nativeClearContentFrameStats },
1608 {"nativeGetContentFrameStats", "(JLandroid/view/WindowContentFrameStats;)Z",
1609 (void*)nativeGetContentFrameStats },
1610 {"nativeClearAnimationFrameStats", "()Z",
1611 (void*)nativeClearAnimationFrameStats },
1612 {"nativeGetAnimationFrameStats", "(Landroid/view/WindowAnimationFrameStats;)Z",
1613 (void*)nativeGetAnimationFrameStats },
1614 {"nativeSetDisplayPowerMode", "(Landroid/os/IBinder;I)V",
1615 (void*)nativeSetDisplayPowerMode },
1616 {"nativeGetProtectedContentSupport", "()Z",
1617 (void*)nativeGetProtectedContentSupport },
1618 {"nativeDeferTransactionUntil", "(JJJJ)V",
1619 (void*)nativeDeferTransactionUntil },
1620 {"nativeDeferTransactionUntilSurface", "(JJJJ)V",
1621 (void*)nativeDeferTransactionUntilSurface },
1622 {"nativeReparentChildren", "(JJJ)V",
1623 (void*)nativeReparentChildren } ,
1624 {"nativeReparent", "(JJJ)V",
1625 (void*)nativeReparent },
1626 {"nativeSeverChildren", "(JJ)V",
1627 (void*)nativeSeverChildren } ,
1628 {"nativeSetOverrideScalingMode", "(JJI)V",
1629 (void*)nativeSetOverrideScalingMode },
1630 {"nativeScreenshot",
1631 "(Landroid/os/IBinder;Landroid/graphics/Rect;IIZIZ)"
1632 "Landroid/view/SurfaceControl$ScreenshotGraphicBuffer;",
1633 (void*)nativeScreenshot },
1634 {"nativeCaptureLayers",
1635 "(Landroid/os/IBinder;JLandroid/graphics/Rect;"
1636 "F[JI)"
1637 "Landroid/view/SurfaceControl$ScreenshotGraphicBuffer;",
1638 (void*)nativeCaptureLayers },
1639 {"nativeSetInputWindowInfo", "(JJLandroid/view/InputWindowHandle;)V",
1640 (void*)nativeSetInputWindowInfo },
1641 {"nativeSetMetadata", "(JJILandroid/os/Parcel;)V",
1642 (void*)nativeSetMetadata },
1643 {"nativeGetDisplayedContentSamplingAttributes",
1644 "(Landroid/os/IBinder;)Landroid/hardware/display/DisplayedContentSamplingAttributes;",
1645 (void*)nativeGetDisplayedContentSamplingAttributes },
1646 {"nativeSetDisplayedContentSamplingEnabled", "(Landroid/os/IBinder;ZII)Z",
1647 (void*)nativeSetDisplayedContentSamplingEnabled },
1648 {"nativeGetDisplayedContentSample",
1649 "(Landroid/os/IBinder;JJ)Landroid/hardware/display/DisplayedContentSample;",
1650 (void*)nativeGetDisplayedContentSample },
1651 {"nativeSetGeometry", "(JJLandroid/graphics/Rect;Landroid/graphics/Rect;J)V",
1652 (void*)nativeSetGeometry },
1653 {"nativeSyncInputWindows", "(J)V",
1654 (void*)nativeSyncInputWindows },
1655 {"nativeGetDisplayBrightnessSupport", "(Landroid/os/IBinder;)Z",
1656 (void*)nativeGetDisplayBrightnessSupport },
1657 {"nativeSetDisplayBrightness", "(Landroid/os/IBinder;F)Z",
1658 (void*)nativeSetDisplayBrightness },
1659 {"nativeReadTransactionFromParcel", "(Landroid/os/Parcel;)J",
1660 (void*)nativeReadTransactionFromParcel },
1661 {"nativeWriteTransactionToParcel", "(JLandroid/os/Parcel;)V",
1662 (void*)nativeWriteTransactionToParcel },
1663 {"nativeMirrorSurface", "(J)J",
1664 (void*)nativeMirrorSurface },
1665 {"nativeSetGlobalShadowSettings", "([F[FFFF)V",
1666 (void*)nativeSetGlobalShadowSettings },
1667 {"nativeGetHandle", "(J)J",
1668 (void*)nativeGetHandle },
1669 {"nativeSetFixedTransformHint", "(JJI)V", (void*)nativeSetFixedTransformHint},
1670 };
1671
register_android_view_SurfaceControl(JNIEnv * env)1672 int register_android_view_SurfaceControl(JNIEnv* env)
1673 {
1674 int err = RegisterMethodsOrDie(env, "android/view/SurfaceControl",
1675 sSurfaceControlMethods, NELEM(sSurfaceControlMethods));
1676
1677 jclass integerClass = FindClassOrDie(env, "java/lang/Integer");
1678 gIntegerClassInfo.clazz = MakeGlobalRefOrDie(env, integerClass);
1679 gIntegerClassInfo.ctor = GetMethodIDOrDie(env, gIntegerClassInfo.clazz, "<init>", "(I)V");
1680
1681 jclass infoClazz = FindClassOrDie(env, "android/view/SurfaceControl$DisplayInfo");
1682 gDisplayInfoClassInfo.clazz = MakeGlobalRefOrDie(env, infoClazz);
1683 gDisplayInfoClassInfo.ctor = GetMethodIDOrDie(env, infoClazz, "<init>", "()V");
1684 gDisplayInfoClassInfo.isInternal = GetFieldIDOrDie(env, infoClazz, "isInternal", "Z");
1685 gDisplayInfoClassInfo.density = GetFieldIDOrDie(env, infoClazz, "density", "F");
1686 gDisplayInfoClassInfo.secure = GetFieldIDOrDie(env, infoClazz, "secure", "Z");
1687 gDisplayInfoClassInfo.deviceProductInfo =
1688 GetFieldIDOrDie(env, infoClazz, "deviceProductInfo",
1689 "Landroid/hardware/display/DeviceProductInfo;");
1690
1691 jclass configClazz = FindClassOrDie(env, "android/view/SurfaceControl$DisplayConfig");
1692 gDisplayConfigClassInfo.clazz = MakeGlobalRefOrDie(env, configClazz);
1693 gDisplayConfigClassInfo.ctor = GetMethodIDOrDie(env, configClazz, "<init>", "()V");
1694 gDisplayConfigClassInfo.width = GetFieldIDOrDie(env, configClazz, "width", "I");
1695 gDisplayConfigClassInfo.height = GetFieldIDOrDie(env, configClazz, "height", "I");
1696 gDisplayConfigClassInfo.xDpi = GetFieldIDOrDie(env, configClazz, "xDpi", "F");
1697 gDisplayConfigClassInfo.yDpi = GetFieldIDOrDie(env, configClazz, "yDpi", "F");
1698 gDisplayConfigClassInfo.refreshRate = GetFieldIDOrDie(env, configClazz, "refreshRate", "F");
1699 gDisplayConfigClassInfo.appVsyncOffsetNanos =
1700 GetFieldIDOrDie(env, configClazz, "appVsyncOffsetNanos", "J");
1701 gDisplayConfigClassInfo.presentationDeadlineNanos =
1702 GetFieldIDOrDie(env, configClazz, "presentationDeadlineNanos", "J");
1703 gDisplayConfigClassInfo.configGroup = GetFieldIDOrDie(env, configClazz, "configGroup", "I");
1704
1705 jclass rectClazz = FindClassOrDie(env, "android/graphics/Rect");
1706 gRectClassInfo.bottom = GetFieldIDOrDie(env, rectClazz, "bottom", "I");
1707 gRectClassInfo.left = GetFieldIDOrDie(env, rectClazz, "left", "I");
1708 gRectClassInfo.right = GetFieldIDOrDie(env, rectClazz, "right", "I");
1709 gRectClassInfo.top = GetFieldIDOrDie(env, rectClazz, "top", "I");
1710
1711 jclass frameStatsClazz = FindClassOrDie(env, "android/view/FrameStats");
1712 jfieldID undefined_time_nano_field = GetStaticFieldIDOrDie(env,
1713 frameStatsClazz, "UNDEFINED_TIME_NANO", "J");
1714 nsecs_t undefined_time_nano = env->GetStaticLongField(frameStatsClazz, undefined_time_nano_field);
1715
1716 jclass contFrameStatsClazz = FindClassOrDie(env, "android/view/WindowContentFrameStats");
1717 gWindowContentFrameStatsClassInfo.init = GetMethodIDOrDie(env,
1718 contFrameStatsClazz, "init", "(J[J[J[J)V");
1719 gWindowContentFrameStatsClassInfo.UNDEFINED_TIME_NANO = undefined_time_nano;
1720
1721 jclass animFrameStatsClazz = FindClassOrDie(env, "android/view/WindowAnimationFrameStats");
1722 gWindowAnimationFrameStatsClassInfo.init = GetMethodIDOrDie(env,
1723 animFrameStatsClazz, "init", "(J[J)V");
1724 gWindowAnimationFrameStatsClassInfo.UNDEFINED_TIME_NANO = undefined_time_nano;
1725
1726 jclass hdrCapabilitiesClazz = FindClassOrDie(env, "android/view/Display$HdrCapabilities");
1727 gHdrCapabilitiesClassInfo.clazz = MakeGlobalRefOrDie(env, hdrCapabilitiesClazz);
1728 gHdrCapabilitiesClassInfo.ctor = GetMethodIDOrDie(env, hdrCapabilitiesClazz, "<init>",
1729 "([IFFF)V");
1730
1731 jclass deviceProductInfoClazz =
1732 FindClassOrDie(env, "android/hardware/display/DeviceProductInfo");
1733 gDeviceProductInfoClassInfo.clazz = MakeGlobalRefOrDie(env, deviceProductInfoClazz);
1734 gDeviceProductInfoClassInfo.ctor =
1735 GetMethodIDOrDie(env, deviceProductInfoClazz, "<init>",
1736 "(Ljava/lang/String;"
1737 "Ljava/lang/String;"
1738 "Ljava/lang/String;"
1739 "Ljava/lang/Integer;"
1740 "Landroid/hardware/display/DeviceProductInfo$ManufactureDate;"
1741 "[I)V");
1742
1743 jclass deviceProductInfoManufactureDateClazz =
1744 FindClassOrDie(env, "android/hardware/display/DeviceProductInfo$ManufactureDate");
1745 gDeviceProductInfoManufactureDateClassInfo.clazz =
1746 MakeGlobalRefOrDie(env, deviceProductInfoManufactureDateClazz);
1747 gDeviceProductInfoManufactureDateClassInfo.ctor =
1748 GetMethodIDOrDie(env, deviceProductInfoManufactureDateClazz, "<init>",
1749 "(Ljava/lang/Integer;Ljava/lang/Integer;)V");
1750
1751 jclass graphicsBufferClazz = FindClassOrDie(env, "android/graphics/GraphicBuffer");
1752 gGraphicBufferClassInfo.clazz = MakeGlobalRefOrDie(env, graphicsBufferClazz);
1753 gGraphicBufferClassInfo.builder = GetStaticMethodIDOrDie(env, graphicsBufferClazz,
1754 "createFromExisting", "(IIIIJ)Landroid/graphics/GraphicBuffer;");
1755
1756 jclass screenshotGraphicsBufferClazz = FindClassOrDie(env,
1757 "android/view/SurfaceControl$ScreenshotGraphicBuffer");
1758 gScreenshotGraphicBufferClassInfo.clazz =
1759 MakeGlobalRefOrDie(env, screenshotGraphicsBufferClazz);
1760 gScreenshotGraphicBufferClassInfo.builder = GetStaticMethodIDOrDie(env,
1761 screenshotGraphicsBufferClazz,
1762 "createFromNative", "(IIIIJIZ)Landroid/view/SurfaceControl$ScreenshotGraphicBuffer;");
1763
1764 jclass displayedContentSampleClazz = FindClassOrDie(env,
1765 "android/hardware/display/DisplayedContentSample");
1766 gDisplayedContentSampleClassInfo.clazz = MakeGlobalRefOrDie(env, displayedContentSampleClazz);
1767 gDisplayedContentSampleClassInfo.ctor = GetMethodIDOrDie(env,
1768 displayedContentSampleClazz, "<init>", "(J[J[J[J[J)V");
1769
1770 jclass displayedContentSamplingAttributesClazz = FindClassOrDie(env,
1771 "android/hardware/display/DisplayedContentSamplingAttributes");
1772 gDisplayedContentSamplingAttributesClassInfo.clazz = MakeGlobalRefOrDie(env,
1773 displayedContentSamplingAttributesClazz);
1774 gDisplayedContentSamplingAttributesClassInfo.ctor = GetMethodIDOrDie(env,
1775 displayedContentSamplingAttributesClazz, "<init>", "(III)V");
1776
1777 jclass cieXyzClazz = FindClassOrDie(env, "android/view/SurfaceControl$CieXyz");
1778 gCieXyzClassInfo.clazz = MakeGlobalRefOrDie(env, cieXyzClazz);
1779 gCieXyzClassInfo.ctor = GetMethodIDOrDie(env, gCieXyzClassInfo.clazz, "<init>", "()V");
1780 gCieXyzClassInfo.X = GetFieldIDOrDie(env, cieXyzClazz, "X", "F");
1781 gCieXyzClassInfo.Y = GetFieldIDOrDie(env, cieXyzClazz, "Y", "F");
1782 gCieXyzClassInfo.Z = GetFieldIDOrDie(env, cieXyzClazz, "Z", "F");
1783
1784 jclass displayPrimariesClazz = FindClassOrDie(env,
1785 "android/view/SurfaceControl$DisplayPrimaries");
1786 gDisplayPrimariesClassInfo.clazz = MakeGlobalRefOrDie(env, displayPrimariesClazz);
1787 gDisplayPrimariesClassInfo.ctor = GetMethodIDOrDie(env, gDisplayPrimariesClassInfo.clazz,
1788 "<init>", "()V");
1789 gDisplayPrimariesClassInfo.red = GetFieldIDOrDie(env, displayPrimariesClazz, "red",
1790 "Landroid/view/SurfaceControl$CieXyz;");
1791 gDisplayPrimariesClassInfo.green = GetFieldIDOrDie(env, displayPrimariesClazz, "green",
1792 "Landroid/view/SurfaceControl$CieXyz;");
1793 gDisplayPrimariesClassInfo.blue = GetFieldIDOrDie(env, displayPrimariesClazz, "blue",
1794 "Landroid/view/SurfaceControl$CieXyz;");
1795 gDisplayPrimariesClassInfo.white = GetFieldIDOrDie(env, displayPrimariesClazz, "white",
1796 "Landroid/view/SurfaceControl$CieXyz;");
1797
1798 jclass desiredDisplayConfigSpecsClazz =
1799 FindClassOrDie(env, "android/view/SurfaceControl$DesiredDisplayConfigSpecs");
1800 gDesiredDisplayConfigSpecsClassInfo.clazz =
1801 MakeGlobalRefOrDie(env, desiredDisplayConfigSpecsClazz);
1802 gDesiredDisplayConfigSpecsClassInfo.ctor =
1803 GetMethodIDOrDie(env, gDesiredDisplayConfigSpecsClassInfo.clazz, "<init>", "(IFFFF)V");
1804 gDesiredDisplayConfigSpecsClassInfo.defaultConfig =
1805 GetFieldIDOrDie(env, desiredDisplayConfigSpecsClazz, "defaultConfig", "I");
1806 gDesiredDisplayConfigSpecsClassInfo.primaryRefreshRateMin =
1807 GetFieldIDOrDie(env, desiredDisplayConfigSpecsClazz, "primaryRefreshRateMin", "F");
1808 gDesiredDisplayConfigSpecsClassInfo.primaryRefreshRateMax =
1809 GetFieldIDOrDie(env, desiredDisplayConfigSpecsClazz, "primaryRefreshRateMax", "F");
1810 gDesiredDisplayConfigSpecsClassInfo.appRequestRefreshRateMin =
1811 GetFieldIDOrDie(env, desiredDisplayConfigSpecsClazz, "appRequestRefreshRateMin", "F");
1812 gDesiredDisplayConfigSpecsClassInfo.appRequestRefreshRateMax =
1813 GetFieldIDOrDie(env, desiredDisplayConfigSpecsClazz, "appRequestRefreshRateMax", "F");
1814
1815 return err;
1816 }
1817
1818 } // namespace android
1819