static void nativeDeferTransactionUntil(JNIEnv* env, jclass clazz, jlong nativeObject, jobject handleObject, jlong frameNumber) { auto ctrl = reinterpret_cast<SurfaceControl *>(nativeObject); sp<IBinder> handle = ibinderForJavaObject(env, handleObject); ctrl->deferTransactionUntil(handle, frameNumber); }
static void nativeSetDisplayLayerStack(JNIEnv* env, jclass clazz, jobject tokenObj, jint layerStack) { sp<IBinder> token(ibinderForJavaObject(env, tokenObj)); if (token == NULL) return; SurfaceComposerClient::setDisplayLayerStack(token, layerStack); }
static void nativeSetDisplayPowerMode(JNIEnv* env, jclass clazz, jobject tokenObj, jint mode) { sp<IBinder> token(ibinderForJavaObject(env, tokenObj)); if (token == NULL) return; ALOGD_IF_SLOW(100, "Excessive delay in setPowerMode()"); SurfaceComposerClient::setDisplayPowerMode(token, mode); }
static void android_os_Parcel_writeStrongBinder(JNIEnv* env, jclass clazz, jlong nativePtr, jobject object) { Parcel* parcel = reinterpret_cast<Parcel*>(nativePtr); if (parcel != NULL) { const status_t err = parcel->writeStrongBinder(ibinderForJavaObject(env, object)); if (err != NO_ERROR) { signalExceptionForError(env, clazz, err); } } }
static void nativeSetDisplayProjection(JNIEnv* env, jclass clazz, 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) { sp<IBinder> token(ibinderForJavaObject(env, tokenObj)); if (token == NULL) return; Rect layerStackRect(layerStackRect_left, layerStackRect_top, layerStackRect_right, layerStackRect_bottom); Rect displayRect(displayRect_left, displayRect_top, displayRect_right, displayRect_bottom); SurfaceComposerClient::setDisplayProjection(token, orientation, layerStackRect, displayRect); }
static void nativeSetDisplaySurface(JNIEnv* env, jclass clazz, jobject tokenObj, jlong nativeSurfaceObject) { sp<IBinder> token(ibinderForJavaObject(env, tokenObj)); if (token == NULL) return; sp<IGraphicBufferProducer> bufferProducer; sp<Surface> sur(reinterpret_cast<Surface *>(nativeSurfaceObject)); if (sur != NULL) { bufferProducer = sur->getIGraphicBufferProducer(); } SurfaceComposerClient::setDisplaySurface(token, bufferProducer); }
static jobject nativeGetHdrCapabilities(JNIEnv* env, jclass clazz, jobject tokenObject) { sp<IBinder> token(ibinderForJavaObject(env, tokenObject)); if (token == NULL) return NULL; HdrCapabilities capabilities; SurfaceComposerClient::getHdrCapabilities(token, &capabilities); const auto& types = capabilities.getSupportedHdrTypes(); auto typesArray = env->NewIntArray(types.size()); env->SetIntArrayRegion(typesArray, 0, types.size(), types.data()); return env->NewObject(gHdrCapabilitiesClassInfo.clazz, gHdrCapabilitiesClassInfo.ctor, typesArray, capabilities.getDesiredMaxLuminance(), capabilities.getDesiredMaxAverageLuminance(), capabilities.getDesiredMinLuminance()); }
static void native_init_memory(JNIEnv * env, jobject object, jobject memObj) { sp<IMemory> memory = interface_cast<IMemory>(ibinderForJavaObject(env, memObj)); if (memory == NULL) { jniThrowException(env, "java/lang/IllegalStateException", "Couldn't get native binder"); return; } CursorWindow * window = new CursorWindow(); if (!window) { jniThrowException(env, "java/lang/RuntimeException", "No memory for native window object"); return; } if (!window->setMemory(memory)) { jniThrowException(env, "java/lang/RuntimeException", "No memory in memObj"); delete window; return; } LOG_WINDOW("native_init_memory: numRows = %d, numColumns = %d, window = %p", window->getNumRows(), window->getNumColumns(), window); SET_WINDOW(env, object, window); }
static jobjectArray nativeGetDisplayConfigs(JNIEnv* env, jclass clazz, jobject tokenObj) { sp<IBinder> token(ibinderForJavaObject(env, tokenObj)); if (token == NULL) return NULL; Vector<DisplayInfo> configs; if (SurfaceComposerClient::getDisplayConfigs(token, &configs) != NO_ERROR || configs.size() == 0) { return NULL; } jobjectArray configArray = env->NewObjectArray(configs.size(), gPhysicalDisplayInfoClassInfo.clazz, NULL); for (size_t c = 0; c < configs.size(); ++c) { const DisplayInfo& info = configs[c]; jobject infoObj = env->NewObject(gPhysicalDisplayInfoClassInfo.clazz, gPhysicalDisplayInfoClassInfo.ctor); env->SetIntField(infoObj, gPhysicalDisplayInfoClassInfo.width, info.w); env->SetIntField(infoObj, gPhysicalDisplayInfoClassInfo.height, info.h); env->SetFloatField(infoObj, gPhysicalDisplayInfoClassInfo.refreshRate, info.fps); env->SetFloatField(infoObj, gPhysicalDisplayInfoClassInfo.density, info.density); env->SetFloatField(infoObj, gPhysicalDisplayInfoClassInfo.xDpi, info.xdpi); env->SetFloatField(infoObj, gPhysicalDisplayInfoClassInfo.yDpi, info.ydpi); env->SetBooleanField(infoObj, gPhysicalDisplayInfoClassInfo.secure, info.secure); env->SetLongField(infoObj, gPhysicalDisplayInfoClassInfo.appVsyncOffsetNanos, info.appVsyncOffset); env->SetLongField(infoObj, gPhysicalDisplayInfoClassInfo.presentationDeadlineNanos, info.presentationDeadline); env->SetIntField(infoObj, gPhysicalDisplayInfoClassInfo.colorTransform, info.colorTransform); env->SetObjectArrayElement(configArray, static_cast<jsize>(c), infoObj); env->DeleteLocalRef(infoObj); } return configArray; }
static void nativeScreenshot(JNIEnv* env, jclass clazz, jobject displayTokenObj, jobject surfaceObj, jobject sourceCropObj, jint width, jint height, jint minLayer, jint maxLayer, bool allLayers, bool useIdentityTransform) { sp<IBinder> displayToken = ibinderForJavaObject(env, displayTokenObj); if (displayToken != NULL) { sp<Surface> consumer = android_view_Surface_getSurface(env, surfaceObj); if (consumer != NULL) { int left = env->GetIntField(sourceCropObj, gRectClassInfo.left); int top = env->GetIntField(sourceCropObj, gRectClassInfo.top); int right = env->GetIntField(sourceCropObj, gRectClassInfo.right); int bottom = env->GetIntField(sourceCropObj, gRectClassInfo.bottom); Rect sourceCrop(left, top, right, bottom); if (allLayers) { minLayer = 0; maxLayer = -1; } ScreenshotClient::capture(displayToken, consumer->getIGraphicBufferProducer(), sourceCrop, width, height, uint32_t(minLayer), uint32_t(maxLayer), useIdentityTransform); } } }
static jboolean nativeSetActiveConfig(JNIEnv* env, jclass clazz, jobject tokenObj, jint id) { sp<IBinder> token(ibinderForJavaObject(env, tokenObj)); if (token == NULL) return JNI_FALSE; status_t err = SurfaceComposerClient::setActiveConfig(token, static_cast<int>(id)); return err == NO_ERROR ? JNI_TRUE : JNI_FALSE; }
static jint nativeGetActiveConfig(JNIEnv* env, jclass clazz, jobject tokenObj) { sp<IBinder> token(ibinderForJavaObject(env, tokenObj)); if (token == NULL) return -1; return static_cast<jint>(SurfaceComposerClient::getActiveConfig(token)); }
static void nativeSetDisplaySize(JNIEnv* env, jclass clazz, jobject tokenObj, jint width, jint height) { sp<IBinder> token(ibinderForJavaObject(env, tokenObj)); if (token == NULL) return; SurfaceComposerClient::setDisplaySize(token, width, height); }
static void nativeDestroyDisplay(JNIEnv* env, jclass clazz, jobject tokenObj) { sp<IBinder> token(ibinderForJavaObject(env, tokenObj)); if (token == NULL) return; SurfaceComposerClient::destroyDisplay(token); }
static jobject nativeScreenshotBitmap(JNIEnv* env, jclass clazz, jobject displayTokenObj, jobject sourceCropObj, jint width, jint height, jint minLayer, jint maxLayer, bool allLayers, bool useIdentityTransform, int rotation) { sp<IBinder> displayToken = ibinderForJavaObject(env, displayTokenObj); if (displayToken == NULL) { return NULL; } int left = env->GetIntField(sourceCropObj, gRectClassInfo.left); int top = env->GetIntField(sourceCropObj, gRectClassInfo.top); int right = env->GetIntField(sourceCropObj, gRectClassInfo.right); int bottom = env->GetIntField(sourceCropObj, gRectClassInfo.bottom); Rect sourceCrop(left, top, right, bottom); std::unique_ptr<ScreenshotClient> screenshot(new ScreenshotClient()); status_t res; if (allLayers) { minLayer = 0; maxLayer = -1; } res = screenshot->update(displayToken, sourceCrop, width, height, minLayer, maxLayer, useIdentityTransform, static_cast<uint32_t>(rotation)); if (res != NO_ERROR) { return NULL; } SkColorType colorType; SkAlphaType alphaType; switch (screenshot->getFormat()) { case PIXEL_FORMAT_RGBX_8888: { colorType = kRGBA_8888_SkColorType; alphaType = kOpaque_SkAlphaType; break; } case PIXEL_FORMAT_RGBA_8888: { colorType = kRGBA_8888_SkColorType; alphaType = kPremul_SkAlphaType; break; } case PIXEL_FORMAT_RGB_565: { colorType = kRGB_565_SkColorType; alphaType = kOpaque_SkAlphaType; break; } default: { return NULL; } } SkImageInfo screenshotInfo = SkImageInfo::Make(screenshot->getWidth(), screenshot->getHeight(), colorType, alphaType); const size_t rowBytes = screenshot->getStride() * android::bytesPerPixel(screenshot->getFormat()); if (!screenshotInfo.width() || !screenshotInfo.height()) { return NULL; } Bitmap* bitmap = new Bitmap( (void*) screenshot->getPixels(), (void*) screenshot.get(), DeleteScreenshot, screenshotInfo, rowBytes, nullptr); screenshot.release(); bitmap->peekAtPixelRef()->setImmutable(); return GraphicsJNI::createBitmap(env, bitmap, GraphicsJNI::kBitmapCreateFlag_Premultiplied, NULL); }