未验证 提交 e5845af4 编写于 作者: E Emmanuel Garcia 提交者: GitHub

Put JNI functions under an interface (#18903)

上级 efd1452a
......@@ -782,13 +782,15 @@ FILE: ../../../flutter/shell/platform/android/io/flutter/view/FlutterRunArgument
FILE: ../../../flutter/shell/platform/android/io/flutter/view/FlutterView.java
FILE: ../../../flutter/shell/platform/android/io/flutter/view/TextureRegistry.java
FILE: ../../../flutter/shell/platform/android/io/flutter/view/VsyncWaiter.java
FILE: ../../../flutter/shell/platform/android/jni/platform_view_android_jni.cc
FILE: ../../../flutter/shell/platform/android/jni/platform_view_android_jni.h
FILE: ../../../flutter/shell/platform/android/library_loader.cc
FILE: ../../../flutter/shell/platform/android/platform_message_response_android.cc
FILE: ../../../flutter/shell/platform/android/platform_message_response_android.h
FILE: ../../../flutter/shell/platform/android/platform_view_android.cc
FILE: ../../../flutter/shell/platform/android/platform_view_android.h
FILE: ../../../flutter/shell/platform/android/platform_view_android_jni.cc
FILE: ../../../flutter/shell/platform/android/platform_view_android_jni.h
FILE: ../../../flutter/shell/platform/android/platform_view_android_jni_impl.cc
FILE: ../../../flutter/shell/platform/android/platform_view_android_jni_impl.h
FILE: ../../../flutter/shell/platform/android/robolectric.properties
FILE: ../../../flutter/shell/platform/android/vsync_waiter_android.cc
FILE: ../../../flutter/shell/platform/android/vsync_waiter_android.h
......
......@@ -50,8 +50,8 @@ shared_library("flutter_shell_native") {
"platform_message_response_android.h",
"platform_view_android.cc",
"platform_view_android.h",
"platform_view_android_jni.cc",
"platform_view_android_jni.h",
"platform_view_android_jni_impl.cc",
"platform_view_android_jni_impl.h",
"vsync_waiter_android.cc",
"vsync_waiter_android.h",
]
......@@ -68,6 +68,7 @@ shared_library("flutter_shell_native") {
"//flutter/runtime:libdart",
"//flutter/shell/common",
"//flutter/shell/platform/android/external_view_embedder",
"//flutter/shell/platform/android/jni",
"//third_party/skia",
]
......
......@@ -6,15 +6,18 @@
#include <GLES/glext.h>
#include "flutter/shell/platform/android/platform_view_android_jni.h"
#include "third_party/skia/include/gpu/GrBackendSurface.h"
namespace flutter {
AndroidExternalTextureGL::AndroidExternalTextureGL(
int64_t id,
const fml::jni::JavaObjectWeakGlobalRef& surfaceTexture)
: Texture(id), surface_texture_(surfaceTexture), transform(SkMatrix::I()) {}
const fml::jni::JavaObjectWeakGlobalRef& surface_texture,
std::shared_ptr<PlatformViewAndroidJNI> jni_facade)
: Texture(id),
jni_facade_(jni_facade),
surface_texture_(surface_texture),
transform(SkMatrix::I()) {}
AndroidExternalTextureGL::~AndroidExternalTextureGL() {
if (state_ == AttachmentState::attached) {
......@@ -68,36 +71,8 @@ void AndroidExternalTextureGL::Paint(SkCanvas& canvas,
}
}
// The bounds we set for the canvas are post composition.
// To fill the canvas we need to ensure that the transformation matrix
// on the `SurfaceTexture` will be scaled to fill. We rescale and preseve
// the scaled aspect ratio.
SkSize ScaleToFill(float scaleX, float scaleY) {
const double epsilon = std::numeric_limits<double>::epsilon();
// scaleY is negative.
const double minScale = fmin(scaleX, fabs(scaleY));
const double rescale = 1.0f / (minScale + epsilon);
return SkSize::Make(scaleX * rescale, scaleY * rescale);
}
void AndroidExternalTextureGL::UpdateTransform() {
JNIEnv* env = fml::jni::AttachCurrentThread();
fml::jni::ScopedJavaLocalRef<jobject> surfaceTexture =
surface_texture_.get(env);
fml::jni::ScopedJavaLocalRef<jfloatArray> transformMatrix(
env, env->NewFloatArray(16));
SurfaceTextureGetTransformMatrix(env, surfaceTexture.obj(),
transformMatrix.obj());
float* m = env->GetFloatArrayElements(transformMatrix.obj(), nullptr);
float scaleX = m[0], scaleY = m[5];
const SkSize scaled = ScaleToFill(scaleX, scaleY);
SkScalar matrix3[] = {
scaled.fWidth, m[1], m[2], //
m[4], scaled.fHeight, m[6], //
m[8], m[9], m[10], //
};
env->ReleaseFloatArrayElements(transformMatrix.obj(), m, JNI_ABORT);
transform.set9(matrix3);
jni_facade_->SurfaceTextureGetTransformMatrix(surface_texture_, transform);
}
void AndroidExternalTextureGL::OnGrContextDestroyed() {
......@@ -108,31 +83,16 @@ void AndroidExternalTextureGL::OnGrContextDestroyed() {
}
void AndroidExternalTextureGL::Attach(jint textureName) {
JNIEnv* env = fml::jni::AttachCurrentThread();
fml::jni::ScopedJavaLocalRef<jobject> surfaceTexture =
surface_texture_.get(env);
if (!surfaceTexture.is_null()) {
SurfaceTextureAttachToGLContext(env, surfaceTexture.obj(), textureName);
}
jni_facade_->SurfaceTextureAttachToGLContext(surface_texture_, textureName);
}
void AndroidExternalTextureGL::Update() {
JNIEnv* env = fml::jni::AttachCurrentThread();
fml::jni::ScopedJavaLocalRef<jobject> surfaceTexture =
surface_texture_.get(env);
if (!surfaceTexture.is_null()) {
SurfaceTextureUpdateTexImage(env, surfaceTexture.obj());
UpdateTransform();
}
jni_facade_->SurfaceTextureUpdateTexImage(surface_texture_);
UpdateTransform();
}
void AndroidExternalTextureGL::Detach() {
JNIEnv* env = fml::jni::AttachCurrentThread();
fml::jni::ScopedJavaLocalRef<jobject> surfaceTexture =
surface_texture_.get(env);
if (!surfaceTexture.is_null()) {
SurfaceTextureDetachFromGLContext(env, surfaceTexture.obj());
}
jni_facade_->SurfaceTextureDetachFromGLContext(surface_texture_);
}
void AndroidExternalTextureGL::OnTextureUnregistered() {}
......
......@@ -8,6 +8,7 @@
#include <GLES/gl.h>
#include "flutter/flow/texture.h"
#include "flutter/fml/platform/android/jni_weak_ref.h"
#include "flutter/shell/platform/android/platform_view_android_jni_impl.h"
namespace flutter {
......@@ -15,7 +16,8 @@ class AndroidExternalTextureGL : public flutter::Texture {
public:
AndroidExternalTextureGL(
int64_t id,
const fml::jni::JavaObjectWeakGlobalRef& surfaceTexture);
const fml::jni::JavaObjectWeakGlobalRef& surface_texture,
std::shared_ptr<PlatformViewAndroidJNI> jni_facade);
~AndroidExternalTextureGL() override;
......@@ -43,6 +45,8 @@ class AndroidExternalTextureGL : public flutter::Texture {
enum class AttachmentState { uninitialized, attached, detached };
std::shared_ptr<PlatformViewAndroidJNI> jni_facade_;
fml::jni::JavaObjectWeakGlobalRef surface_texture_;
AttachmentState state_ = AttachmentState::uninitialized;
......
......@@ -29,9 +29,9 @@ static WindowData GetDefaultWindowData() {
AndroidShellHolder::AndroidShellHolder(
flutter::Settings settings,
fml::jni::JavaObjectWeakGlobalRef java_object,
std::shared_ptr<PlatformViewAndroidJNI> jni_facade,
bool is_background_view)
: settings_(std::move(settings)), java_object_(java_object) {
: settings_(std::move(settings)), jni_facade_(jni_facade) {
static size_t shell_count = 1;
auto thread_label = std::to_string(shell_count++);
......@@ -56,20 +56,19 @@ AndroidShellHolder::AndroidShellHolder(
fml::WeakPtr<PlatformViewAndroid> weak_platform_view;
Shell::CreateCallback<PlatformView> on_create_platform_view =
[is_background_view, java_object, &weak_platform_view](Shell& shell) {
[is_background_view, &jni_facade, &weak_platform_view](Shell& shell) {
std::unique_ptr<PlatformViewAndroid> platform_view_android;
if (is_background_view) {
platform_view_android = std::make_unique<PlatformViewAndroid>(
shell, // delegate
shell.GetTaskRunners(), // task runners
java_object // java object handle for JNI interop
jni_facade // JNI interop
);
} else {
platform_view_android = std::make_unique<PlatformViewAndroid>(
shell, // delegate
shell.GetTaskRunners(), // task runners
java_object, // java object handle for JNI interop
jni_facade, // JNI interop
shell.GetSettings()
.enable_software_rendering // use software rendering
);
......
......@@ -8,13 +8,13 @@
#include <memory>
#include "flutter/fml/macros.h"
#include "flutter/fml/platform/android/jni_weak_ref.h"
#include "flutter/fml/unique_fd.h"
#include "flutter/lib/ui/window/viewport_metrics.h"
#include "flutter/runtime/window_data.h"
#include "flutter/shell/common/run_configuration.h"
#include "flutter/shell/common/shell.h"
#include "flutter/shell/common/thread_host.h"
#include "flutter/shell/platform/android/jni/platform_view_android_jni.h"
#include "flutter/shell/platform/android/platform_view_android.h"
namespace flutter {
......@@ -22,7 +22,7 @@ namespace flutter {
class AndroidShellHolder {
public:
AndroidShellHolder(flutter::Settings settings,
fml::jni::JavaObjectWeakGlobalRef java_object,
std::shared_ptr<PlatformViewAndroidJNI> jni_facade,
bool is_background_view);
~AndroidShellHolder();
......@@ -44,7 +44,7 @@ class AndroidShellHolder {
private:
const flutter::Settings settings_;
const fml::jni::JavaObjectWeakGlobalRef java_object_;
const std::shared_ptr<PlatformViewAndroidJNI> jni_facade_;
fml::WeakPtr<PlatformViewAndroid> platform_view_;
ThreadHost thread_host_;
std::unique_ptr<Shell> shell_;
......
......@@ -15,18 +15,19 @@
namespace flutter {
std::unique_ptr<AndroidSurface> AndroidSurface::Create(
std::shared_ptr<AndroidContext> android_context) {
std::shared_ptr<AndroidContext> android_context,
std::shared_ptr<PlatformViewAndroidJNI> jni_facade) {
std::unique_ptr<AndroidSurface> surface;
switch (android_context->RenderingApi()) {
case AndroidRenderingAPI::kSoftware:
surface = std::make_unique<AndroidSurfaceSoftware>();
surface = std::make_unique<AndroidSurfaceSoftware>(jni_facade);
break;
case AndroidRenderingAPI::kOpenGLES:
surface = std::make_unique<AndroidSurfaceGL>(android_context);
surface = std::make_unique<AndroidSurfaceGL>(android_context, jni_facade);
break;
case AndroidRenderingAPI::kVulkan:
#if SHELL_ENABLE_VULKAN
surface = std::make_unique<AndroidSurfaceVulkan>();
surface = std::make_unique<AndroidSurfaceVulkan>(jni_facade);
#endif // SHELL_ENABLE_VULKAN
break;
}
......
......@@ -14,6 +14,7 @@
#include "flutter/shell/common/platform_view.h"
#include "flutter/shell/platform/android/android_context.h"
#include "flutter/shell/platform/android/android_native_window.h"
#include "flutter/shell/platform/android/jni/platform_view_android_jni.h"
#include "third_party/skia/include/core/SkSize.h"
namespace flutter {
......@@ -21,7 +22,8 @@ namespace flutter {
class AndroidSurface {
public:
static std::unique_ptr<AndroidSurface> Create(
std::shared_ptr<AndroidContext> android_context);
std::shared_ptr<AndroidContext> android_context,
std::shared_ptr<PlatformViewAndroidJNI> jni_facade);
virtual ~AndroidSurface();
......
......@@ -12,7 +12,8 @@
namespace flutter {
AndroidSurfaceGL::AndroidSurfaceGL(
std::shared_ptr<AndroidContext> android_context)
std::shared_ptr<AndroidContext> android_context,
std::shared_ptr<PlatformViewAndroidJNI> jni_facade)
: native_window_(nullptr),
onscreen_surface_(nullptr),
offscreen_surface_(nullptr) {
......@@ -23,7 +24,8 @@ AndroidSurfaceGL::AndroidSurfaceGL(
if (!offscreen_surface_->IsValid()) {
offscreen_surface_ = nullptr;
}
external_view_embedder_ = std::make_unique<AndroidExternalViewEmbedder>();
external_view_embedder_ =
std::make_unique<AndroidExternalViewEmbedder>(jni_facade);
}
AndroidSurfaceGL::~AndroidSurfaceGL() = default;
......
......@@ -14,13 +14,15 @@
#include "flutter/shell/platform/android/android_environment_gl.h"
#include "flutter/shell/platform/android/android_surface.h"
#include "flutter/shell/platform/android/external_view_embedder/external_view_embedder.h"
#include "flutter/shell/platform/android/jni/platform_view_android_jni.h"
namespace flutter {
class AndroidSurfaceGL final : public GPUSurfaceGLDelegate,
public AndroidSurface {
public:
AndroidSurfaceGL(std::shared_ptr<AndroidContext> android_context);
AndroidSurfaceGL(std::shared_ptr<AndroidContext> android_context,
std::shared_ptr<PlatformViewAndroidJNI> jni_facade);
~AndroidSurfaceGL() override;
......
......@@ -11,7 +11,7 @@
#include "flutter/fml/platform/android/jni_weak_ref.h"
#include "flutter/fml/platform/android/scoped_java_ref.h"
#include "flutter/fml/trace_event.h"
#include "flutter/shell/platform/android/platform_view_android_jni.h"
#include "flutter/shell/platform/android/jni/platform_view_android_jni.h"
namespace flutter {
......@@ -36,10 +36,12 @@ bool GetSkColorType(int32_t buffer_format,
} // anonymous namespace
AndroidSurfaceSoftware::AndroidSurfaceSoftware() {
AndroidSurfaceSoftware::AndroidSurfaceSoftware(
std::shared_ptr<PlatformViewAndroidJNI> jni_facade) {
GetSkColorType(WINDOW_FORMAT_RGBA_8888, &target_color_type_,
&target_alpha_type_);
external_view_embedder_ = std::make_unique<AndroidExternalViewEmbedder>();
external_view_embedder_ =
std::make_unique<AndroidExternalViewEmbedder>(jni_facade);
}
AndroidSurfaceSoftware::~AndroidSurfaceSoftware() = default;
......
......@@ -11,13 +11,14 @@
#include "flutter/shell/gpu/gpu_surface_software.h"
#include "flutter/shell/platform/android/android_surface.h"
#include "flutter/shell/platform/android/external_view_embedder/external_view_embedder.h"
#include "flutter/shell/platform/android/jni/platform_view_android_jni.h"
namespace flutter {
class AndroidSurfaceSoftware final : public AndroidSurface,
public GPUSurfaceSoftwareDelegate {
public:
AndroidSurfaceSoftware();
AndroidSurfaceSoftware(std::shared_ptr<PlatformViewAndroidJNI> jni_facade);
~AndroidSurfaceSoftware() override;
......
......@@ -12,9 +12,11 @@
namespace flutter {
AndroidSurfaceVulkan::AndroidSurfaceVulkan()
AndroidSurfaceVulkan::AndroidSurfaceVulkan(
std::shared_ptr<PlatformViewAndroidJNI> jni_facade)
: proc_table_(fml::MakeRefCounted<vulkan::VulkanProcTable>()) {
external_view_embedder_ = std::make_unique<AndroidExternalViewEmbedder>();
external_view_embedder_ =
std::make_unique<AndroidExternalViewEmbedder>(jni_facade);
}
AndroidSurfaceVulkan::~AndroidSurfaceVulkan() = default;
......
......@@ -12,6 +12,7 @@
#include "flutter/shell/platform/android/android_native_window.h"
#include "flutter/shell/platform/android/android_surface.h"
#include "flutter/shell/platform/android/external_view_embedder/external_view_embedder.h"
#include "flutter/shell/platform/android/jni/platform_view_android_jni.h"
#include "flutter/vulkan/vulkan_window.h"
namespace flutter {
......@@ -19,7 +20,7 @@ namespace flutter {
class AndroidSurfaceVulkan : public AndroidSurface,
public GPUSurfaceVulkanDelegate {
public:
AndroidSurfaceVulkan();
AndroidSurfaceVulkan(std::shared_ptr<PlatformViewAndroidJNI> jni_facade);
~AndroidSurfaceVulkan() override;
......
......@@ -22,6 +22,7 @@ source_set("external_view_embedder") {
"//flutter/common",
"//flutter/flow",
"//flutter/fml",
"//flutter/shell/platform/android/jni",
"//third_party/skia",
]
}
......
......@@ -8,6 +8,10 @@
namespace flutter {
AndroidExternalViewEmbedder::AndroidExternalViewEmbedder(
std::shared_ptr<PlatformViewAndroidJNI> jni_facade)
: ExternalViewEmbedder(), jni_facade_(jni_facade) {}
// |ExternalViewEmbedder|
void AndroidExternalViewEmbedder::PrerollCompositeEmbeddedView(
int view_id,
......
......@@ -7,12 +7,16 @@
#include "flutter/flow/embedded_views.h"
#include "flutter/shell/platform/android/jni/platform_view_android_jni.h"
#include "third_party/skia/include/core/SkPictureRecorder.h"
namespace flutter {
class AndroidExternalViewEmbedder : public ExternalViewEmbedder {
class AndroidExternalViewEmbedder final : public ExternalViewEmbedder {
public:
AndroidExternalViewEmbedder(
std::shared_ptr<PlatformViewAndroidJNI> jni_facade);
// |ExternalViewEmbedder|
void PrerollCompositeEmbeddedView(
int view_id,
......@@ -48,6 +52,9 @@ class AndroidExternalViewEmbedder : public ExternalViewEmbedder {
fml::RefPtr<fml::RasterThreadMerger> raster_thread_merger) override;
private:
// Allows to call methods in Java.
const std::shared_ptr<PlatformViewAndroidJNI> jni_facade_;
// The number of frames the rasterizer task runner will continue
// to run on the platform thread after no platform view is rendered.
//
......
......@@ -11,7 +11,7 @@ namespace flutter {
namespace testing {
TEST(AndroidExternalViewEmbedder, GetCurrentCanvases) {
auto embedder = new AndroidExternalViewEmbedder();
auto embedder = new AndroidExternalViewEmbedder(nullptr);
embedder->BeginFrame(SkISize::Make(10, 20), nullptr, 1.0);
......@@ -27,7 +27,7 @@ TEST(AndroidExternalViewEmbedder, GetCurrentCanvases) {
}
TEST(AndroidExternalViewEmbedder, CompositeEmbeddedView) {
auto embedder = new AndroidExternalViewEmbedder();
auto embedder = new AndroidExternalViewEmbedder(nullptr);
embedder->PrerollCompositeEmbeddedView(
0, std::make_unique<EmbeddedViewParams>());
......@@ -39,7 +39,7 @@ TEST(AndroidExternalViewEmbedder, CompositeEmbeddedView) {
}
TEST(AndroidExternalViewEmbedder, CancelFrame) {
auto embedder = new AndroidExternalViewEmbedder();
auto embedder = new AndroidExternalViewEmbedder(nullptr);
embedder->PrerollCompositeEmbeddedView(
0, std::make_unique<EmbeddedViewParams>());
......@@ -50,7 +50,7 @@ TEST(AndroidExternalViewEmbedder, CancelFrame) {
}
TEST(AndroidExternalViewEmbedder, RasterizerRunsOnPlatformThread) {
auto embedder = new AndroidExternalViewEmbedder();
auto embedder = new AndroidExternalViewEmbedder(nullptr);
auto platform_thread = new fml::Thread("platform");
auto rasterizer_thread = new fml::Thread("rasterizer");
auto platform_queue_id = platform_thread->GetTaskRunner()->GetTaskQueueId();
......@@ -82,7 +82,7 @@ TEST(AndroidExternalViewEmbedder, RasterizerRunsOnPlatformThread) {
}
TEST(AndroidExternalViewEmbedder, RasterizerRunsOnRasterizerThread) {
auto embedder = new AndroidExternalViewEmbedder();
auto embedder = new AndroidExternalViewEmbedder(nullptr);
auto platform_thread = new fml::Thread("platform");
auto rasterizer_thread = new fml::Thread("rasterizer");
auto platform_queue_id = platform_thread->GetTaskRunner()->GetTaskQueueId();
......
# Copyright 2013 The Flutter Authors. All rights reserved.
# Use of this source code is governed by a BSD-style license that can be
# found in the LICENSE file.
import("//flutter/common/config.gni")
source_set("jni") {
sources = [
"platform_view_android_jni.cc",
"platform_view_android_jni.h",
]
public_configs = [ "//flutter:config" ]
deps = [
"//flutter/fml",
"//flutter/lib/ui",
"//third_party/skia",
]
}
// Copyright 2013 The Flutter Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
#include "flutter/shell/platform/android/jni/platform_view_android_jni.h"
namespace flutter {
PlatformViewAndroidJNI::~PlatformViewAndroidJNI() = default;
} // namespace flutter
// Copyright 2013 The Flutter Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
#ifndef FLUTTER_SHELL_PLATFORM_ANDROID_PLATFORM_VIEW_ANDROID_JNI_H_
#define FLUTTER_SHELL_PLATFORM_ANDROID_PLATFORM_VIEW_ANDROID_JNI_H_
#include "flutter/fml/macros.h"
#include "flutter/fml/mapping.h"
#if OS_ANDROID
#include "flutter/fml/platform/android/jni_weak_ref.h"
#endif
#include "flutter/lib/ui/window/platform_message.h"
#include "third_party/skia/include/core/SkMatrix.h"
namespace flutter {
#if OS_ANDROID
using JavaWeakGlobalRef = fml::jni::JavaObjectWeakGlobalRef;
#else
using JavaWeakGlobalRef = std::nullptr_t;
#endif
//------------------------------------------------------------------------------
/// Allows to call Java code running in the JVM from any thread. However, most
/// methods can only be called from the platform thread as that is where the
/// Java code runs.
///
/// This interface must not depend on the Android toolchain directly, so it can
/// be used in unit tests compiled with the host toolchain.
///
class PlatformViewAndroidJNI {
public:
virtual ~PlatformViewAndroidJNI();
//----------------------------------------------------------------------------
/// @brief Sends a platform message. The message may be empty.
///
virtual void FlutterViewHandlePlatformMessage(
fml::RefPtr<flutter::PlatformMessage> message,
int responseId) = 0;
//----------------------------------------------------------------------------
/// @brief Responds to a platform message. The data may be a `nullptr`.
///
virtual void FlutterViewHandlePlatformMessageResponse(
int responseId,
std::unique_ptr<fml::Mapping> data) = 0;
//----------------------------------------------------------------------------
/// @brief Sends semantics tree updates.
///
/// @note Must be called from the platform thread.
///
virtual void FlutterViewUpdateSemantics(std::vector<uint8_t> buffer,
std::vector<std::string> strings) = 0;
//----------------------------------------------------------------------------
/// @brief Sends new custom accessibility events.
///
/// @note Must be called from the platform thread.
///
virtual void FlutterViewUpdateCustomAccessibilityActions(
std::vector<uint8_t> actions_buffer,
std::vector<std::string> strings) = 0;
//----------------------------------------------------------------------------
/// @brief Indicates that FlutterView should start painting pixels.
///
/// @note Must be called from the platform thread.
///
virtual void FlutterViewOnFirstFrame() = 0;
//----------------------------------------------------------------------------
/// @brief Indicates that a hot restart is about to happen.
///
virtual void FlutterViewOnPreEngineRestart() = 0;
//----------------------------------------------------------------------------
/// @brief Attach the SurfaceTexture to the OpenGL ES context that is
/// current on the calling thread.
///
virtual void SurfaceTextureAttachToGLContext(
JavaWeakGlobalRef surface_texture,
int textureId) = 0;
//----------------------------------------------------------------------------
/// @brief Updates the texture image to the most recent frame from the
/// image stream.
///
virtual void SurfaceTextureUpdateTexImage(
JavaWeakGlobalRef surface_texture) = 0;
//----------------------------------------------------------------------------
/// @brief Gets the transform matrix from the SurfaceTexture.
/// Then, it updates the `transform` matrix, so it fill the canvas
/// and preserve the aspect ratio.
///
virtual void SurfaceTextureGetTransformMatrix(
JavaWeakGlobalRef surface_texture,
SkMatrix& transform) = 0;
//----------------------------------------------------------------------------
/// @brief Detaches a SurfaceTexture from the OpenGL ES context.
///
virtual void SurfaceTextureDetachFromGLContext(
JavaWeakGlobalRef surface_texture) = 0;
//----------------------------------------------------------------------------
/// @brief Positions and sizes a platform view if using hybrid
/// composition.
///
/// @note Must be called from the platform thread.
///
virtual void FlutterViewOnDisplayPlatformView(int view_id,
int x,
int y,
int width,
int height) = 0;
//----------------------------------------------------------------------------
/// @brief Positions and sizes an overlay surface in hybrid composition.
///
/// @note Must be called from the platform thread.
///
virtual void FlutterViewDisplayOverlaySurface(int surface_id,
int x,
int y,
int width,
int height) = 0;
};
} // namespace flutter
#endif // FLUTTER_SHELL_PLATFORM_ANDROID_PLATFORM_VIEW_ANDROID_JNI_H_
......@@ -5,16 +5,16 @@
#include "flutter/shell/platform/android/platform_message_response_android.h"
#include "flutter/fml/make_copyable.h"
#include "flutter/shell/platform/android/platform_view_android_jni.h"
#include "flutter/shell/platform/android/jni/platform_view_android_jni.h"
namespace flutter {
PlatformMessageResponseAndroid::PlatformMessageResponseAndroid(
int response_id,
fml::jni::JavaObjectWeakGlobalRef weak_java_object,
std::shared_ptr<PlatformViewAndroidJNI> jni_facade,
fml::RefPtr<fml::TaskRunner> platform_task_runner)
: response_id_(response_id),
weak_java_object_(weak_java_object),
jni_facade_(jni_facade),
platform_task_runner_(std::move(platform_task_runner)) {}
PlatformMessageResponseAndroid::~PlatformMessageResponseAndroid() = default;
......@@ -23,53 +23,23 @@ PlatformMessageResponseAndroid::~PlatformMessageResponseAndroid() = default;
void PlatformMessageResponseAndroid::Complete(
std::unique_ptr<fml::Mapping> data) {
platform_task_runner_->PostTask(
fml::MakeCopyable([response = response_id_, //
weak_java_object = weak_java_object_, //
data = std::move(data) //
]() {
// We are on the platform thread. Attempt to get the strong reference to
// the Java object.
auto* env = fml::jni::AttachCurrentThread();
auto java_object = weak_java_object.get(env);
if (java_object.is_null()) {
// The Java object was collected before this message response got to
// it. Drop the response on the floor.
return;
}
// Convert the vector to a Java byte array.
fml::jni::ScopedJavaLocalRef<jbyteArray> data_array(
env, env->NewByteArray(data->GetSize()));
env->SetByteArrayRegion(
data_array.obj(), 0, data->GetSize(),
reinterpret_cast<const jbyte*>(data->GetMapping()));
// Make the response call into Java.
FlutterViewHandlePlatformMessageResponse(env, java_object.obj(),
response, data_array.obj());
fml::MakeCopyable([response_id = response_id_, //
data = std::move(data), //
jni_facade = jni_facade_]() mutable {
jni_facade->FlutterViewHandlePlatformMessageResponse(response_id,
std::move(data));
}));
}
// |flutter::PlatformMessageResponse|
void PlatformMessageResponseAndroid::CompleteEmpty() {
platform_task_runner_->PostTask(
fml::MakeCopyable([response = response_id_, //
weak_java_object = weak_java_object_ //
fml::MakeCopyable([response_id = response_id_, //
jni_facade = jni_facade_ //
]() {
// We are on the platform thread. Attempt to get the strong reference to
// the Java object.
auto* env = fml::jni::AttachCurrentThread();
auto java_object = weak_java_object.get(env);
if (java_object.is_null()) {
// The Java object was collected before this message response got to
// it. Drop the response on the floor.
return;
}
// Make the response call into Java.
FlutterViewHandlePlatformMessageResponse(env, java_object.obj(),
response, nullptr);
jni_facade->FlutterViewHandlePlatformMessageResponse(response_id,
nullptr);
}));
}
} // namespace flutter
......@@ -9,6 +9,7 @@
#include "flutter/fml/platform/android/jni_weak_ref.h"
#include "flutter/fml/task_runner.h"
#include "flutter/lib/ui/window/platform_message_response.h"
#include "flutter/shell/platform/android/jni/platform_view_android_jni.h"
namespace flutter {
......@@ -23,14 +24,14 @@ class PlatformMessageResponseAndroid : public flutter::PlatformMessageResponse {
private:
PlatformMessageResponseAndroid(
int response_id,
fml::jni::JavaObjectWeakGlobalRef weak_java_object,
std::shared_ptr<PlatformViewAndroidJNI> jni_facade,
fml::RefPtr<fml::TaskRunner> platform_task_runner);
~PlatformMessageResponseAndroid() override;
int response_id_;
fml::jni::JavaObjectWeakGlobalRef weak_java_object_;
fml::RefPtr<fml::TaskRunner> platform_task_runner_;
const int response_id_;
const std::shared_ptr<PlatformViewAndroidJNI> jni_facade_;
const fml::RefPtr<fml::TaskRunner> platform_task_runner_;
FML_FRIEND_MAKE_REF_COUNTED(PlatformMessageResponseAndroid);
FML_DISALLOW_COPY_AND_ASSIGN(PlatformMessageResponseAndroid);
......
......@@ -13,8 +13,8 @@
#include "flutter/shell/platform/android/android_context.h"
#include "flutter/shell/platform/android/android_external_texture_gl.h"
#include "flutter/shell/platform/android/android_surface_gl.h"
#include "flutter/shell/platform/android/jni/platform_view_android_jni.h"
#include "flutter/shell/platform/android/platform_message_response_android.h"
#include "flutter/shell/platform/android/platform_view_android_jni.h"
#include "flutter/shell/platform/android/vsync_waiter_android.h"
namespace flutter {
......@@ -22,10 +22,9 @@ namespace flutter {
PlatformViewAndroid::PlatformViewAndroid(
PlatformView::Delegate& delegate,
flutter::TaskRunners task_runners,
fml::jni::JavaObjectWeakGlobalRef java_object,
std::shared_ptr<PlatformViewAndroidJNI> jni_facade,
bool use_software_rendering)
: PlatformView(delegate, std::move(task_runners)),
java_object_(java_object) {
: PlatformView(delegate, std::move(task_runners)), jni_facade_(jni_facade) {
std::shared_ptr<AndroidContext> android_context;
if (use_software_rendering) {
android_context = AndroidContext::Create(AndroidRenderingAPI::kSoftware);
......@@ -36,7 +35,7 @@ PlatformViewAndroid::PlatformViewAndroid(
android_context = AndroidContext::Create(AndroidRenderingAPI::kOpenGLES);
#endif // SHELL_ENABLE_VULKAN
}
android_surface_ = AndroidSurface::Create(android_context);
android_surface_ = AndroidSurface::Create(android_context, jni_facade);
FML_CHECK(android_surface_)
<< "Could not create an OpenGL, Vulkan or Software surface to setup "
"rendering.";
......@@ -45,10 +44,9 @@ PlatformViewAndroid::PlatformViewAndroid(
PlatformViewAndroid::PlatformViewAndroid(
PlatformView::Delegate& delegate,
flutter::TaskRunners task_runners,
fml::jni::JavaObjectWeakGlobalRef java_object)
std::shared_ptr<PlatformViewAndroidJNI> jni_facade)
: PlatformView(delegate, std::move(task_runners)),
java_object_(java_object),
android_surface_(nullptr) {}
jni_facade_(jni_facade) {}
PlatformViewAndroid::~PlatformViewAndroid() = default;
......@@ -113,7 +111,7 @@ void PlatformViewAndroid::DispatchPlatformMessage(JNIEnv* env,
fml::RefPtr<flutter::PlatformMessageResponse> response;
if (response_id) {
response = fml::MakeRefCounted<PlatformMessageResponseAndroid>(
response_id, java_object_, task_runners_.GetPlatformTaskRunner());
response_id, jni_facade_, task_runners_.GetPlatformTaskRunner());
}
PlatformView::DispatchPlatformMessage(
......@@ -127,7 +125,7 @@ void PlatformViewAndroid::DispatchEmptyPlatformMessage(JNIEnv* env,
fml::RefPtr<flutter::PlatformMessageResponse> response;
if (response_id) {
response = fml::MakeRefCounted<PlatformMessageResponseAndroid>(
response_id, java_object_, task_runners_.GetPlatformTaskRunner());
response_id, jni_facade_, task_runners_.GetPlatformTaskRunner());
}
PlatformView::DispatchPlatformMessage(
......@@ -171,46 +169,19 @@ void PlatformViewAndroid::InvokePlatformMessageEmptyResponseCallback(
// |PlatformView|
void PlatformViewAndroid::HandlePlatformMessage(
fml::RefPtr<flutter::PlatformMessage> message) {
JNIEnv* env = fml::jni::AttachCurrentThread();
fml::jni::ScopedJavaLocalRef<jobject> view = java_object_.get(env);
if (view.is_null())
return;
int response_id = 0;
if (auto response = message->response()) {
response_id = next_response_id_++;
pending_responses_[response_id] = response;
}
auto java_channel = fml::jni::StringToJavaString(env, message->channel());
if (message->hasData()) {
fml::jni::ScopedJavaLocalRef<jbyteArray> message_array(
env, env->NewByteArray(message->data().size()));
env->SetByteArrayRegion(
message_array.obj(), 0, message->data().size(),
reinterpret_cast<const jbyte*>(message->data().data()));
message = nullptr;
// This call can re-enter in InvokePlatformMessageXxxResponseCallback.
FlutterViewHandlePlatformMessage(env, view.obj(), java_channel.obj(),
message_array.obj(), response_id);
} else {
message = nullptr;
// This call can re-enter in InvokePlatformMessageXxxResponseCallback.
FlutterViewHandlePlatformMessage(env, view.obj(), java_channel.obj(),
nullptr, response_id);
}
// This call can re-enter in InvokePlatformMessageXxxResponseCallback.
jni_facade_->FlutterViewHandlePlatformMessage(message, response_id);
message = nullptr;
}
// |PlatformView|
void PlatformViewAndroid::OnPreEngineRestart() const {
JNIEnv* env = fml::jni::AttachCurrentThread();
fml::jni::ScopedJavaLocalRef<jobject> view = java_object_.get(env);
if (view.is_null()) {
// The Java object died.
return;
}
FlutterViewOnPreEngineRestart(fml::jni::AttachCurrentThread(), view.obj());
jni_facade_->FlutterViewOnPreEngineRestart();
}
void PlatformViewAndroid::DispatchSemanticsAction(JNIEnv* env,
......@@ -242,12 +213,7 @@ void PlatformViewAndroid::UpdateSemantics(
constexpr size_t kBytesPerChild = sizeof(int32_t);
constexpr size_t kBytesPerAction = 4 * sizeof(int32_t);
JNIEnv* env = fml::jni::AttachCurrentThread();
{
fml::jni::ScopedJavaLocalRef<jobject> view = java_object_.get(env);
if (view.is_null())
return;
size_t num_bytes = 0;
for (const auto& value : update) {
num_bytes += kBytesPerNode;
......@@ -372,20 +338,12 @@ void PlatformViewAndroid::UpdateSemantics(
// Calling NewDirectByteBuffer in API level 22 and below with a size of zero
// will cause a JNI crash.
if (actions_buffer.size() > 0) {
fml::jni::ScopedJavaLocalRef<jobject> direct_actions_buffer(
env, env->NewDirectByteBuffer(actions_buffer.data(),
actions_buffer.size()));
FlutterViewUpdateCustomAccessibilityActions(
env, view.obj(), direct_actions_buffer.obj(),
fml::jni::VectorToStringArray(env, action_strings).obj());
jni_facade_->FlutterViewUpdateCustomAccessibilityActions(actions_buffer,
strings);
}
if (buffer.size() > 0) {
fml::jni::ScopedJavaLocalRef<jobject> direct_buffer(
env, env->NewDirectByteBuffer(buffer.data(), buffer.size()));
FlutterViewUpdateSemantics(
env, view.obj(), direct_buffer.obj(),
fml::jni::VectorToStringArray(env, strings).obj());
jni_facade_->FlutterViewUpdateSemantics(buffer, strings);
}
}
}
......@@ -393,8 +351,8 @@ void PlatformViewAndroid::UpdateSemantics(
void PlatformViewAndroid::RegisterExternalTexture(
int64_t texture_id,
const fml::jni::JavaObjectWeakGlobalRef& surface_texture) {
RegisterTexture(
std::make_shared<AndroidExternalTextureGL>(texture_id, surface_texture));
RegisterTexture(std::make_shared<AndroidExternalTextureGL>(
texture_id, surface_texture, std::move(jni_facade_)));
}
// |PlatformView|
......@@ -454,13 +412,7 @@ void PlatformViewAndroid::InstallFirstFrameCallback() {
}
void PlatformViewAndroid::FireFirstFrameCallback() {
JNIEnv* env = fml::jni::AttachCurrentThread();
fml::jni::ScopedJavaLocalRef<jobject> view = java_object_.get(env);
if (view.is_null()) {
// The Java object died.
return;
}
FlutterViewOnFirstFrame(fml::jni::AttachCurrentThread(), view.obj());
jni_facade_->FlutterViewOnFirstFrame();
}
} // namespace flutter
......@@ -17,6 +17,7 @@
#include "flutter/shell/common/platform_view.h"
#include "flutter/shell/platform/android/android_native_window.h"
#include "flutter/shell/platform/android/android_surface.h"
#include "flutter/shell/platform/android/jni/platform_view_android_jni.h"
namespace flutter {
......@@ -28,12 +29,12 @@ class PlatformViewAndroid final : public PlatformView {
// background execution.
PlatformViewAndroid(PlatformView::Delegate& delegate,
flutter::TaskRunners task_runners,
fml::jni::JavaObjectWeakGlobalRef java_object);
std::shared_ptr<PlatformViewAndroidJNI> jni_facade);
// Creates a PlatformViewAndroid with a rendering surface.
PlatformViewAndroid(PlatformView::Delegate& delegate,
flutter::TaskRunners task_runners,
fml::jni::JavaObjectWeakGlobalRef java_object,
std::shared_ptr<PlatformViewAndroidJNI> jni_facade,
bool use_software_rendering);
~PlatformViewAndroid() override;
......@@ -74,7 +75,7 @@ class PlatformViewAndroid final : public PlatformView {
const fml::jni::JavaObjectWeakGlobalRef& surface_texture);
private:
const fml::jni::JavaObjectWeakGlobalRef java_object_;
const std::shared_ptr<PlatformViewAndroidJNI> jni_facade_;
std::unique_ptr<AndroidSurface> android_surface_;
// We use id 0 to mean that no response is expected.
......
// Copyright 2013 The Flutter Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
#ifndef FLUTTER_SHELL_PLATFORM_ANDROID_PLATFORM_VIEW_ANDROID_JNI_H_
#define FLUTTER_SHELL_PLATFORM_ANDROID_PLATFORM_VIEW_ANDROID_JNI_H_
#include <jni.h>
#include "flutter/fml/macros.h"
#include "flutter/shell/platform/android/platform_view_android.h"
namespace flutter {
void FlutterViewHandlePlatformMessage(JNIEnv* env,
jobject obj,
jstring channel,
jobject message,
jint responseId);
void FlutterViewHandlePlatformMessageResponse(JNIEnv* env,
jobject obj,
jint responseId,
jobject response);
void FlutterViewUpdateSemantics(JNIEnv* env,
jobject obj,
jobject buffer,
jobjectArray strings);
void FlutterViewUpdateCustomAccessibilityActions(JNIEnv* env,
jobject obj,
jobject buffer,
jobjectArray strings);
void FlutterViewOnFirstFrame(JNIEnv* env, jobject obj);
void FlutterViewOnPreEngineRestart(JNIEnv* env, jobject obj);
void FlutterViewOnDisplayPlatformView(JNIEnv* env,
jobject obj,
jint view_id,
jint x,
jint y,
jint width,
jint height);
void FlutterViewDisplayOverlaySurface(JNIEnv* env,
jobject obj,
jint id,
jint x,
jint y,
jint width,
jint height);
void SurfaceTextureAttachToGLContext(JNIEnv* env, jobject obj, jint textureId);
void SurfaceTextureUpdateTexImage(JNIEnv* env, jobject obj);
void SurfaceTextureGetTransformMatrix(JNIEnv* env,
jobject obj,
jfloatArray result);
void SurfaceTextureDetachFromGLContext(JNIEnv* env, jobject obj);
} // namespace flutter
#endif // FLUTTER_SHELL_PLATFORM_ANDROID_PLATFORM_VIEW_ANDROID_JNI_H_
......@@ -2,11 +2,12 @@
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
#include "flutter/shell/platform/android/platform_view_android_jni.h"
#include "flutter/shell/platform/android/platform_view_android_jni_impl.h"
#include <android/native_window_jni.h>
#include <jni.h>
#include <utility>
#include "unicode/uchar.h"
#include "flutter/assets/directory_asset_bundle.h"
......@@ -23,6 +24,7 @@
#include "flutter/shell/platform/android/android_shell_holder.h"
#include "flutter/shell/platform/android/apk_asset_provider.h"
#include "flutter/shell/platform/android/flutter_main.h"
#include "flutter/shell/platform/android/platform_view_android.h"
#define ANDROID_SHELL_HOLDER \
(reinterpret_cast<AndroidShellHolder*>(shell_holder))
......@@ -67,105 +69,39 @@ jobject CreateFlutterCallbackInformation(
}
static jmethodID g_handle_platform_message_method = nullptr;
void FlutterViewHandlePlatformMessage(JNIEnv* env,
jobject obj,
jstring channel,
jobject message,
jint responseId) {
env->CallVoidMethod(obj, g_handle_platform_message_method, channel, message,
responseId);
FML_CHECK(CheckException(env));
}
static jmethodID g_handle_platform_message_response_method = nullptr;
void FlutterViewHandlePlatformMessageResponse(JNIEnv* env,
jobject obj,
jint responseId,
jobject response) {
env->CallVoidMethod(obj, g_handle_platform_message_response_method,
responseId, response);
FML_CHECK(CheckException(env));
}
static jmethodID g_update_semantics_method = nullptr;
void FlutterViewUpdateSemantics(JNIEnv* env,
jobject obj,
jobject buffer,
jobjectArray strings) {
env->CallVoidMethod(obj, g_update_semantics_method, buffer, strings);
FML_CHECK(CheckException(env));
}
static jmethodID g_update_custom_accessibility_actions_method = nullptr;
void FlutterViewUpdateCustomAccessibilityActions(JNIEnv* env,
jobject obj,
jobject buffer,
jobjectArray strings) {
env->CallVoidMethod(obj, g_update_custom_accessibility_actions_method, buffer,
strings);
FML_CHECK(CheckException(env));
}
static jmethodID g_on_first_frame_method = nullptr;
void FlutterViewOnFirstFrame(JNIEnv* env, jobject obj) {
env->CallVoidMethod(obj, g_on_first_frame_method);
FML_CHECK(CheckException(env));
}
static jmethodID g_on_engine_restart_method = nullptr;
void FlutterViewOnPreEngineRestart(JNIEnv* env, jobject obj) {
env->CallVoidMethod(obj, g_on_engine_restart_method);
FML_CHECK(CheckException(env));
}
static jmethodID g_on_display_platform_view_method = nullptr;
void FlutterViewOnDisplayPlatformView(JNIEnv* env,
jobject obj,
jint view_id,
jint x,
jint y,
jint width,
jint height) {
env->CallVoidMethod(obj, g_on_display_platform_view_method, view_id, x, y,
width, height);
FML_CHECK(CheckException(env));
}
static jmethodID g_attach_to_gl_context_method = nullptr;
void SurfaceTextureAttachToGLContext(JNIEnv* env, jobject obj, jint textureId) {
env->CallVoidMethod(obj, g_attach_to_gl_context_method, textureId);
FML_CHECK(CheckException(env));
}
static jmethodID g_update_tex_image_method = nullptr;
void SurfaceTextureUpdateTexImage(JNIEnv* env, jobject obj) {
env->CallVoidMethod(obj, g_update_tex_image_method);
FML_CHECK(CheckException(env));
}
static jmethodID g_get_transform_matrix_method = nullptr;
void SurfaceTextureGetTransformMatrix(JNIEnv* env,
jobject obj,
jfloatArray result) {
env->CallVoidMethod(obj, g_get_transform_matrix_method, result);
FML_CHECK(CheckException(env));
}
static jmethodID g_detach_from_gl_context_method = nullptr;
void SurfaceTextureDetachFromGLContext(JNIEnv* env, jobject obj) {
env->CallVoidMethod(obj, g_detach_from_gl_context_method);
FML_CHECK(CheckException(env));
}
// Called By Java
static jmethodID g_on_display_platform_view_method = nullptr;
static jmethodID g_on_display_overlay_surface_method = nullptr;
// Called By Java
static jlong AttachJNI(JNIEnv* env,
jclass clazz,
jobject flutterJNI,
jboolean is_background_view) {
fml::jni::JavaObjectWeakGlobalRef java_object(env, flutterJNI);
std::shared_ptr<PlatformViewAndroidJNI> jni_facade =
std::make_shared<PlatformViewAndroidJNIImpl>(java_object);
auto shell_holder = std::make_unique<AndroidShellHolder>(
FlutterMain::Get().GetSettings(), java_object, is_background_view);
FlutterMain::Get().GetSettings(), jni_facade, is_background_view);
if (shell_holder->IsValid()) {
return reinterpret_cast<jlong>(shell_holder.release());
} else {
......@@ -782,6 +718,14 @@ bool PlatformViewAndroid::Register(JNIEnv* env) {
return false;
}
g_on_display_overlay_surface_method = env->GetMethodID(
g_flutter_jni_class->obj(), "onDisplayOverlaySurface", "(IIIII)V");
if (g_on_display_overlay_surface_method == nullptr) {
FML_LOG(ERROR) << "Could not locate onDisplayOverlaySurface method";
return false;
}
g_surface_texture_class = new fml::jni::ScopedJavaGlobalRef<jclass>(
env, env->FindClass("android/graphics/SurfaceTexture"));
if (g_surface_texture_class->is_null()) {
......@@ -824,4 +768,270 @@ bool PlatformViewAndroid::Register(JNIEnv* env) {
return RegisterApi(env);
}
PlatformViewAndroidJNIImpl::PlatformViewAndroidJNIImpl(
fml::jni::JavaObjectWeakGlobalRef java_object)
: java_object_(java_object) {}
PlatformViewAndroidJNIImpl::~PlatformViewAndroidJNIImpl() = default;
void PlatformViewAndroidJNIImpl::FlutterViewHandlePlatformMessage(
fml::RefPtr<flutter::PlatformMessage> message,
int responseId) {
JNIEnv* env = fml::jni::AttachCurrentThread();
auto java_object = java_object_.get(env);
if (java_object.is_null()) {
return;
}
fml::jni::ScopedJavaLocalRef<jstring> java_channel =
fml::jni::StringToJavaString(env, message->channel());
if (message->hasData()) {
fml::jni::ScopedJavaLocalRef<jbyteArray> message_array(
env, env->NewByteArray(message->data().size()));
env->SetByteArrayRegion(
message_array.obj(), 0, message->data().size(),
reinterpret_cast<const jbyte*>(message->data().data()));
env->CallVoidMethod(java_object.obj(), g_handle_platform_message_method,
java_channel.obj(), message_array.obj(), responseId);
} else {
env->CallVoidMethod(java_object.obj(), g_handle_platform_message_method,
java_channel.obj(), nullptr, responseId);
}
FML_CHECK(CheckException(env));
}
void PlatformViewAndroidJNIImpl::FlutterViewHandlePlatformMessageResponse(
int responseId,
std::unique_ptr<fml::Mapping> data) {
// We are on the platform thread. Attempt to get the strong reference to
// the Java object.
JNIEnv* env = fml::jni::AttachCurrentThread();
auto java_object = java_object_.get(env);
if (java_object.is_null()) {
// The Java object was collected before this message response got to
// it. Drop the response on the floor.
return;
}
if (data == nullptr) { // Empty response.
env->CallVoidMethod(java_object.obj(),
g_handle_platform_message_response_method, responseId,
nullptr);
} else {
// Convert the vector to a Java byte array.
fml::jni::ScopedJavaLocalRef<jbyteArray> data_array(
env, env->NewByteArray(data->GetSize()));
env->SetByteArrayRegion(data_array.obj(), 0, data->GetSize(),
reinterpret_cast<const jbyte*>(data->GetMapping()));
env->CallVoidMethod(java_object.obj(),
g_handle_platform_message_response_method, responseId,
data_array.obj());
}
FML_CHECK(CheckException(env));
}
void PlatformViewAndroidJNIImpl::FlutterViewUpdateSemantics(
std::vector<uint8_t> buffer,
std::vector<std::string> strings) {
JNIEnv* env = fml::jni::AttachCurrentThread();
auto java_object = java_object_.get(env);
if (java_object.is_null()) {
return;
}
fml::jni::ScopedJavaLocalRef<jobject> direct_buffer(
env, env->NewDirectByteBuffer(buffer.data(), buffer.size()));
fml::jni::ScopedJavaLocalRef<jobjectArray> jstrings =
fml::jni::VectorToStringArray(env, strings);
env->CallVoidMethod(java_object.obj(), g_update_semantics_method,
direct_buffer.obj(), jstrings.obj());
FML_CHECK(CheckException(env));
}
void PlatformViewAndroidJNIImpl::FlutterViewUpdateCustomAccessibilityActions(
std::vector<uint8_t> actions_buffer,
std::vector<std::string> strings) {
JNIEnv* env = fml::jni::AttachCurrentThread();
auto java_object = java_object_.get(env);
if (java_object.is_null()) {
return;
}
fml::jni::ScopedJavaLocalRef<jobject> direct_actions_buffer(
env,
env->NewDirectByteBuffer(actions_buffer.data(), actions_buffer.size()));
fml::jni::ScopedJavaLocalRef<jobjectArray> jstrings =
fml::jni::VectorToStringArray(env, strings);
env->CallVoidMethod(java_object.obj(),
g_update_custom_accessibility_actions_method,
direct_actions_buffer.obj(), jstrings.obj());
FML_CHECK(CheckException(env));
}
void PlatformViewAndroidJNIImpl::FlutterViewOnFirstFrame() {
JNIEnv* env = fml::jni::AttachCurrentThread();
auto java_object = java_object_.get(env);
if (java_object.is_null()) {
return;
}
env->CallVoidMethod(java_object.obj(), g_on_first_frame_method);
FML_CHECK(CheckException(env));
}
void PlatformViewAndroidJNIImpl::FlutterViewOnPreEngineRestart() {
JNIEnv* env = fml::jni::AttachCurrentThread();
auto java_object = java_object_.get(env);
if (java_object.is_null()) {
return;
}
env->CallVoidMethod(java_object.obj(), g_on_engine_restart_method);
FML_CHECK(CheckException(env));
}
void PlatformViewAndroidJNIImpl::SurfaceTextureAttachToGLContext(
JavaWeakGlobalRef surface_texture,
int textureId) {
JNIEnv* env = fml::jni::AttachCurrentThread();
fml::jni::ScopedJavaLocalRef<jobject> surface_texture_local_ref =
surface_texture.get(env);
if (surface_texture_local_ref.is_null()) {
return;
}
env->CallVoidMethod(surface_texture_local_ref.obj(),
g_attach_to_gl_context_method, textureId);
FML_CHECK(CheckException(env));
}
void PlatformViewAndroidJNIImpl::SurfaceTextureUpdateTexImage(
JavaWeakGlobalRef surface_texture) {
JNIEnv* env = fml::jni::AttachCurrentThread();
fml::jni::ScopedJavaLocalRef<jobject> surface_texture_local_ref =
surface_texture.get(env);
if (surface_texture_local_ref.is_null()) {
return;
}
env->CallVoidMethod(surface_texture_local_ref.obj(),
g_update_tex_image_method);
FML_CHECK(CheckException(env));
}
// The bounds we set for the canvas are post composition.
// To fill the canvas we need to ensure that the transformation matrix
// on the `SurfaceTexture` will be scaled to fill. We rescale and preseve
// the scaled aspect ratio.
SkSize ScaleToFill(float scaleX, float scaleY) {
const double epsilon = std::numeric_limits<double>::epsilon();
// scaleY is negative.
const double minScale = fmin(scaleX, fabs(scaleY));
const double rescale = 1.0f / (minScale + epsilon);
return SkSize::Make(scaleX * rescale, scaleY * rescale);
}
void PlatformViewAndroidJNIImpl::SurfaceTextureGetTransformMatrix(
JavaWeakGlobalRef surface_texture,
SkMatrix& transform) {
JNIEnv* env = fml::jni::AttachCurrentThread();
fml::jni::ScopedJavaLocalRef<jobject> surface_texture_local_ref =
surface_texture.get(env);
if (surface_texture_local_ref.is_null()) {
return;
}
fml::jni::ScopedJavaLocalRef<jfloatArray> transformMatrix(
env, env->NewFloatArray(16));
env->CallVoidMethod(surface_texture_local_ref.obj(),
g_get_transform_matrix_method, transformMatrix.obj());
FML_CHECK(CheckException(env));
float* m = env->GetFloatArrayElements(transformMatrix.obj(), nullptr);
float scaleX = m[0], scaleY = m[5];
const SkSize scaled = ScaleToFill(scaleX, scaleY);
SkScalar matrix3[] = {
scaled.fWidth, m[1], m[2], //
m[4], scaled.fHeight, m[6], //
m[8], m[9], m[10], //
};
env->ReleaseFloatArrayElements(transformMatrix.obj(), m, JNI_ABORT);
transform.set9(matrix3);
}
void PlatformViewAndroidJNIImpl::SurfaceTextureDetachFromGLContext(
JavaWeakGlobalRef surface_texture) {
JNIEnv* env = fml::jni::AttachCurrentThread();
fml::jni::ScopedJavaLocalRef<jobject> surface_texture_local_ref =
surface_texture.get(env);
if (surface_texture_local_ref.is_null()) {
return;
}
env->CallVoidMethod(surface_texture_local_ref.obj(),
g_detach_from_gl_context_method);
FML_CHECK(CheckException(env));
}
void PlatformViewAndroidJNIImpl::FlutterViewOnDisplayPlatformView(int view_id,
int x,
int y,
int width,
int height) {
JNIEnv* env = fml::jni::AttachCurrentThread();
auto java_object = java_object_.get(env);
if (java_object.is_null()) {
return;
}
env->CallVoidMethod(java_object.obj(), g_on_display_platform_view_method,
view_id, x, y, width, height);
FML_CHECK(CheckException(env));
}
void PlatformViewAndroidJNIImpl::FlutterViewDisplayOverlaySurface(
int surface_id,
int x,
int y,
int width,
int height) {
JNIEnv* env = fml::jni::AttachCurrentThread();
auto java_object = java_object_.get(env);
if (java_object.is_null()) {
return;
}
env->CallVoidMethod(java_object.obj(), g_on_display_overlay_surface_method,
surface_id, x, y, width, height);
FML_CHECK(CheckException(env));
}
} // namespace flutter
// Copyright 2013 The Flutter Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
#ifndef FLUTTER_SHELL_PLATFORM_ANDROID_PLATFORM_VIEW_ANDROID_JNI_IMPL_H_
#define FLUTTER_SHELL_PLATFORM_ANDROID_PLATFORM_VIEW_ANDROID_JNI_IMPL_H_
#include "flutter/fml/platform/android/jni_weak_ref.h"
#include "flutter/shell/platform/android/jni/platform_view_android_jni.h"
namespace flutter {
//------------------------------------------------------------------------------
/// @brief Concrete implementation of `PlatformViewAndroidJNI` that is
/// compiled with the Android toolchain.
///
class PlatformViewAndroidJNIImpl final : public PlatformViewAndroidJNI {
public:
PlatformViewAndroidJNIImpl(fml::jni::JavaObjectWeakGlobalRef java_object);
~PlatformViewAndroidJNIImpl() override;
void FlutterViewHandlePlatformMessage(
fml::RefPtr<flutter::PlatformMessage> message,
int responseId) override;
void FlutterViewHandlePlatformMessageResponse(
int responseId,
std::unique_ptr<fml::Mapping> data) override;
void FlutterViewUpdateSemantics(std::vector<uint8_t> buffer,
std::vector<std::string> strings) override;
void FlutterViewUpdateCustomAccessibilityActions(
std::vector<uint8_t> actions_buffer,
std::vector<std::string> strings) override;
void FlutterViewOnFirstFrame() override;
void FlutterViewOnPreEngineRestart() override;
void SurfaceTextureAttachToGLContext(JavaWeakGlobalRef surface_texture,
int textureId) override;
void SurfaceTextureUpdateTexImage(JavaWeakGlobalRef surface_texture) override;
void SurfaceTextureGetTransformMatrix(JavaWeakGlobalRef surface_texture,
SkMatrix& transform) override;
void SurfaceTextureDetachFromGLContext(
JavaWeakGlobalRef surface_texture) override;
void FlutterViewOnDisplayPlatformView(int view_id,
int x,
int y,
int width,
int height) override;
void FlutterViewDisplayOverlaySurface(int surface_id,
int x,
int y,
int width,
int height) override;
private:
// Reference to FlutterJNI object.
const fml::jni::JavaObjectWeakGlobalRef java_object_;
FML_DISALLOW_COPY_AND_ASSIGN(PlatformViewAndroidJNIImpl);
};
} // namespace flutter
#endif // FLUTTER_SHELL_PLATFORM_ANDROID_PLATFORM_VIEW_ANDROID_JNI_IMPL_H_
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册