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