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/graphics/Bitmap.h"
23 #include "android/graphics/GraphicsJNI.h"
24 #include "android/graphics/Region.h"
25 #include "core_jni_helpers.h"
26
27 #include <android-base/chrono_utils.h>
28 #include <nativehelper/JNIHelp.h>
29 #include <nativehelper/ScopedUtfChars.h>
30 #include <android_runtime/android_view_Surface.h>
31 #include <android_runtime/android_view_SurfaceSession.h>
32 #include <gui/Surface.h>
33 #include <gui/SurfaceComposerClient.h>
34 #include <jni.h>
35 #include <memory>
36 #include <stdio.h>
37 #include <system/graphics.h>
38 #include <ui/DisplayInfo.h>
39 #include <ui/FrameStats.h>
40 #include <ui/GraphicTypes.h>
41 #include <ui/HdrCapabilities.h>
42 #include <ui/Rect.h>
43 #include <ui/Region.h>
44 #include <utils/Log.h>
45
46 // ----------------------------------------------------------------------------
47
48 namespace android {
49
50 static const char* const OutOfResourcesException =
51 "android/view/Surface$OutOfResourcesException";
52
53 static struct {
54 jclass clazz;
55 jmethodID ctor;
56 jfieldID width;
57 jfieldID height;
58 jfieldID refreshRate;
59 jfieldID density;
60 jfieldID xDpi;
61 jfieldID yDpi;
62 jfieldID secure;
63 jfieldID appVsyncOffsetNanos;
64 jfieldID presentationDeadlineNanos;
65 } gPhysicalDisplayInfoClassInfo;
66
67 static struct {
68 jfieldID bottom;
69 jfieldID left;
70 jfieldID right;
71 jfieldID top;
72 } gRectClassInfo;
73
74 // Implements SkMallocPixelRef::ReleaseProc, to delete the screenshot on unref.
DeleteScreenshot(void * addr,void * context)75 void DeleteScreenshot(void* addr, void* context) {
76 delete ((ScreenshotClient*) context);
77 }
78
79 static struct {
80 nsecs_t UNDEFINED_TIME_NANO;
81 jmethodID init;
82 } gWindowContentFrameStatsClassInfo;
83
84 static struct {
85 nsecs_t UNDEFINED_TIME_NANO;
86 jmethodID init;
87 } gWindowAnimationFrameStatsClassInfo;
88
89 static struct {
90 jclass clazz;
91 jmethodID ctor;
92 } gHdrCapabilitiesClassInfo;
93
94 static struct {
95 jclass clazz;
96 jmethodID builder;
97 } gGraphicBufferClassInfo;
98
99 // ----------------------------------------------------------------------------
100
nativeCreateTransaction(JNIEnv * env,jclass clazz)101 static jlong nativeCreateTransaction(JNIEnv* env, jclass clazz) {
102 return reinterpret_cast<jlong>(new SurfaceComposerClient::Transaction);
103 }
104
releaseTransaction(SurfaceComposerClient::Transaction * t)105 static void releaseTransaction(SurfaceComposerClient::Transaction* t) {
106 delete t;
107 }
108
nativeGetNativeTransactionFinalizer(JNIEnv * env,jclass clazz)109 static jlong nativeGetNativeTransactionFinalizer(JNIEnv* env, jclass clazz) {
110 return static_cast<jlong>(reinterpret_cast<uintptr_t>(&releaseTransaction));
111 }
112
nativeCreate(JNIEnv * env,jclass clazz,jobject sessionObj,jstring nameStr,jint w,jint h,jint format,jint flags,jlong parentObject,jint windowType,jint ownerUid)113 static jlong nativeCreate(JNIEnv* env, jclass clazz, jobject sessionObj,
114 jstring nameStr, jint w, jint h, jint format, jint flags, jlong parentObject,
115 jint windowType, jint ownerUid) {
116 ScopedUtfChars name(env, nameStr);
117 sp<SurfaceComposerClient> client(android_view_SurfaceSession_getClient(env, sessionObj));
118 SurfaceControl *parent = reinterpret_cast<SurfaceControl*>(parentObject);
119 sp<SurfaceControl> surface;
120 status_t err = client->createSurfaceChecked(
121 String8(name.c_str()), w, h, format, &surface, flags, parent, windowType, ownerUid);
122 if (err == NAME_NOT_FOUND) {
123 jniThrowException(env, "java/lang/IllegalArgumentException", NULL);
124 return 0;
125 } else if (err != NO_ERROR) {
126 jniThrowException(env, OutOfResourcesException, NULL);
127 return 0;
128 }
129
130 surface->incStrong((void *)nativeCreate);
131 return reinterpret_cast<jlong>(surface.get());
132 }
133
nativeRelease(JNIEnv * env,jclass clazz,jlong nativeObject)134 static void nativeRelease(JNIEnv* env, jclass clazz, jlong nativeObject) {
135 sp<SurfaceControl> ctrl(reinterpret_cast<SurfaceControl *>(nativeObject));
136 ctrl->decStrong((void *)nativeCreate);
137 }
138
nativeDestroy(JNIEnv * env,jclass clazz,jlong nativeObject)139 static void nativeDestroy(JNIEnv* env, jclass clazz, jlong nativeObject) {
140 sp<SurfaceControl> ctrl(reinterpret_cast<SurfaceControl *>(nativeObject));
141 ctrl->clear();
142 ctrl->decStrong((void *)nativeCreate);
143 }
144
nativeDisconnect(JNIEnv * env,jclass clazz,jlong nativeObject)145 static void nativeDisconnect(JNIEnv* env, jclass clazz, jlong nativeObject) {
146 SurfaceControl* const ctrl = reinterpret_cast<SurfaceControl *>(nativeObject);
147 if (ctrl != NULL) {
148 ctrl->disconnect();
149 }
150 }
151
rectFromObj(JNIEnv * env,jobject rectObj)152 static Rect rectFromObj(JNIEnv* env, jobject rectObj) {
153 int left = env->GetIntField(rectObj, gRectClassInfo.left);
154 int top = env->GetIntField(rectObj, gRectClassInfo.top);
155 int right = env->GetIntField(rectObj, gRectClassInfo.right);
156 int bottom = env->GetIntField(rectObj, gRectClassInfo.bottom);
157 return Rect(left, top, right, bottom);
158 }
159
nativeScreenshotToBuffer(JNIEnv * env,jclass clazz,jobject displayTokenObj,jobject sourceCropObj,jint width,jint height,jint minLayer,jint maxLayer,bool allLayers,bool useIdentityTransform,int rotation,bool captureSecureLayers)160 static jobject nativeScreenshotToBuffer(JNIEnv* env, jclass clazz,
161 jobject displayTokenObj, jobject sourceCropObj, jint width, jint height,
162 jint minLayer, jint maxLayer, bool allLayers, bool useIdentityTransform,
163 int rotation, bool captureSecureLayers) {
164 sp<IBinder> displayToken = ibinderForJavaObject(env, displayTokenObj);
165 if (displayToken == NULL) {
166 return NULL;
167 }
168 Rect sourceCrop = rectFromObj(env, sourceCropObj);
169 if (allLayers) {
170 minLayer = INT32_MIN;
171 maxLayer = INT32_MAX;
172 }
173 sp<GraphicBuffer> buffer;
174 bool capturedSecureLayers = false;
175 status_t res = ScreenshotClient::capture(displayToken,
176 sourceCrop, width, height, minLayer, maxLayer, useIdentityTransform,
177 rotation, captureSecureLayers, &buffer, capturedSecureLayers);
178 if (res != NO_ERROR) {
179 return NULL;
180 }
181
182 return env->CallStaticObjectMethod(gGraphicBufferClassInfo.clazz,
183 gGraphicBufferClassInfo.builder,
184 buffer->getWidth(),
185 buffer->getHeight(),
186 buffer->getPixelFormat(),
187 (jint)buffer->getUsage(),
188 (jlong)buffer.get(),
189 capturedSecureLayers);
190 }
191
nativeScreenshotBitmap(JNIEnv * env,jclass clazz,jobject displayTokenObj,jobject sourceCropObj,jint width,jint height,jint minLayer,jint maxLayer,bool allLayers,bool useIdentityTransform,int rotation)192 static jobject nativeScreenshotBitmap(JNIEnv* env, jclass clazz,
193 jobject displayTokenObj, jobject sourceCropObj, jint width, jint height,
194 jint minLayer, jint maxLayer, bool allLayers, bool useIdentityTransform,
195 int rotation) {
196 sp<IBinder> displayToken = ibinderForJavaObject(env, displayTokenObj);
197 if (displayToken == NULL) {
198 return NULL;
199 }
200
201 Rect sourceCrop = rectFromObj(env, sourceCropObj);
202
203 std::unique_ptr<ScreenshotClient> screenshot(new ScreenshotClient());
204 status_t res;
205 if (allLayers) {
206 minLayer = INT32_MIN;
207 maxLayer = INT32_MAX;
208 }
209
210 sp<GraphicBuffer> buffer;
211 res = ScreenshotClient::capture(displayToken, sourceCrop, width, height,
212 minLayer, maxLayer, useIdentityTransform, static_cast<uint32_t>(rotation), &buffer);
213 if (res != NO_ERROR) {
214 return NULL;
215 }
216
217 SkColorType colorType;
218 SkAlphaType alphaType;
219
220 PixelFormat format = buffer->getPixelFormat();
221 switch (format) {
222 case PIXEL_FORMAT_RGBX_8888: {
223 colorType = kRGBA_8888_SkColorType;
224 alphaType = kOpaque_SkAlphaType;
225 break;
226 }
227 case PIXEL_FORMAT_RGBA_8888: {
228 colorType = kRGBA_8888_SkColorType;
229 alphaType = kPremul_SkAlphaType;
230 break;
231 }
232 case PIXEL_FORMAT_RGBA_FP16: {
233 colorType = kRGBA_F16_SkColorType;
234 alphaType = kPremul_SkAlphaType;
235 break;
236 }
237 case PIXEL_FORMAT_RGB_565: {
238 colorType = kRGB_565_SkColorType;
239 alphaType = kOpaque_SkAlphaType;
240 break;
241 }
242 default: {
243 return NULL;
244 }
245 }
246
247 SkImageInfo info = SkImageInfo::Make(buffer->getWidth(), buffer->getHeight(),
248 colorType, alphaType,
249 SkColorSpace::MakeSRGB());
250
251 auto bitmap = sk_sp<Bitmap>(new Bitmap(buffer.get(), info));
252 return bitmap::createBitmap(env, bitmap.release(),
253 android::bitmap::kBitmapCreateFlag_Premultiplied, NULL);
254 }
255
nativeScreenshot(JNIEnv * env,jclass clazz,jobject displayTokenObj,jobject surfaceObj,jobject sourceCropObj,jint width,jint height,jint minLayer,jint maxLayer,bool allLayers,bool useIdentityTransform)256 static void nativeScreenshot(JNIEnv* env, jclass clazz, jobject displayTokenObj,
257 jobject surfaceObj, jobject sourceCropObj, jint width, jint height,
258 jint minLayer, jint maxLayer, bool allLayers, bool useIdentityTransform) {
259 sp<IBinder> displayToken = ibinderForJavaObject(env, displayTokenObj);
260 if (displayToken == NULL) {
261 return;
262 }
263
264 sp<Surface> consumer = android_view_Surface_getSurface(env, surfaceObj);
265 if (consumer == NULL) {
266 return;
267 }
268
269 Rect sourceCrop;
270 if (sourceCropObj != NULL) {
271 sourceCrop = rectFromObj(env, sourceCropObj);
272 }
273
274 if (allLayers) {
275 minLayer = INT32_MIN;
276 maxLayer = INT32_MAX;
277 }
278
279 sp<GraphicBuffer> buffer;
280 ScreenshotClient::capture(displayToken, sourceCrop, width, height, minLayer, maxLayer,
281 useIdentityTransform, 0, &buffer);
282
283 Surface::attachAndQueueBuffer(consumer.get(), buffer);
284 }
285
nativeCaptureLayers(JNIEnv * env,jclass clazz,jobject layerHandleToken,jobject sourceCropObj,jfloat frameScale)286 static jobject nativeCaptureLayers(JNIEnv* env, jclass clazz, jobject layerHandleToken,
287 jobject sourceCropObj, jfloat frameScale) {
288
289 sp<IBinder> layerHandle = ibinderForJavaObject(env, layerHandleToken);
290 if (layerHandle == NULL) {
291 return NULL;
292 }
293
294 Rect sourceCrop;
295 if (sourceCropObj != NULL) {
296 sourceCrop = rectFromObj(env, sourceCropObj);
297 }
298
299 sp<GraphicBuffer> buffer;
300 status_t res = ScreenshotClient::captureChildLayers(layerHandle, sourceCrop, frameScale, &buffer);
301 if (res != NO_ERROR) {
302 return NULL;
303 }
304
305 return env->CallStaticObjectMethod(gGraphicBufferClassInfo.clazz,
306 gGraphicBufferClassInfo.builder,
307 buffer->getWidth(),
308 buffer->getHeight(),
309 buffer->getPixelFormat(),
310 (jint)buffer->getUsage(),
311 (jlong)buffer.get(),
312 false /* capturedSecureLayers */);
313 }
314
nativeApplyTransaction(JNIEnv * env,jclass clazz,jlong transactionObj,jboolean sync)315 static void nativeApplyTransaction(JNIEnv* env, jclass clazz, jlong transactionObj, jboolean sync) {
316 auto transaction = reinterpret_cast<SurfaceComposerClient::Transaction*>(transactionObj);
317 transaction->apply(sync);
318 }
319
nativeMergeTransaction(JNIEnv * env,jclass clazz,jlong transactionObj,jlong otherTransactionObj)320 static void nativeMergeTransaction(JNIEnv* env, jclass clazz,
321 jlong transactionObj, jlong otherTransactionObj) {
322 auto transaction = reinterpret_cast<SurfaceComposerClient::Transaction*>(transactionObj);
323 auto otherTransaction = reinterpret_cast<SurfaceComposerClient::Transaction*>(
324 otherTransactionObj);
325 transaction->merge(std::move(*otherTransaction));
326 }
327
nativeSetAnimationTransaction(JNIEnv * env,jclass clazz,jlong transactionObj)328 static void nativeSetAnimationTransaction(JNIEnv* env, jclass clazz, jlong transactionObj) {
329 auto transaction = reinterpret_cast<SurfaceComposerClient::Transaction*>(transactionObj);
330 transaction->setAnimationTransaction();
331 }
332
nativeSetEarlyWakeup(JNIEnv * env,jclass clazz,jlong transactionObj)333 static void nativeSetEarlyWakeup(JNIEnv* env, jclass clazz, jlong transactionObj) {
334 auto transaction = reinterpret_cast<SurfaceComposerClient::Transaction*>(transactionObj);
335 transaction->setEarlyWakeup();
336 }
337
nativeSetLayer(JNIEnv * env,jclass clazz,jlong transactionObj,jlong nativeObject,jint zorder)338 static void nativeSetLayer(JNIEnv* env, jclass clazz, jlong transactionObj,
339 jlong nativeObject, jint zorder) {
340 auto transaction = reinterpret_cast<SurfaceComposerClient::Transaction*>(transactionObj);
341
342 SurfaceControl* const ctrl = reinterpret_cast<SurfaceControl *>(nativeObject);
343 transaction->setLayer(ctrl, zorder);
344 }
345
nativeSetRelativeLayer(JNIEnv * env,jclass clazz,jlong transactionObj,jlong nativeObject,jobject relativeTo,jint zorder)346 static void nativeSetRelativeLayer(JNIEnv* env, jclass clazz, jlong transactionObj,
347 jlong nativeObject,
348 jobject relativeTo, jint zorder) {
349
350 auto ctrl = reinterpret_cast<SurfaceControl *>(nativeObject);
351 sp<IBinder> handle = ibinderForJavaObject(env, relativeTo);
352
353 {
354 auto transaction = reinterpret_cast<SurfaceComposerClient::Transaction*>(transactionObj);
355 transaction->setRelativeLayer(ctrl, handle, zorder);
356 }
357 }
358
nativeSetPosition(JNIEnv * env,jclass clazz,jlong transactionObj,jlong nativeObject,jfloat x,jfloat y)359 static void nativeSetPosition(JNIEnv* env, jclass clazz, jlong transactionObj,
360 jlong nativeObject, jfloat x, jfloat y) {
361 auto transaction = reinterpret_cast<SurfaceComposerClient::Transaction*>(transactionObj);
362
363 SurfaceControl* const ctrl = reinterpret_cast<SurfaceControl *>(nativeObject);
364 transaction->setPosition(ctrl, x, y);
365 }
366
nativeSetGeometryAppliesWithResize(JNIEnv * env,jclass clazz,jlong transactionObj,jlong nativeObject)367 static void nativeSetGeometryAppliesWithResize(JNIEnv* env, jclass clazz,
368 jlong transactionObj,
369 jlong nativeObject) {
370 auto transaction = reinterpret_cast<SurfaceComposerClient::Transaction*>(transactionObj);
371
372 SurfaceControl* const ctrl = reinterpret_cast<SurfaceControl *>(nativeObject);
373 transaction->setGeometryAppliesWithResize(ctrl);
374 }
375
nativeSetSize(JNIEnv * env,jclass clazz,jlong transactionObj,jlong nativeObject,jint w,jint h)376 static void nativeSetSize(JNIEnv* env, jclass clazz, jlong transactionObj,
377 jlong nativeObject, jint w, jint h) {
378 auto transaction = reinterpret_cast<SurfaceComposerClient::Transaction*>(transactionObj);
379
380 SurfaceControl* const ctrl = reinterpret_cast<SurfaceControl *>(nativeObject);
381 transaction->setSize(ctrl, w, h);
382 }
383
nativeSetFlags(JNIEnv * env,jclass clazz,jlong transactionObj,jlong nativeObject,jint flags,jint mask)384 static void nativeSetFlags(JNIEnv* env, jclass clazz, jlong transactionObj,
385 jlong nativeObject, jint flags, jint mask) {
386 auto transaction = reinterpret_cast<SurfaceComposerClient::Transaction*>(transactionObj);
387
388 SurfaceControl* const ctrl = reinterpret_cast<SurfaceControl *>(nativeObject);
389 transaction->setFlags(ctrl, flags, mask);
390 }
391
nativeSetTransparentRegionHint(JNIEnv * env,jclass clazz,jlong transactionObj,jlong nativeObject,jobject regionObj)392 static void nativeSetTransparentRegionHint(JNIEnv* env, jclass clazz, jlong transactionObj,
393 jlong nativeObject, jobject regionObj) {
394 SurfaceControl* const ctrl = reinterpret_cast<SurfaceControl *>(nativeObject);
395 SkRegion* region = android_graphics_Region_getSkRegion(env, regionObj);
396 if (!region) {
397 doThrowIAE(env);
398 return;
399 }
400
401 const SkIRect& b(region->getBounds());
402 Region reg(Rect(b.fLeft, b.fTop, b.fRight, b.fBottom));
403 if (region->isComplex()) {
404 SkRegion::Iterator it(*region);
405 while (!it.done()) {
406 const SkIRect& r(it.rect());
407 reg.addRectUnchecked(r.fLeft, r.fTop, r.fRight, r.fBottom);
408 it.next();
409 }
410 }
411
412 {
413 auto transaction = reinterpret_cast<SurfaceComposerClient::Transaction*>(transactionObj);
414 transaction->setTransparentRegionHint(ctrl, reg);
415 }
416 }
417
nativeSetAlpha(JNIEnv * env,jclass clazz,jlong transactionObj,jlong nativeObject,jfloat alpha)418 static void nativeSetAlpha(JNIEnv* env, jclass clazz, jlong transactionObj,
419 jlong nativeObject, jfloat alpha) {
420 auto transaction = reinterpret_cast<SurfaceComposerClient::Transaction*>(transactionObj);
421
422 SurfaceControl* const ctrl = reinterpret_cast<SurfaceControl *>(nativeObject);
423 transaction->setAlpha(ctrl, alpha);
424 }
425
nativeSetColor(JNIEnv * env,jclass clazz,jlong transactionObj,jlong nativeObject,jfloatArray fColor)426 static void nativeSetColor(JNIEnv* env, jclass clazz, jlong transactionObj,
427 jlong nativeObject, jfloatArray fColor) {
428 auto transaction = reinterpret_cast<SurfaceComposerClient::Transaction*>(transactionObj);
429 SurfaceControl* const ctrl = reinterpret_cast<SurfaceControl *>(nativeObject);
430
431 float* floatColors = env->GetFloatArrayElements(fColor, 0);
432 half3 color(floatColors[0], floatColors[1], floatColors[2]);
433 transaction->setColor(ctrl, color);
434 }
435
nativeSetMatrix(JNIEnv * env,jclass clazz,jlong transactionObj,jlong nativeObject,jfloat dsdx,jfloat dtdx,jfloat dtdy,jfloat dsdy)436 static void nativeSetMatrix(JNIEnv* env, jclass clazz, jlong transactionObj,
437 jlong nativeObject,
438 jfloat dsdx, jfloat dtdx, jfloat dtdy, jfloat dsdy) {
439 auto transaction = reinterpret_cast<SurfaceComposerClient::Transaction*>(transactionObj);
440
441 SurfaceControl* const ctrl = reinterpret_cast<SurfaceControl *>(nativeObject);
442 transaction->setMatrix(ctrl, dsdx, dtdx, dtdy, dsdy);
443 }
444
nativeSetWindowCrop(JNIEnv * env,jclass clazz,jlong transactionObj,jlong nativeObject,jint l,jint t,jint r,jint b)445 static void nativeSetWindowCrop(JNIEnv* env, jclass clazz, jlong transactionObj,
446 jlong nativeObject,
447 jint l, jint t, jint r, jint b) {
448 auto transaction = reinterpret_cast<SurfaceComposerClient::Transaction*>(transactionObj);
449
450 SurfaceControl* const ctrl = reinterpret_cast<SurfaceControl *>(nativeObject);
451 Rect crop(l, t, r, b);
452 transaction->setCrop(ctrl, crop);
453 }
454
nativeSetFinalCrop(JNIEnv * env,jclass clazz,jlong transactionObj,jlong nativeObject,jint l,jint t,jint r,jint b)455 static void nativeSetFinalCrop(JNIEnv* env, jclass clazz, jlong transactionObj,
456 jlong nativeObject,
457 jint l, jint t, jint r, jint b) {
458 auto transaction = reinterpret_cast<SurfaceComposerClient::Transaction*>(transactionObj);
459
460 SurfaceControl* const ctrl = reinterpret_cast<SurfaceControl *>(nativeObject);
461 Rect crop(l, t, r, b);
462 transaction->setFinalCrop(ctrl, crop);
463 }
464
nativeSetLayerStack(JNIEnv * env,jclass clazz,jlong transactionObj,jlong nativeObject,jint layerStack)465 static void nativeSetLayerStack(JNIEnv* env, jclass clazz, jlong transactionObj,
466 jlong nativeObject, jint layerStack) {
467 auto transaction = reinterpret_cast<SurfaceComposerClient::Transaction*>(transactionObj);
468
469 SurfaceControl* const ctrl = reinterpret_cast<SurfaceControl *>(nativeObject);
470 transaction->setLayerStack(ctrl, layerStack);
471 }
472
nativeGetBuiltInDisplay(JNIEnv * env,jclass clazz,jint id)473 static jobject nativeGetBuiltInDisplay(JNIEnv* env, jclass clazz, jint id) {
474 sp<IBinder> token(SurfaceComposerClient::getBuiltInDisplay(id));
475 return javaObjectForIBinder(env, token);
476 }
477
nativeCreateDisplay(JNIEnv * env,jclass clazz,jstring nameObj,jboolean secure)478 static jobject nativeCreateDisplay(JNIEnv* env, jclass clazz, jstring nameObj,
479 jboolean secure) {
480 ScopedUtfChars name(env, nameObj);
481 sp<IBinder> token(SurfaceComposerClient::createDisplay(
482 String8(name.c_str()), bool(secure)));
483 return javaObjectForIBinder(env, token);
484 }
485
nativeDestroyDisplay(JNIEnv * env,jclass clazz,jobject tokenObj)486 static void nativeDestroyDisplay(JNIEnv* env, jclass clazz, jobject tokenObj) {
487 sp<IBinder> token(ibinderForJavaObject(env, tokenObj));
488 if (token == NULL) return;
489 SurfaceComposerClient::destroyDisplay(token);
490 }
491
nativeSetDisplaySurface(JNIEnv * env,jclass clazz,jlong transactionObj,jobject tokenObj,jlong nativeSurfaceObject)492 static void nativeSetDisplaySurface(JNIEnv* env, jclass clazz,
493 jlong transactionObj,
494 jobject tokenObj, jlong nativeSurfaceObject) {
495 sp<IBinder> token(ibinderForJavaObject(env, tokenObj));
496 if (token == NULL) return;
497 sp<IGraphicBufferProducer> bufferProducer;
498 sp<Surface> sur(reinterpret_cast<Surface *>(nativeSurfaceObject));
499 if (sur != NULL) {
500 bufferProducer = sur->getIGraphicBufferProducer();
501 }
502
503
504 status_t err = NO_ERROR;
505 {
506 auto transaction = reinterpret_cast<SurfaceComposerClient::Transaction*>(transactionObj);
507 err = transaction->setDisplaySurface(token,
508 bufferProducer);
509 }
510 if (err != NO_ERROR) {
511 doThrowIAE(env, "Illegal Surface, could not enable async mode. Was this"
512 " Surface created with singleBufferMode?");
513 }
514 }
515
nativeSetDisplayLayerStack(JNIEnv * env,jclass clazz,jlong transactionObj,jobject tokenObj,jint layerStack)516 static void nativeSetDisplayLayerStack(JNIEnv* env, jclass clazz,
517 jlong transactionObj,
518 jobject tokenObj, jint layerStack) {
519
520 sp<IBinder> token(ibinderForJavaObject(env, tokenObj));
521 if (token == NULL) return;
522
523 {
524 auto transaction = reinterpret_cast<SurfaceComposerClient::Transaction*>(transactionObj);
525 transaction->setDisplayLayerStack(token, layerStack);
526 }
527 }
528
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)529 static void nativeSetDisplayProjection(JNIEnv* env, jclass clazz,
530 jlong transactionObj,
531 jobject tokenObj, jint orientation,
532 jint layerStackRect_left, jint layerStackRect_top, jint layerStackRect_right, jint layerStackRect_bottom,
533 jint displayRect_left, jint displayRect_top, jint displayRect_right, jint displayRect_bottom) {
534 sp<IBinder> token(ibinderForJavaObject(env, tokenObj));
535 if (token == NULL) return;
536 Rect layerStackRect(layerStackRect_left, layerStackRect_top, layerStackRect_right, layerStackRect_bottom);
537 Rect displayRect(displayRect_left, displayRect_top, displayRect_right, displayRect_bottom);
538
539 {
540 auto transaction = reinterpret_cast<SurfaceComposerClient::Transaction*>(transactionObj);
541 transaction->setDisplayProjection(token, orientation, layerStackRect, displayRect);
542 }
543 }
544
nativeSetDisplaySize(JNIEnv * env,jclass clazz,jlong transactionObj,jobject tokenObj,jint width,jint height)545 static void nativeSetDisplaySize(JNIEnv* env, jclass clazz,
546 jlong transactionObj,
547 jobject tokenObj, jint width, jint height) {
548 sp<IBinder> token(ibinderForJavaObject(env, tokenObj));
549 if (token == NULL) return;
550
551 {
552 auto transaction = reinterpret_cast<SurfaceComposerClient::Transaction*>(transactionObj);
553 transaction->setDisplaySize(token, width, height);
554 }
555 }
556
nativeGetDisplayConfigs(JNIEnv * env,jclass clazz,jobject tokenObj)557 static jobjectArray nativeGetDisplayConfigs(JNIEnv* env, jclass clazz,
558 jobject tokenObj) {
559 sp<IBinder> token(ibinderForJavaObject(env, tokenObj));
560 if (token == NULL) return NULL;
561
562 Vector<DisplayInfo> configs;
563 if (SurfaceComposerClient::getDisplayConfigs(token, &configs) != NO_ERROR ||
564 configs.size() == 0) {
565 return NULL;
566 }
567
568 jobjectArray configArray = env->NewObjectArray(configs.size(),
569 gPhysicalDisplayInfoClassInfo.clazz, NULL);
570
571 for (size_t c = 0; c < configs.size(); ++c) {
572 const DisplayInfo& info = configs[c];
573 jobject infoObj = env->NewObject(gPhysicalDisplayInfoClassInfo.clazz,
574 gPhysicalDisplayInfoClassInfo.ctor);
575 env->SetIntField(infoObj, gPhysicalDisplayInfoClassInfo.width, info.w);
576 env->SetIntField(infoObj, gPhysicalDisplayInfoClassInfo.height, info.h);
577 env->SetFloatField(infoObj, gPhysicalDisplayInfoClassInfo.refreshRate, info.fps);
578 env->SetFloatField(infoObj, gPhysicalDisplayInfoClassInfo.density, info.density);
579 env->SetFloatField(infoObj, gPhysicalDisplayInfoClassInfo.xDpi, info.xdpi);
580 env->SetFloatField(infoObj, gPhysicalDisplayInfoClassInfo.yDpi, info.ydpi);
581 env->SetBooleanField(infoObj, gPhysicalDisplayInfoClassInfo.secure, info.secure);
582 env->SetLongField(infoObj, gPhysicalDisplayInfoClassInfo.appVsyncOffsetNanos,
583 info.appVsyncOffset);
584 env->SetLongField(infoObj, gPhysicalDisplayInfoClassInfo.presentationDeadlineNanos,
585 info.presentationDeadline);
586 env->SetObjectArrayElement(configArray, static_cast<jsize>(c), infoObj);
587 env->DeleteLocalRef(infoObj);
588 }
589
590 return configArray;
591 }
592
nativeGetActiveConfig(JNIEnv * env,jclass clazz,jobject tokenObj)593 static jint nativeGetActiveConfig(JNIEnv* env, jclass clazz, jobject tokenObj) {
594 sp<IBinder> token(ibinderForJavaObject(env, tokenObj));
595 if (token == NULL) return -1;
596 return static_cast<jint>(SurfaceComposerClient::getActiveConfig(token));
597 }
598
nativeSetActiveConfig(JNIEnv * env,jclass clazz,jobject tokenObj,jint id)599 static jboolean nativeSetActiveConfig(JNIEnv* env, jclass clazz, jobject tokenObj, jint id) {
600 sp<IBinder> token(ibinderForJavaObject(env, tokenObj));
601 if (token == NULL) return JNI_FALSE;
602 status_t err = SurfaceComposerClient::setActiveConfig(token, static_cast<int>(id));
603 return err == NO_ERROR ? JNI_TRUE : JNI_FALSE;
604 }
605
nativeGetDisplayColorModes(JNIEnv * env,jclass,jobject tokenObj)606 static jintArray nativeGetDisplayColorModes(JNIEnv* env, jclass, jobject tokenObj) {
607 sp<IBinder> token(ibinderForJavaObject(env, tokenObj));
608 if (token == NULL) return NULL;
609 Vector<ui::ColorMode> colorModes;
610 if (SurfaceComposerClient::getDisplayColorModes(token, &colorModes) != NO_ERROR ||
611 colorModes.isEmpty()) {
612 return NULL;
613 }
614
615 jintArray colorModesArray = env->NewIntArray(colorModes.size());
616 if (colorModesArray == NULL) {
617 jniThrowException(env, "java/lang/OutOfMemoryError", NULL);
618 return NULL;
619 }
620 jint* colorModesArrayValues = env->GetIntArrayElements(colorModesArray, 0);
621 for (size_t i = 0; i < colorModes.size(); i++) {
622 colorModesArrayValues[i] = static_cast<jint>(colorModes[i]);
623 }
624 env->ReleaseIntArrayElements(colorModesArray, colorModesArrayValues, 0);
625 return colorModesArray;
626 }
627
nativeGetActiveColorMode(JNIEnv * env,jclass,jobject tokenObj)628 static jint nativeGetActiveColorMode(JNIEnv* env, jclass, jobject tokenObj) {
629 sp<IBinder> token(ibinderForJavaObject(env, tokenObj));
630 if (token == NULL) return -1;
631 return static_cast<jint>(SurfaceComposerClient::getActiveColorMode(token));
632 }
633
nativeSetActiveColorMode(JNIEnv * env,jclass,jobject tokenObj,jint colorMode)634 static jboolean nativeSetActiveColorMode(JNIEnv* env, jclass,
635 jobject tokenObj, jint colorMode) {
636 sp<IBinder> token(ibinderForJavaObject(env, tokenObj));
637 if (token == NULL) return JNI_FALSE;
638 status_t err = SurfaceComposerClient::setActiveColorMode(token,
639 static_cast<ui::ColorMode>(colorMode));
640 return err == NO_ERROR ? JNI_TRUE : JNI_FALSE;
641 }
642
nativeSetDisplayPowerMode(JNIEnv * env,jclass clazz,jobject tokenObj,jint mode)643 static void nativeSetDisplayPowerMode(JNIEnv* env, jclass clazz, jobject tokenObj, jint mode) {
644 sp<IBinder> token(ibinderForJavaObject(env, tokenObj));
645 if (token == NULL) return;
646
647 android::base::Timer t;
648 SurfaceComposerClient::setDisplayPowerMode(token, mode);
649 if (t.duration() > 100ms) ALOGD("Excessive delay in setPowerMode()");
650 }
651
nativeClearContentFrameStats(JNIEnv * env,jclass clazz,jlong nativeObject)652 static jboolean nativeClearContentFrameStats(JNIEnv* env, jclass clazz, jlong nativeObject) {
653 SurfaceControl* const ctrl = reinterpret_cast<SurfaceControl *>(nativeObject);
654 status_t err = ctrl->clearLayerFrameStats();
655
656 if (err < 0 && err != NO_INIT) {
657 doThrowIAE(env);
658 }
659
660 // The other end is not ready, just report we failed.
661 if (err == NO_INIT) {
662 return JNI_FALSE;
663 }
664
665 return JNI_TRUE;
666 }
667
nativeGetContentFrameStats(JNIEnv * env,jclass clazz,jlong nativeObject,jobject outStats)668 static jboolean nativeGetContentFrameStats(JNIEnv* env, jclass clazz, jlong nativeObject,
669 jobject outStats) {
670 FrameStats stats;
671
672 SurfaceControl* const ctrl = reinterpret_cast<SurfaceControl *>(nativeObject);
673 status_t err = ctrl->getLayerFrameStats(&stats);
674 if (err < 0 && err != NO_INIT) {
675 doThrowIAE(env);
676 }
677
678 // The other end is not ready, fine just return empty stats.
679 if (err == NO_INIT) {
680 return JNI_FALSE;
681 }
682
683 jlong refreshPeriodNano = static_cast<jlong>(stats.refreshPeriodNano);
684 size_t frameCount = stats.desiredPresentTimesNano.size();
685
686 jlongArray postedTimesNanoDst = env->NewLongArray(frameCount);
687 if (postedTimesNanoDst == NULL) {
688 return JNI_FALSE;
689 }
690
691 jlongArray presentedTimesNanoDst = env->NewLongArray(frameCount);
692 if (presentedTimesNanoDst == NULL) {
693 return JNI_FALSE;
694 }
695
696 jlongArray readyTimesNanoDst = env->NewLongArray(frameCount);
697 if (readyTimesNanoDst == NULL) {
698 return JNI_FALSE;
699 }
700
701 nsecs_t postedTimesNanoSrc[frameCount];
702 nsecs_t presentedTimesNanoSrc[frameCount];
703 nsecs_t readyTimesNanoSrc[frameCount];
704
705 for (size_t i = 0; i < frameCount; i++) {
706 nsecs_t postedTimeNano = stats.desiredPresentTimesNano[i];
707 if (postedTimeNano == INT64_MAX) {
708 postedTimeNano = gWindowContentFrameStatsClassInfo.UNDEFINED_TIME_NANO;
709 }
710 postedTimesNanoSrc[i] = postedTimeNano;
711
712 nsecs_t presentedTimeNano = stats.actualPresentTimesNano[i];
713 if (presentedTimeNano == INT64_MAX) {
714 presentedTimeNano = gWindowContentFrameStatsClassInfo.UNDEFINED_TIME_NANO;
715 }
716 presentedTimesNanoSrc[i] = presentedTimeNano;
717
718 nsecs_t readyTimeNano = stats.frameReadyTimesNano[i];
719 if (readyTimeNano == INT64_MAX) {
720 readyTimeNano = gWindowContentFrameStatsClassInfo.UNDEFINED_TIME_NANO;
721 }
722 readyTimesNanoSrc[i] = readyTimeNano;
723 }
724
725 env->SetLongArrayRegion(postedTimesNanoDst, 0, frameCount, postedTimesNanoSrc);
726 env->SetLongArrayRegion(presentedTimesNanoDst, 0, frameCount, presentedTimesNanoSrc);
727 env->SetLongArrayRegion(readyTimesNanoDst, 0, frameCount, readyTimesNanoSrc);
728
729 env->CallVoidMethod(outStats, gWindowContentFrameStatsClassInfo.init, refreshPeriodNano,
730 postedTimesNanoDst, presentedTimesNanoDst, readyTimesNanoDst);
731
732 if (env->ExceptionCheck()) {
733 return JNI_FALSE;
734 }
735
736 return JNI_TRUE;
737 }
738
nativeClearAnimationFrameStats(JNIEnv * env,jclass clazz)739 static jboolean nativeClearAnimationFrameStats(JNIEnv* env, jclass clazz) {
740 status_t err = SurfaceComposerClient::clearAnimationFrameStats();
741
742 if (err < 0 && err != NO_INIT) {
743 doThrowIAE(env);
744 }
745
746 // The other end is not ready, just report we failed.
747 if (err == NO_INIT) {
748 return JNI_FALSE;
749 }
750
751 return JNI_TRUE;
752 }
753
nativeGetAnimationFrameStats(JNIEnv * env,jclass clazz,jobject outStats)754 static jboolean nativeGetAnimationFrameStats(JNIEnv* env, jclass clazz, jobject outStats) {
755 FrameStats stats;
756
757 status_t err = SurfaceComposerClient::getAnimationFrameStats(&stats);
758 if (err < 0 && err != NO_INIT) {
759 doThrowIAE(env);
760 }
761
762 // The other end is not ready, fine just return empty stats.
763 if (err == NO_INIT) {
764 return JNI_FALSE;
765 }
766
767 jlong refreshPeriodNano = static_cast<jlong>(stats.refreshPeriodNano);
768 size_t frameCount = stats.desiredPresentTimesNano.size();
769
770 jlongArray presentedTimesNanoDst = env->NewLongArray(frameCount);
771 if (presentedTimesNanoDst == NULL) {
772 return JNI_FALSE;
773 }
774
775 nsecs_t presentedTimesNanoSrc[frameCount];
776
777 for (size_t i = 0; i < frameCount; i++) {
778 nsecs_t presentedTimeNano = stats.actualPresentTimesNano[i];
779 if (presentedTimeNano == INT64_MAX) {
780 presentedTimeNano = gWindowContentFrameStatsClassInfo.UNDEFINED_TIME_NANO;
781 }
782 presentedTimesNanoSrc[i] = presentedTimeNano;
783 }
784
785 env->SetLongArrayRegion(presentedTimesNanoDst, 0, frameCount, presentedTimesNanoSrc);
786
787 env->CallVoidMethod(outStats, gWindowAnimationFrameStatsClassInfo.init, refreshPeriodNano,
788 presentedTimesNanoDst);
789
790 if (env->ExceptionCheck()) {
791 return JNI_FALSE;
792 }
793
794 return JNI_TRUE;
795 }
796
nativeDeferTransactionUntil(JNIEnv * env,jclass clazz,jlong transactionObj,jlong nativeObject,jobject handleObject,jlong frameNumber)797 static void nativeDeferTransactionUntil(JNIEnv* env, jclass clazz, jlong transactionObj,
798 jlong nativeObject,
799 jobject handleObject, jlong frameNumber) {
800 auto ctrl = reinterpret_cast<SurfaceControl *>(nativeObject);
801 sp<IBinder> handle = ibinderForJavaObject(env, handleObject);
802
803 {
804 auto transaction = reinterpret_cast<SurfaceComposerClient::Transaction*>(transactionObj);
805 transaction->deferTransactionUntil(ctrl, handle, frameNumber);
806 }
807 }
808
nativeDeferTransactionUntilSurface(JNIEnv * env,jclass clazz,jlong transactionObj,jlong nativeObject,jlong surfaceObject,jlong frameNumber)809 static void nativeDeferTransactionUntilSurface(JNIEnv* env, jclass clazz, jlong transactionObj,
810 jlong nativeObject,
811 jlong surfaceObject, jlong frameNumber) {
812 auto transaction = reinterpret_cast<SurfaceComposerClient::Transaction*>(transactionObj);
813
814 auto ctrl = reinterpret_cast<SurfaceControl *>(nativeObject);
815 sp<Surface> barrier = reinterpret_cast<Surface *>(surfaceObject);
816
817 transaction->deferTransactionUntil(ctrl, barrier, frameNumber);
818 }
819
nativeReparentChildren(JNIEnv * env,jclass clazz,jlong transactionObj,jlong nativeObject,jobject newParentObject)820 static void nativeReparentChildren(JNIEnv* env, jclass clazz, jlong transactionObj,
821 jlong nativeObject,
822 jobject newParentObject) {
823
824 auto ctrl = reinterpret_cast<SurfaceControl *>(nativeObject);
825 sp<IBinder> handle = ibinderForJavaObject(env, newParentObject);
826
827 {
828 auto transaction = reinterpret_cast<SurfaceComposerClient::Transaction*>(transactionObj);
829 transaction->reparentChildren(ctrl, handle);
830 }
831 }
832
nativeReparent(JNIEnv * env,jclass clazz,jlong transactionObj,jlong nativeObject,jobject newParentObject)833 static void nativeReparent(JNIEnv* env, jclass clazz, jlong transactionObj,
834 jlong nativeObject,
835 jobject newParentObject) {
836 auto ctrl = reinterpret_cast<SurfaceControl *>(nativeObject);
837 sp<IBinder> parentHandle = ibinderForJavaObject(env, newParentObject);
838
839 {
840 auto transaction = reinterpret_cast<SurfaceComposerClient::Transaction*>(transactionObj);
841 transaction->reparent(ctrl, parentHandle);
842 }
843 }
844
nativeSeverChildren(JNIEnv * env,jclass clazz,jlong transactionObj,jlong nativeObject)845 static void nativeSeverChildren(JNIEnv* env, jclass clazz, jlong transactionObj,
846 jlong nativeObject) {
847 auto transaction = reinterpret_cast<SurfaceComposerClient::Transaction*>(transactionObj);
848
849 auto ctrl = reinterpret_cast<SurfaceControl *>(nativeObject);
850 transaction->detachChildren(ctrl);
851 }
852
nativeSetOverrideScalingMode(JNIEnv * env,jclass clazz,jlong transactionObj,jlong nativeObject,jint scalingMode)853 static void nativeSetOverrideScalingMode(JNIEnv* env, jclass clazz, jlong transactionObj,
854 jlong nativeObject,
855 jint scalingMode) {
856 auto transaction = reinterpret_cast<SurfaceComposerClient::Transaction*>(transactionObj);
857
858 auto ctrl = reinterpret_cast<SurfaceControl *>(nativeObject);
859 transaction->setOverrideScalingMode(ctrl, scalingMode);
860 }
861
nativeDestroyInTransaction(JNIEnv * env,jclass clazz,jlong transactionObj,jlong nativeObject)862 static void nativeDestroyInTransaction(JNIEnv* env, jclass clazz,
863 jlong transactionObj,
864 jlong nativeObject) {
865 auto transaction = reinterpret_cast<SurfaceComposerClient::Transaction*>(transactionObj);
866 auto ctrl = reinterpret_cast<SurfaceControl*>(nativeObject);
867 transaction->destroySurface(ctrl);
868 }
869
nativeGetHandle(JNIEnv * env,jclass clazz,jlong nativeObject)870 static jobject nativeGetHandle(JNIEnv* env, jclass clazz, jlong nativeObject) {
871 auto ctrl = reinterpret_cast<SurfaceControl *>(nativeObject);
872 return javaObjectForIBinder(env, ctrl->getHandle());
873 }
874
nativeGetHdrCapabilities(JNIEnv * env,jclass clazz,jobject tokenObject)875 static jobject nativeGetHdrCapabilities(JNIEnv* env, jclass clazz, jobject tokenObject) {
876 sp<IBinder> token(ibinderForJavaObject(env, tokenObject));
877 if (token == NULL) return NULL;
878
879 HdrCapabilities capabilities;
880 SurfaceComposerClient::getHdrCapabilities(token, &capabilities);
881
882 const auto& types = capabilities.getSupportedHdrTypes();
883 std::vector<int32_t> intTypes;
884 for (auto type : types) {
885 intTypes.push_back(static_cast<int32_t>(type));
886 }
887 auto typesArray = env->NewIntArray(types.size());
888 env->SetIntArrayRegion(typesArray, 0, intTypes.size(), intTypes.data());
889
890 return env->NewObject(gHdrCapabilitiesClassInfo.clazz, gHdrCapabilitiesClassInfo.ctor,
891 typesArray, capabilities.getDesiredMaxLuminance(),
892 capabilities.getDesiredMaxAverageLuminance(), capabilities.getDesiredMinLuminance());
893 }
894
nativeReadFromParcel(JNIEnv * env,jclass clazz,jobject parcelObj)895 static jlong nativeReadFromParcel(JNIEnv* env, jclass clazz, jobject parcelObj) {
896 Parcel* parcel = parcelForJavaObject(env, parcelObj);
897 if (parcel == NULL) {
898 doThrowNPE(env);
899 return 0;
900 }
901 sp<SurfaceControl> surface = SurfaceControl::readFromParcel(parcel);
902 if (surface == nullptr) {
903 return 0;
904 }
905 surface->incStrong((void *)nativeCreate);
906 return reinterpret_cast<jlong>(surface.get());
907 }
908
nativeWriteToParcel(JNIEnv * env,jclass clazz,jlong nativeObject,jobject parcelObj)909 static void nativeWriteToParcel(JNIEnv* env, jclass clazz,
910 jlong nativeObject, jobject parcelObj) {
911 Parcel* parcel = parcelForJavaObject(env, parcelObj);
912 if (parcel == NULL) {
913 doThrowNPE(env);
914 return;
915 }
916 SurfaceControl* const self = reinterpret_cast<SurfaceControl *>(nativeObject);
917 self->writeToParcel(parcel);
918 }
919
920 // ----------------------------------------------------------------------------
921
922 static const JNINativeMethod sSurfaceControlMethods[] = {
923 {"nativeCreate", "(Landroid/view/SurfaceSession;Ljava/lang/String;IIIIJII)J",
924 (void*)nativeCreate },
925 {"nativeReadFromParcel", "(Landroid/os/Parcel;)J",
926 (void*)nativeReadFromParcel },
927 {"nativeWriteToParcel", "(JLandroid/os/Parcel;)V",
928 (void*)nativeWriteToParcel },
929 {"nativeRelease", "(J)V",
930 (void*)nativeRelease },
931 {"nativeDestroy", "(J)V",
932 (void*)nativeDestroy },
933 {"nativeDisconnect", "(J)V",
934 (void*)nativeDisconnect },
935 {"nativeScreenshot", "(Landroid/os/IBinder;Landroid/graphics/Rect;IIIIZZI)Landroid/graphics/Bitmap;",
936 (void*)nativeScreenshotBitmap },
937 {"nativeScreenshot", "(Landroid/os/IBinder;Landroid/view/Surface;Landroid/graphics/Rect;IIIIZZ)V",
938 (void*)nativeScreenshot },
939 {"nativeCreateTransaction", "()J",
940 (void*)nativeCreateTransaction },
941 {"nativeApplyTransaction", "(JZ)V",
942 (void*)nativeApplyTransaction },
943 {"nativeGetNativeTransactionFinalizer", "()J",
944 (void*)nativeGetNativeTransactionFinalizer },
945 {"nativeMergeTransaction", "(JJ)V",
946 (void*)nativeMergeTransaction },
947 {"nativeSetAnimationTransaction", "(J)V",
948 (void*)nativeSetAnimationTransaction },
949 {"nativeSetEarlyWakeup", "(J)V",
950 (void*)nativeSetEarlyWakeup },
951 {"nativeSetLayer", "(JJI)V",
952 (void*)nativeSetLayer },
953 {"nativeSetRelativeLayer", "(JJLandroid/os/IBinder;I)V",
954 (void*)nativeSetRelativeLayer },
955 {"nativeSetPosition", "(JJFF)V",
956 (void*)nativeSetPosition },
957 {"nativeSetGeometryAppliesWithResize", "(JJ)V",
958 (void*)nativeSetGeometryAppliesWithResize },
959 {"nativeSetSize", "(JJII)V",
960 (void*)nativeSetSize },
961 {"nativeSetTransparentRegionHint", "(JJLandroid/graphics/Region;)V",
962 (void*)nativeSetTransparentRegionHint },
963 {"nativeSetAlpha", "(JJF)V",
964 (void*)nativeSetAlpha },
965 {"nativeSetColor", "(JJ[F)V",
966 (void*)nativeSetColor },
967 {"nativeSetMatrix", "(JJFFFF)V",
968 (void*)nativeSetMatrix },
969 {"nativeSetFlags", "(JJII)V",
970 (void*)nativeSetFlags },
971 {"nativeSetWindowCrop", "(JJIIII)V",
972 (void*)nativeSetWindowCrop },
973 {"nativeSetFinalCrop", "(JJIIII)V",
974 (void*)nativeSetFinalCrop },
975 {"nativeSetLayerStack", "(JJI)V",
976 (void*)nativeSetLayerStack },
977 {"nativeGetBuiltInDisplay", "(I)Landroid/os/IBinder;",
978 (void*)nativeGetBuiltInDisplay },
979 {"nativeCreateDisplay", "(Ljava/lang/String;Z)Landroid/os/IBinder;",
980 (void*)nativeCreateDisplay },
981 {"nativeDestroyDisplay", "(Landroid/os/IBinder;)V",
982 (void*)nativeDestroyDisplay },
983 {"nativeSetDisplaySurface", "(JLandroid/os/IBinder;J)V",
984 (void*)nativeSetDisplaySurface },
985 {"nativeSetDisplayLayerStack", "(JLandroid/os/IBinder;I)V",
986 (void*)nativeSetDisplayLayerStack },
987 {"nativeSetDisplayProjection", "(JLandroid/os/IBinder;IIIIIIIII)V",
988 (void*)nativeSetDisplayProjection },
989 {"nativeSetDisplaySize", "(JLandroid/os/IBinder;II)V",
990 (void*)nativeSetDisplaySize },
991 {"nativeGetDisplayConfigs", "(Landroid/os/IBinder;)[Landroid/view/SurfaceControl$PhysicalDisplayInfo;",
992 (void*)nativeGetDisplayConfigs },
993 {"nativeGetActiveConfig", "(Landroid/os/IBinder;)I",
994 (void*)nativeGetActiveConfig },
995 {"nativeSetActiveConfig", "(Landroid/os/IBinder;I)Z",
996 (void*)nativeSetActiveConfig },
997 {"nativeGetDisplayColorModes", "(Landroid/os/IBinder;)[I",
998 (void*)nativeGetDisplayColorModes},
999 {"nativeGetActiveColorMode", "(Landroid/os/IBinder;)I",
1000 (void*)nativeGetActiveColorMode},
1001 {"nativeSetActiveColorMode", "(Landroid/os/IBinder;I)Z",
1002 (void*)nativeSetActiveColorMode},
1003 {"nativeGetHdrCapabilities", "(Landroid/os/IBinder;)Landroid/view/Display$HdrCapabilities;",
1004 (void*)nativeGetHdrCapabilities },
1005 {"nativeClearContentFrameStats", "(J)Z",
1006 (void*)nativeClearContentFrameStats },
1007 {"nativeGetContentFrameStats", "(JLandroid/view/WindowContentFrameStats;)Z",
1008 (void*)nativeGetContentFrameStats },
1009 {"nativeClearAnimationFrameStats", "()Z",
1010 (void*)nativeClearAnimationFrameStats },
1011 {"nativeGetAnimationFrameStats", "(Landroid/view/WindowAnimationFrameStats;)Z",
1012 (void*)nativeGetAnimationFrameStats },
1013 {"nativeSetDisplayPowerMode", "(Landroid/os/IBinder;I)V",
1014 (void*)nativeSetDisplayPowerMode },
1015 {"nativeDeferTransactionUntil", "(JJLandroid/os/IBinder;J)V",
1016 (void*)nativeDeferTransactionUntil },
1017 {"nativeDeferTransactionUntilSurface", "(JJJJ)V",
1018 (void*)nativeDeferTransactionUntilSurface },
1019 {"nativeReparentChildren", "(JJLandroid/os/IBinder;)V",
1020 (void*)nativeReparentChildren } ,
1021 {"nativeReparent", "(JJLandroid/os/IBinder;)V",
1022 (void*)nativeReparent },
1023 {"nativeSeverChildren", "(JJ)V",
1024 (void*)nativeSeverChildren } ,
1025 {"nativeSetOverrideScalingMode", "(JJI)V",
1026 (void*)nativeSetOverrideScalingMode },
1027 {"nativeDestroy", "(JJ)V",
1028 (void*)nativeDestroyInTransaction },
1029 {"nativeGetHandle", "(J)Landroid/os/IBinder;",
1030 (void*)nativeGetHandle },
1031 {"nativeScreenshotToBuffer",
1032 "(Landroid/os/IBinder;Landroid/graphics/Rect;IIIIZZIZ)Landroid/graphics/GraphicBuffer;",
1033 (void*)nativeScreenshotToBuffer },
1034 {"nativeCaptureLayers", "(Landroid/os/IBinder;Landroid/graphics/Rect;F)Landroid/graphics/GraphicBuffer;",
1035 (void*)nativeCaptureLayers },
1036 };
1037
register_android_view_SurfaceControl(JNIEnv * env)1038 int register_android_view_SurfaceControl(JNIEnv* env)
1039 {
1040 int err = RegisterMethodsOrDie(env, "android/view/SurfaceControl",
1041 sSurfaceControlMethods, NELEM(sSurfaceControlMethods));
1042
1043 jclass clazz = FindClassOrDie(env, "android/view/SurfaceControl$PhysicalDisplayInfo");
1044 gPhysicalDisplayInfoClassInfo.clazz = MakeGlobalRefOrDie(env, clazz);
1045 gPhysicalDisplayInfoClassInfo.ctor = GetMethodIDOrDie(env,
1046 gPhysicalDisplayInfoClassInfo.clazz, "<init>", "()V");
1047 gPhysicalDisplayInfoClassInfo.width = GetFieldIDOrDie(env, clazz, "width", "I");
1048 gPhysicalDisplayInfoClassInfo.height = GetFieldIDOrDie(env, clazz, "height", "I");
1049 gPhysicalDisplayInfoClassInfo.refreshRate = GetFieldIDOrDie(env, clazz, "refreshRate", "F");
1050 gPhysicalDisplayInfoClassInfo.density = GetFieldIDOrDie(env, clazz, "density", "F");
1051 gPhysicalDisplayInfoClassInfo.xDpi = GetFieldIDOrDie(env, clazz, "xDpi", "F");
1052 gPhysicalDisplayInfoClassInfo.yDpi = GetFieldIDOrDie(env, clazz, "yDpi", "F");
1053 gPhysicalDisplayInfoClassInfo.secure = GetFieldIDOrDie(env, clazz, "secure", "Z");
1054 gPhysicalDisplayInfoClassInfo.appVsyncOffsetNanos = GetFieldIDOrDie(env,
1055 clazz, "appVsyncOffsetNanos", "J");
1056 gPhysicalDisplayInfoClassInfo.presentationDeadlineNanos = GetFieldIDOrDie(env,
1057 clazz, "presentationDeadlineNanos", "J");
1058
1059 jclass rectClazz = FindClassOrDie(env, "android/graphics/Rect");
1060 gRectClassInfo.bottom = GetFieldIDOrDie(env, rectClazz, "bottom", "I");
1061 gRectClassInfo.left = GetFieldIDOrDie(env, rectClazz, "left", "I");
1062 gRectClassInfo.right = GetFieldIDOrDie(env, rectClazz, "right", "I");
1063 gRectClassInfo.top = GetFieldIDOrDie(env, rectClazz, "top", "I");
1064
1065 jclass frameStatsClazz = FindClassOrDie(env, "android/view/FrameStats");
1066 jfieldID undefined_time_nano_field = GetStaticFieldIDOrDie(env,
1067 frameStatsClazz, "UNDEFINED_TIME_NANO", "J");
1068 nsecs_t undefined_time_nano = env->GetStaticLongField(frameStatsClazz, undefined_time_nano_field);
1069
1070 jclass contFrameStatsClazz = FindClassOrDie(env, "android/view/WindowContentFrameStats");
1071 gWindowContentFrameStatsClassInfo.init = GetMethodIDOrDie(env,
1072 contFrameStatsClazz, "init", "(J[J[J[J)V");
1073 gWindowContentFrameStatsClassInfo.UNDEFINED_TIME_NANO = undefined_time_nano;
1074
1075 jclass animFrameStatsClazz = FindClassOrDie(env, "android/view/WindowAnimationFrameStats");
1076 gWindowAnimationFrameStatsClassInfo.init = GetMethodIDOrDie(env,
1077 animFrameStatsClazz, "init", "(J[J)V");
1078 gWindowAnimationFrameStatsClassInfo.UNDEFINED_TIME_NANO = undefined_time_nano;
1079
1080 jclass hdrCapabilitiesClazz = FindClassOrDie(env, "android/view/Display$HdrCapabilities");
1081 gHdrCapabilitiesClassInfo.clazz = MakeGlobalRefOrDie(env, hdrCapabilitiesClazz);
1082 gHdrCapabilitiesClassInfo.ctor = GetMethodIDOrDie(env, hdrCapabilitiesClazz, "<init>",
1083 "([IFFF)V");
1084
1085 jclass graphicsBufferClazz = FindClassOrDie(env, "android/graphics/GraphicBuffer");
1086 gGraphicBufferClassInfo.clazz = MakeGlobalRefOrDie(env, graphicsBufferClazz);
1087 gGraphicBufferClassInfo.builder = GetStaticMethodIDOrDie(env, graphicsBufferClazz,
1088 "createFromExisting", "(IIIIJZ)Landroid/graphics/GraphicBuffer;");
1089
1090 return err;
1091 }
1092
1093 };
1094