android_view_SurfaceControl.cpp revision 00101052b5bf99a29acea3525864ed64b709c16c
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 19#include <stdio.h> 20 21#include "jni.h" 22#include "JNIHelp.h" 23 24#include "android_os_Parcel.h" 25#include "android_util_Binder.h" 26#include "android/graphics/GraphicsJNI.h" 27#include "android/graphics/Region.h" 28 29#include <android_runtime/AndroidRuntime.h> 30#include <android_runtime/android_view_Surface.h> 31#include <android_runtime/android_view_SurfaceSession.h> 32 33#include <gui/Surface.h> 34#include <gui/SurfaceComposerClient.h> 35 36#include <ui/DisplayInfo.h> 37#include <ui/FrameStats.h> 38#include <ui/Rect.h> 39#include <ui/Region.h> 40 41#include <utils/Log.h> 42 43#include <ScopedUtfChars.h> 44 45// ---------------------------------------------------------------------------- 46 47namespace android { 48 49static const char* const OutOfResourcesException = 50 "android/view/Surface$OutOfResourcesException"; 51 52static struct { 53 jclass clazz; 54 jmethodID ctor; 55 jfieldID width; 56 jfieldID height; 57 jfieldID refreshRate; 58 jfieldID density; 59 jfieldID xDpi; 60 jfieldID yDpi; 61 jfieldID secure; 62} gPhysicalDisplayInfoClassInfo; 63 64// Implements SkMallocPixelRef::ReleaseProc, to delete the screenshot on unref. 65void DeleteScreenshot(void* addr, void* context) { 66 SkASSERT(addr == ((ScreenshotClient*) context)->getPixels()); 67 delete ((ScreenshotClient*) context); 68} 69 70static struct { 71 nsecs_t UNDEFINED_TIME_NANO; 72 jmethodID init; 73} gWindowContentFrameStatsClassInfo; 74 75static struct { 76 nsecs_t UNDEFINED_TIME_NANO; 77 jmethodID init; 78} gWindowAnimationFrameStatsClassInfo; 79 80// ---------------------------------------------------------------------------- 81 82static jlong nativeCreate(JNIEnv* env, jclass clazz, jobject sessionObj, 83 jstring nameStr, jint w, jint h, jint format, jint flags) { 84 ScopedUtfChars name(env, nameStr); 85 sp<SurfaceComposerClient> client(android_view_SurfaceSession_getClient(env, sessionObj)); 86 sp<SurfaceControl> surface = client->createSurface( 87 String8(name.c_str()), w, h, format, flags); 88 if (surface == NULL) { 89 jniThrowException(env, OutOfResourcesException, NULL); 90 return 0; 91 } 92 surface->incStrong((void *)nativeCreate); 93 return reinterpret_cast<jlong>(surface.get()); 94} 95 96static void nativeRelease(JNIEnv* env, jclass clazz, jlong nativeObject) { 97 sp<SurfaceControl> ctrl(reinterpret_cast<SurfaceControl *>(nativeObject)); 98 ctrl->decStrong((void *)nativeCreate); 99} 100 101static void nativeDestroy(JNIEnv* env, jclass clazz, jlong nativeObject) { 102 sp<SurfaceControl> ctrl(reinterpret_cast<SurfaceControl *>(nativeObject)); 103 ctrl->clear(); 104 ctrl->decStrong((void *)nativeCreate); 105} 106 107static jobject nativeScreenshotBitmap(JNIEnv* env, jclass clazz, jobject displayTokenObj, 108 jint width, jint height, jint minLayer, jint maxLayer, bool allLayers, 109 bool useIdentityTransform) { 110 sp<IBinder> displayToken = ibinderForJavaObject(env, displayTokenObj); 111 if (displayToken == NULL) { 112 return NULL; 113 } 114 115 ScreenshotClient* screenshot = new ScreenshotClient(); 116 status_t res; 117 if (width > 0 && height > 0) { 118 if (allLayers) { 119 res = screenshot->update(displayToken, width, height, useIdentityTransform); 120 } else { 121 res = screenshot->update(displayToken, width, height, minLayer, maxLayer, 122 useIdentityTransform); 123 } 124 } else { 125 res = screenshot->update(displayToken, useIdentityTransform); 126 } 127 if (res != NO_ERROR) { 128 delete screenshot; 129 return NULL; 130 } 131 132 SkImageInfo screenshotInfo; 133 screenshotInfo.fWidth = screenshot->getWidth(); 134 screenshotInfo.fHeight = screenshot->getHeight(); 135 136 switch (screenshot->getFormat()) { 137 case PIXEL_FORMAT_RGBX_8888: { 138 screenshotInfo.fColorType = kRGBA_8888_SkColorType; 139 screenshotInfo.fAlphaType = kIgnore_SkAlphaType; 140 break; 141 } 142 case PIXEL_FORMAT_RGBA_8888: { 143 screenshotInfo.fColorType = kRGBA_8888_SkColorType; 144 screenshotInfo.fAlphaType = kPremul_SkAlphaType; 145 break; 146 } 147 case PIXEL_FORMAT_RGB_565: { 148 screenshotInfo.fColorType = kRGB_565_SkColorType; 149 screenshotInfo.fAlphaType = kIgnore_SkAlphaType; 150 break; 151 } 152 default: { 153 delete screenshot; 154 return NULL; 155 } 156 } 157 158 const ssize_t rowBytes = 159 screenshot->getStride() * android::bytesPerPixel(screenshot->getFormat()); 160 161 SkBitmap* bitmap = new SkBitmap(); 162 bitmap->setConfig(screenshotInfo, (size_t)rowBytes); 163 if (screenshotInfo.fWidth > 0 && screenshotInfo.fHeight > 0) { 164 // takes ownership of ScreenshotClient 165 SkMallocPixelRef* pixels = SkMallocPixelRef::NewWithProc(screenshotInfo, 166 (size_t) rowBytes, NULL, (void*) screenshot->getPixels(), &DeleteScreenshot, 167 (void*) screenshot); 168 pixels->setImmutable(); 169 bitmap->setPixelRef(pixels)->unref(); 170 bitmap->lockPixels(); 171 } 172 173 return GraphicsJNI::createBitmap(env, bitmap, 174 GraphicsJNI::kBitmapCreateFlag_Premultiplied, NULL); 175} 176 177static void nativeScreenshot(JNIEnv* env, jclass clazz, 178 jobject displayTokenObj, jobject surfaceObj, 179 jint width, jint height, jint minLayer, jint maxLayer, bool allLayers, 180 bool useIdentityTransform) { 181 sp<IBinder> displayToken = ibinderForJavaObject(env, displayTokenObj); 182 if (displayToken != NULL) { 183 sp<Surface> consumer = android_view_Surface_getSurface(env, surfaceObj); 184 if (consumer != NULL) { 185 if (allLayers) { 186 minLayer = 0; 187 maxLayer = -1; 188 } 189 ScreenshotClient::capture( 190 displayToken, consumer->getIGraphicBufferProducer(), 191 width, height, uint32_t(minLayer), uint32_t(maxLayer), 192 useIdentityTransform); 193 } 194 } 195} 196 197static void nativeOpenTransaction(JNIEnv* env, jclass clazz) { 198 SurfaceComposerClient::openGlobalTransaction(); 199} 200 201static void nativeCloseTransaction(JNIEnv* env, jclass clazz) { 202 SurfaceComposerClient::closeGlobalTransaction(); 203} 204 205static void nativeSetAnimationTransaction(JNIEnv* env, jclass clazz) { 206 SurfaceComposerClient::setAnimationTransaction(); 207} 208 209static void nativeSetLayer(JNIEnv* env, jclass clazz, jlong nativeObject, jint zorder) { 210 SurfaceControl* const ctrl = reinterpret_cast<SurfaceControl *>(nativeObject); 211 status_t err = ctrl->setLayer(zorder); 212 if (err < 0 && err != NO_INIT) { 213 doThrowIAE(env); 214 } 215} 216 217static void nativeSetPosition(JNIEnv* env, jclass clazz, jlong nativeObject, jfloat x, jfloat y) { 218 SurfaceControl* const ctrl = reinterpret_cast<SurfaceControl *>(nativeObject); 219 status_t err = ctrl->setPosition(x, y); 220 if (err < 0 && err != NO_INIT) { 221 doThrowIAE(env); 222 } 223} 224 225static void nativeSetSize(JNIEnv* env, jclass clazz, jlong nativeObject, jint w, jint h) { 226 SurfaceControl* const ctrl = reinterpret_cast<SurfaceControl *>(nativeObject); 227 status_t err = ctrl->setSize(w, h); 228 if (err < 0 && err != NO_INIT) { 229 doThrowIAE(env); 230 } 231} 232 233static void nativeSetFlags(JNIEnv* env, jclass clazz, jlong nativeObject, jint flags, jint mask) { 234 SurfaceControl* const ctrl = reinterpret_cast<SurfaceControl *>(nativeObject); 235 status_t err = ctrl->setFlags(flags, mask); 236 if (err < 0 && err != NO_INIT) { 237 doThrowIAE(env); 238 } 239} 240 241static void nativeSetTransparentRegionHint(JNIEnv* env, jclass clazz, jlong nativeObject, jobject regionObj) { 242 SurfaceControl* const ctrl = reinterpret_cast<SurfaceControl *>(nativeObject); 243 SkRegion* region = android_graphics_Region_getSkRegion(env, regionObj); 244 if (!region) { 245 doThrowIAE(env); 246 return; 247 } 248 249 const SkIRect& b(region->getBounds()); 250 Region reg(Rect(b.fLeft, b.fTop, b.fRight, b.fBottom)); 251 if (region->isComplex()) { 252 SkRegion::Iterator it(*region); 253 while (!it.done()) { 254 const SkIRect& r(it.rect()); 255 reg.addRectUnchecked(r.fLeft, r.fTop, r.fRight, r.fBottom); 256 it.next(); 257 } 258 } 259 260 status_t err = ctrl->setTransparentRegionHint(reg); 261 if (err < 0 && err != NO_INIT) { 262 doThrowIAE(env); 263 } 264} 265 266static void nativeSetAlpha(JNIEnv* env, jclass clazz, jlong nativeObject, jfloat alpha) { 267 SurfaceControl* const ctrl = reinterpret_cast<SurfaceControl *>(nativeObject); 268 status_t err = ctrl->setAlpha(alpha); 269 if (err < 0 && err != NO_INIT) { 270 doThrowIAE(env); 271 } 272} 273 274static void nativeSetMatrix(JNIEnv* env, jclass clazz, jlong nativeObject, 275 jfloat dsdx, jfloat dtdx, jfloat dsdy, jfloat dtdy) { 276 SurfaceControl* const ctrl = reinterpret_cast<SurfaceControl *>(nativeObject); 277 status_t err = ctrl->setMatrix(dsdx, dtdx, dsdy, dtdy); 278 if (err < 0 && err != NO_INIT) { 279 doThrowIAE(env); 280 } 281} 282 283static void nativeSetWindowCrop(JNIEnv* env, jclass clazz, jlong nativeObject, 284 jint l, jint t, jint r, jint b) { 285 SurfaceControl* const ctrl = reinterpret_cast<SurfaceControl *>(nativeObject); 286 Rect crop(l, t, r, b); 287 status_t err = ctrl->setCrop(crop); 288 if (err < 0 && err != NO_INIT) { 289 doThrowIAE(env); 290 } 291} 292 293static void nativeSetLayerStack(JNIEnv* env, jclass clazz, jlong nativeObject, jint layerStack) { 294 SurfaceControl* const ctrl = reinterpret_cast<SurfaceControl *>(nativeObject); 295 status_t err = ctrl->setLayerStack(layerStack); 296 if (err < 0 && err != NO_INIT) { 297 doThrowIAE(env); 298 } 299} 300 301static jobject nativeGetBuiltInDisplay(JNIEnv* env, jclass clazz, jint id) { 302 sp<IBinder> token(SurfaceComposerClient::getBuiltInDisplay(id)); 303 return javaObjectForIBinder(env, token); 304} 305 306static jobject nativeCreateDisplay(JNIEnv* env, jclass clazz, jstring nameObj, 307 jboolean secure) { 308 ScopedUtfChars name(env, nameObj); 309 sp<IBinder> token(SurfaceComposerClient::createDisplay( 310 String8(name.c_str()), bool(secure))); 311 return javaObjectForIBinder(env, token); 312} 313 314static void nativeDestroyDisplay(JNIEnv* env, jclass clazz, jobject tokenObj) { 315 sp<IBinder> token(ibinderForJavaObject(env, tokenObj)); 316 if (token == NULL) return; 317 SurfaceComposerClient::destroyDisplay(token); 318} 319 320static void nativeSetDisplaySurface(JNIEnv* env, jclass clazz, 321 jobject tokenObj, jlong nativeSurfaceObject) { 322 sp<IBinder> token(ibinderForJavaObject(env, tokenObj)); 323 if (token == NULL) return; 324 sp<IGraphicBufferProducer> bufferProducer; 325 sp<Surface> sur(reinterpret_cast<Surface *>(nativeSurfaceObject)); 326 if (sur != NULL) { 327 bufferProducer = sur->getIGraphicBufferProducer(); 328 } 329 SurfaceComposerClient::setDisplaySurface(token, bufferProducer); 330} 331 332static void nativeSetDisplayLayerStack(JNIEnv* env, jclass clazz, 333 jobject tokenObj, jint layerStack) { 334 sp<IBinder> token(ibinderForJavaObject(env, tokenObj)); 335 if (token == NULL) return; 336 337 SurfaceComposerClient::setDisplayLayerStack(token, layerStack); 338} 339 340static void nativeSetDisplayProjection(JNIEnv* env, jclass clazz, 341 jobject tokenObj, jint orientation, 342 jint layerStackRect_left, jint layerStackRect_top, jint layerStackRect_right, jint layerStackRect_bottom, 343 jint displayRect_left, jint displayRect_top, jint displayRect_right, jint displayRect_bottom) { 344 sp<IBinder> token(ibinderForJavaObject(env, tokenObj)); 345 if (token == NULL) return; 346 Rect layerStackRect(layerStackRect_left, layerStackRect_top, layerStackRect_right, layerStackRect_bottom); 347 Rect displayRect(displayRect_left, displayRect_top, displayRect_right, displayRect_bottom); 348 SurfaceComposerClient::setDisplayProjection(token, orientation, layerStackRect, displayRect); 349} 350 351static jobjectArray nativeGetDisplayConfigs(JNIEnv* env, jclass clazz, 352 jobject tokenObj) { 353 sp<IBinder> token(ibinderForJavaObject(env, tokenObj)); 354 if (token == NULL) return NULL; 355 356 Vector<DisplayInfo> configs; 357 if (SurfaceComposerClient::getDisplayConfigs(token, &configs) != NO_ERROR || 358 configs.size() == 0) { 359 return NULL; 360 } 361 362 jobjectArray configArray = env->NewObjectArray(configs.size(), 363 gPhysicalDisplayInfoClassInfo.clazz, NULL); 364 365 for (size_t c = 0; c < configs.size(); ++c) { 366 const DisplayInfo& info = configs[c]; 367 jobject infoObj = env->NewObject(gPhysicalDisplayInfoClassInfo.clazz, 368 gPhysicalDisplayInfoClassInfo.ctor); 369 env->SetIntField(infoObj, gPhysicalDisplayInfoClassInfo.width, info.w); 370 env->SetIntField(infoObj, gPhysicalDisplayInfoClassInfo.height, info.h); 371 env->SetFloatField(infoObj, gPhysicalDisplayInfoClassInfo.refreshRate, info.fps); 372 env->SetFloatField(infoObj, gPhysicalDisplayInfoClassInfo.density, info.density); 373 env->SetFloatField(infoObj, gPhysicalDisplayInfoClassInfo.xDpi, info.xdpi); 374 env->SetFloatField(infoObj, gPhysicalDisplayInfoClassInfo.yDpi, info.ydpi); 375 env->SetBooleanField(infoObj, gPhysicalDisplayInfoClassInfo.secure, info.secure); 376 env->SetObjectArrayElement(configArray, static_cast<jsize>(c), infoObj); 377 env->DeleteLocalRef(infoObj); 378 } 379 380 return configArray; 381} 382 383static jint nativeGetActiveConfig(JNIEnv* env, jclass clazz, jobject tokenObj) { 384 sp<IBinder> token(ibinderForJavaObject(env, tokenObj)); 385 if (token == NULL) return -1; 386 return static_cast<jint>(SurfaceComposerClient::getActiveConfig(token)); 387} 388 389static jboolean nativeSetActiveConfig(JNIEnv* env, jclass clazz, jobject tokenObj, jint id) { 390 sp<IBinder> token(ibinderForJavaObject(env, tokenObj)); 391 if (token == NULL) return JNI_FALSE; 392 status_t err = SurfaceComposerClient::setActiveConfig(token, static_cast<int>(id)); 393 return err == NO_ERROR ? JNI_TRUE : JNI_FALSE; 394} 395 396static void nativeBlankDisplay(JNIEnv* env, jclass clazz, jobject tokenObj) { 397 sp<IBinder> token(ibinderForJavaObject(env, tokenObj)); 398 if (token == NULL) return; 399 400 ALOGD_IF_SLOW(100, "Excessive delay in blankDisplay() while turning screen off"); 401 SurfaceComposerClient::blankDisplay(token); 402} 403 404static void nativeUnblankDisplay(JNIEnv* env, jclass clazz, jobject tokenObj) { 405 sp<IBinder> token(ibinderForJavaObject(env, tokenObj)); 406 if (token == NULL) return; 407 408 ALOGD_IF_SLOW(100, "Excessive delay in unblankDisplay() while turning screen on"); 409 SurfaceComposerClient::unblankDisplay(token); 410} 411 412static jboolean nativeClearContentFrameStats(JNIEnv* env, jclass clazz, jlong nativeObject) { 413 SurfaceControl* const ctrl = reinterpret_cast<SurfaceControl *>(nativeObject); 414 status_t err = ctrl->clearLayerFrameStats(); 415 416 if (err < 0 && err != NO_INIT) { 417 doThrowIAE(env); 418 } 419 420 // The other end is not ready, just report we failed. 421 if (err == NO_INIT) { 422 return JNI_FALSE; 423 } 424 425 return JNI_TRUE; 426} 427 428static jboolean nativeGetContentFrameStats(JNIEnv* env, jclass clazz, jlong nativeObject, 429 jobject outStats) { 430 FrameStats stats; 431 432 SurfaceControl* const ctrl = reinterpret_cast<SurfaceControl *>(nativeObject); 433 status_t err = ctrl->getLayerFrameStats(&stats); 434 if (err < 0 && err != NO_INIT) { 435 doThrowIAE(env); 436 } 437 438 // The other end is not ready, fine just return empty stats. 439 if (err == NO_INIT) { 440 return JNI_FALSE; 441 } 442 443 jlong refreshPeriodNano = static_cast<jlong>(stats.refreshPeriodNano); 444 size_t frameCount = stats.desiredPresentTimesNano.size(); 445 446 jlongArray postedTimesNanoDst = env->NewLongArray(frameCount); 447 if (postedTimesNanoDst == NULL) { 448 return JNI_FALSE; 449 } 450 451 jlongArray presentedTimesNanoDst = env->NewLongArray(frameCount); 452 if (presentedTimesNanoDst == NULL) { 453 return JNI_FALSE; 454 } 455 456 jlongArray readyTimesNanoDst = env->NewLongArray(frameCount); 457 if (readyTimesNanoDst == NULL) { 458 return JNI_FALSE; 459 } 460 461 nsecs_t postedTimesNanoSrc[frameCount]; 462 nsecs_t presentedTimesNanoSrc[frameCount]; 463 nsecs_t readyTimesNanoSrc[frameCount]; 464 465 for (size_t i = 0; i < frameCount; i++) { 466 nsecs_t postedTimeNano = stats.desiredPresentTimesNano[i]; 467 if (postedTimeNano == INT64_MAX) { 468 postedTimeNano = gWindowContentFrameStatsClassInfo.UNDEFINED_TIME_NANO; 469 } 470 postedTimesNanoSrc[i] = postedTimeNano; 471 472 nsecs_t presentedTimeNano = stats.actualPresentTimesNano[i]; 473 if (presentedTimeNano == INT64_MAX) { 474 presentedTimeNano = gWindowContentFrameStatsClassInfo.UNDEFINED_TIME_NANO; 475 } 476 presentedTimesNanoSrc[i] = presentedTimeNano; 477 478 nsecs_t readyTimeNano = stats.frameReadyTimesNano[i]; 479 if (readyTimeNano == INT64_MAX) { 480 readyTimeNano = gWindowContentFrameStatsClassInfo.UNDEFINED_TIME_NANO; 481 } 482 readyTimesNanoSrc[i] = readyTimeNano; 483 } 484 485 env->SetLongArrayRegion(postedTimesNanoDst, 0, frameCount, postedTimesNanoSrc); 486 env->SetLongArrayRegion(presentedTimesNanoDst, 0, frameCount, presentedTimesNanoSrc); 487 env->SetLongArrayRegion(readyTimesNanoDst, 0, frameCount, readyTimesNanoSrc); 488 489 env->CallVoidMethod(outStats, gWindowContentFrameStatsClassInfo.init, refreshPeriodNano, 490 postedTimesNanoDst, presentedTimesNanoDst, readyTimesNanoDst); 491 492 if (env->ExceptionCheck()) { 493 return JNI_FALSE; 494 } 495 496 return JNI_TRUE; 497} 498 499static jboolean nativeClearAnimationFrameStats(JNIEnv* env, jclass clazz) { 500 status_t err = SurfaceComposerClient::clearAnimationFrameStats(); 501 502 if (err < 0 && err != NO_INIT) { 503 doThrowIAE(env); 504 } 505 506 // The other end is not ready, just report we failed. 507 if (err == NO_INIT) { 508 return JNI_FALSE; 509 } 510 511 return JNI_TRUE; 512} 513 514static jboolean nativeGetAnimationFrameStats(JNIEnv* env, jclass clazz, jobject outStats) { 515 FrameStats stats; 516 517 status_t err = SurfaceComposerClient::getAnimationFrameStats(&stats); 518 if (err < 0 && err != NO_INIT) { 519 doThrowIAE(env); 520 } 521 522 // The other end is not ready, fine just return empty stats. 523 if (err == NO_INIT) { 524 return JNI_FALSE; 525 } 526 527 jlong refreshPeriodNano = static_cast<jlong>(stats.refreshPeriodNano); 528 size_t frameCount = stats.desiredPresentTimesNano.size(); 529 530 jlongArray presentedTimesNanoDst = env->NewLongArray(frameCount); 531 if (presentedTimesNanoDst == NULL) { 532 return JNI_FALSE; 533 } 534 535 nsecs_t presentedTimesNanoSrc[frameCount]; 536 537 for (size_t i = 0; i < frameCount; i++) { 538 nsecs_t presentedTimeNano = stats.actualPresentTimesNano[i]; 539 if (presentedTimeNano == INT64_MAX) { 540 presentedTimeNano = gWindowContentFrameStatsClassInfo.UNDEFINED_TIME_NANO; 541 } 542 presentedTimesNanoSrc[i] = presentedTimeNano; 543 } 544 545 env->SetLongArrayRegion(presentedTimesNanoDst, 0, frameCount, presentedTimesNanoSrc); 546 547 env->CallVoidMethod(outStats, gWindowAnimationFrameStatsClassInfo.init, refreshPeriodNano, 548 presentedTimesNanoDst); 549 550 if (env->ExceptionCheck()) { 551 return JNI_FALSE; 552 } 553 554 return JNI_TRUE; 555} 556 557// ---------------------------------------------------------------------------- 558 559static JNINativeMethod sSurfaceControlMethods[] = { 560 {"nativeCreate", "(Landroid/view/SurfaceSession;Ljava/lang/String;IIII)J", 561 (void*)nativeCreate }, 562 {"nativeRelease", "(J)V", 563 (void*)nativeRelease }, 564 {"nativeDestroy", "(J)V", 565 (void*)nativeDestroy }, 566 {"nativeScreenshot", "(Landroid/os/IBinder;IIIIZZ)Landroid/graphics/Bitmap;", 567 (void*)nativeScreenshotBitmap }, 568 {"nativeScreenshot", "(Landroid/os/IBinder;Landroid/view/Surface;IIIIZZ)V", 569 (void*)nativeScreenshot }, 570 {"nativeOpenTransaction", "()V", 571 (void*)nativeOpenTransaction }, 572 {"nativeCloseTransaction", "()V", 573 (void*)nativeCloseTransaction }, 574 {"nativeSetAnimationTransaction", "()V", 575 (void*)nativeSetAnimationTransaction }, 576 {"nativeSetLayer", "(JI)V", 577 (void*)nativeSetLayer }, 578 {"nativeSetPosition", "(JFF)V", 579 (void*)nativeSetPosition }, 580 {"nativeSetSize", "(JII)V", 581 (void*)nativeSetSize }, 582 {"nativeSetTransparentRegionHint", "(JLandroid/graphics/Region;)V", 583 (void*)nativeSetTransparentRegionHint }, 584 {"nativeSetAlpha", "(JF)V", 585 (void*)nativeSetAlpha }, 586 {"nativeSetMatrix", "(JFFFF)V", 587 (void*)nativeSetMatrix }, 588 {"nativeSetFlags", "(JII)V", 589 (void*)nativeSetFlags }, 590 {"nativeSetWindowCrop", "(JIIII)V", 591 (void*)nativeSetWindowCrop }, 592 {"nativeSetLayerStack", "(JI)V", 593 (void*)nativeSetLayerStack }, 594 {"nativeGetBuiltInDisplay", "(I)Landroid/os/IBinder;", 595 (void*)nativeGetBuiltInDisplay }, 596 {"nativeCreateDisplay", "(Ljava/lang/String;Z)Landroid/os/IBinder;", 597 (void*)nativeCreateDisplay }, 598 {"nativeDestroyDisplay", "(Landroid/os/IBinder;)V", 599 (void*)nativeDestroyDisplay }, 600 {"nativeSetDisplaySurface", "(Landroid/os/IBinder;J)V", 601 (void*)nativeSetDisplaySurface }, 602 {"nativeSetDisplayLayerStack", "(Landroid/os/IBinder;I)V", 603 (void*)nativeSetDisplayLayerStack }, 604 {"nativeSetDisplayProjection", "(Landroid/os/IBinder;IIIIIIIII)V", 605 (void*)nativeSetDisplayProjection }, 606 {"nativeGetDisplayConfigs", "(Landroid/os/IBinder;)[Landroid/view/SurfaceControl$PhysicalDisplayInfo;", 607 (void*)nativeGetDisplayConfigs }, 608 {"nativeGetActiveConfig", "(Landroid/os/IBinder;)I", 609 (void*)nativeGetActiveConfig }, 610 {"nativeSetActiveConfig", "(Landroid/os/IBinder;I)Z", 611 (void*)nativeSetActiveConfig }, 612 {"nativeBlankDisplay", "(Landroid/os/IBinder;)V", 613 (void*)nativeBlankDisplay }, 614 {"nativeUnblankDisplay", "(Landroid/os/IBinder;)V", 615 (void*)nativeUnblankDisplay }, 616 {"nativeClearContentFrameStats", "(J)Z", 617 (void*)nativeClearContentFrameStats }, 618 {"nativeGetContentFrameStats", "(JLandroid/view/WindowContentFrameStats;)Z", 619 (void*)nativeGetContentFrameStats }, 620 {"nativeClearAnimationFrameStats", "()Z", 621 (void*)nativeClearAnimationFrameStats }, 622 {"nativeGetAnimationFrameStats", "(Landroid/view/WindowAnimationFrameStats;)Z", 623 (void*)nativeGetAnimationFrameStats }, 624}; 625 626int register_android_view_SurfaceControl(JNIEnv* env) 627{ 628 int err = AndroidRuntime::registerNativeMethods(env, "android/view/SurfaceControl", 629 sSurfaceControlMethods, NELEM(sSurfaceControlMethods)); 630 631 jclass clazz = env->FindClass("android/view/SurfaceControl$PhysicalDisplayInfo"); 632 gPhysicalDisplayInfoClassInfo.clazz = static_cast<jclass>(env->NewGlobalRef(clazz)); 633 gPhysicalDisplayInfoClassInfo.ctor = env->GetMethodID(gPhysicalDisplayInfoClassInfo.clazz, 634 "<init>", "()V"); 635 gPhysicalDisplayInfoClassInfo.width = env->GetFieldID(clazz, "width", "I"); 636 gPhysicalDisplayInfoClassInfo.height = env->GetFieldID(clazz, "height", "I"); 637 gPhysicalDisplayInfoClassInfo.refreshRate = env->GetFieldID(clazz, "refreshRate", "F"); 638 gPhysicalDisplayInfoClassInfo.density = env->GetFieldID(clazz, "density", "F"); 639 gPhysicalDisplayInfoClassInfo.xDpi = env->GetFieldID(clazz, "xDpi", "F"); 640 gPhysicalDisplayInfoClassInfo.yDpi = env->GetFieldID(clazz, "yDpi", "F"); 641 gPhysicalDisplayInfoClassInfo.secure = env->GetFieldID(clazz, "secure", "Z"); 642 643 jclass frameStatsClazz = env->FindClass("android/view/FrameStats"); 644 jfieldID undefined_time_nano_field = env->GetStaticFieldID(frameStatsClazz, "UNDEFINED_TIME_NANO", "J"); 645 nsecs_t undefined_time_nano = env->GetStaticLongField(frameStatsClazz, undefined_time_nano_field); 646 647 jclass contFrameStatsClazz = env->FindClass("android/view/WindowContentFrameStats"); 648 gWindowContentFrameStatsClassInfo.init = env->GetMethodID(contFrameStatsClazz, "init", "(J[J[J[J)V"); 649 gWindowContentFrameStatsClassInfo.UNDEFINED_TIME_NANO = undefined_time_nano; 650 651 jclass animFrameStatsClazz = env->FindClass("android/view/WindowAnimationFrameStats"); 652 gWindowAnimationFrameStatsClassInfo.init = env->GetMethodID(animFrameStatsClazz, "init", "(J[J)V"); 653 gWindowAnimationFrameStatsClassInfo.UNDEFINED_TIME_NANO = undefined_time_nano; 654 655 return err; 656} 657 658}; 659