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