Flutter Engine
The Flutter Engine
Loading...
Searching...
No Matches
Namespaces | Macros | Functions | Variables
platform_view_android_jni_impl.cc File Reference
#include "flutter/shell/platform/android/platform_view_android_jni_impl.h"
#include <android/hardware_buffer_jni.h>
#include <android/native_window_jni.h>
#include <dlfcn.h>
#include <jni.h>
#include <memory>
#include <sstream>
#include <utility>
#include "include/android/SkImageAndroid.h"
#include "unicode/uchar.h"
#include "flutter/assets/directory_asset_bundle.h"
#include "flutter/common/constants.h"
#include "flutter/fml/file.h"
#include "flutter/fml/mapping.h"
#include "flutter/fml/native_library.h"
#include "flutter/fml/platform/android/jni_util.h"
#include "flutter/fml/platform/android/jni_weak_ref.h"
#include "flutter/fml/platform/android/scoped_java_ref.h"
#include "flutter/fml/size.h"
#include "flutter/lib/ui/plugins/callback_cache.h"
#include "flutter/runtime/dart_service_isolate.h"
#include "flutter/shell/common/run_configuration.h"
#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/image_external_texture_gl.h"
#include "flutter/shell/platform/android/jni/platform_view_android_jni.h"
#include "flutter/shell/platform/android/platform_view_android.h"
#include "flutter/shell/platform/android/surface_texture_external_texture_gl.h"

Go to the source code of this file.

Namespaces

namespace  flutter
 

Macros

#define ANDROID_SHELL_HOLDER    (reinterpret_cast<AndroidShellHolder*>(shell_holder))
 

Functions

jobject flutter::CreateFlutterCallbackInformation (JNIEnv *env, const std::string &callbackName, const std::string &callbackClassName, const std::string &callbackLibraryPath)
 
static jlong flutter::AttachJNI (JNIEnv *env, jclass clazz, jobject flutterJNI)
 
static void flutter::DestroyJNI (JNIEnv *env, jobject jcaller, jlong shell_holder)
 
static jobject flutter::SpawnJNI (JNIEnv *env, jobject jcaller, jlong shell_holder, jstring jEntrypoint, jstring jLibraryUrl, jstring jInitialRoute, jobject jEntrypointArgs)
 
static void flutter::SurfaceCreated (JNIEnv *env, jobject jcaller, jlong shell_holder, jobject jsurface)
 
static void flutter::SurfaceWindowChanged (JNIEnv *env, jobject jcaller, jlong shell_holder, jobject jsurface)
 
static void flutter::SurfaceChanged (JNIEnv *env, jobject jcaller, jlong shell_holder, jint width, jint height)
 
static void flutter::SurfaceDestroyed (JNIEnv *env, jobject jcaller, jlong shell_holder)
 
static void flutter::RunBundleAndSnapshotFromLibrary (JNIEnv *env, jobject jcaller, jlong shell_holder, jstring jBundlePath, jstring jEntrypoint, jstring jLibraryUrl, jobject jAssetManager, jobject jEntrypointArgs)
 
static jobject flutter::LookupCallbackInformation (JNIEnv *env, jobject, jlong handle)
 
static void flutter::SetViewportMetrics (JNIEnv *env, jobject jcaller, jlong shell_holder, jfloat devicePixelRatio, jint physicalWidth, jint physicalHeight, jint physicalPaddingTop, jint physicalPaddingRight, jint physicalPaddingBottom, jint physicalPaddingLeft, jint physicalViewInsetTop, jint physicalViewInsetRight, jint physicalViewInsetBottom, jint physicalViewInsetLeft, jint systemGestureInsetTop, jint systemGestureInsetRight, jint systemGestureInsetBottom, jint systemGestureInsetLeft, jint physicalTouchSlop, jintArray javaDisplayFeaturesBounds, jintArray javaDisplayFeaturesType, jintArray javaDisplayFeaturesState)
 
static void flutter::UpdateDisplayMetrics (JNIEnv *env, jobject jcaller, jlong shell_holder)
 
static jobject flutter::GetBitmap (JNIEnv *env, jobject jcaller, jlong shell_holder)
 
static void flutter::DispatchPlatformMessage (JNIEnv *env, jobject jcaller, jlong shell_holder, jstring channel, jobject message, jint position, jint responseId)
 
static void flutter::DispatchEmptyPlatformMessage (JNIEnv *env, jobject jcaller, jlong shell_holder, jstring channel, jint responseId)
 
static void flutter::CleanupMessageData (JNIEnv *env, jobject jcaller, jlong message_data)
 
static void flutter::DispatchPointerDataPacket (JNIEnv *env, jobject jcaller, jlong shell_holder, jobject buffer, jint position)
 
static void flutter::DispatchSemanticsAction (JNIEnv *env, jobject jcaller, jlong shell_holder, jint id, jint action, jobject args, jint args_position)
 
static void flutter::SetSemanticsEnabled (JNIEnv *env, jobject jcaller, jlong shell_holder, jboolean enabled)
 
static void flutter::SetAccessibilityFeatures (JNIEnv *env, jobject jcaller, jlong shell_holder, jint flags)
 
static jboolean flutter::GetIsSoftwareRendering (JNIEnv *env, jobject jcaller)
 
static void flutter::RegisterTexture (JNIEnv *env, jobject jcaller, jlong shell_holder, jlong texture_id, jobject surface_texture)
 
static void flutter::RegisterImageTexture (JNIEnv *env, jobject jcaller, jlong shell_holder, jlong texture_id, jobject image_texture_entry)
 
static void flutter::UnregisterTexture (JNIEnv *env, jobject jcaller, jlong shell_holder, jlong texture_id)
 
static void flutter::MarkTextureFrameAvailable (JNIEnv *env, jobject jcaller, jlong shell_holder, jlong texture_id)
 
static void flutter::ScheduleFrame (JNIEnv *env, jobject jcaller, jlong shell_holder)
 
static void flutter::InvokePlatformMessageResponseCallback (JNIEnv *env, jobject jcaller, jlong shell_holder, jint responseId, jobject message, jint position)
 
static void flutter::InvokePlatformMessageEmptyResponseCallback (JNIEnv *env, jobject jcaller, jlong shell_holder, jint responseId)
 
static void flutter::NotifyLowMemoryWarning (JNIEnv *env, jobject obj, jlong shell_holder)
 
static jboolean flutter::FlutterTextUtilsIsEmoji (JNIEnv *env, jobject obj, jint codePoint)
 
static jboolean flutter::FlutterTextUtilsIsEmojiModifier (JNIEnv *env, jobject obj, jint codePoint)
 
static jboolean flutter::FlutterTextUtilsIsEmojiModifierBase (JNIEnv *env, jobject obj, jint codePoint)
 
static jboolean flutter::FlutterTextUtilsIsVariationSelector (JNIEnv *env, jobject obj, jint codePoint)
 
static jboolean flutter::FlutterTextUtilsIsRegionalIndicator (JNIEnv *env, jobject obj, jint codePoint)
 
static void flutter::LoadLoadingUnitFailure (intptr_t loading_unit_id, const std::string &message, bool transient)
 
static void flutter::DeferredComponentInstallFailure (JNIEnv *env, jobject obj, jint jLoadingUnitId, jstring jError, jboolean jTransient)
 
static void flutter::LoadDartDeferredLibrary (JNIEnv *env, jobject obj, jlong shell_holder, jint jLoadingUnitId, jobjectArray jSearchPaths)
 
static void flutter::UpdateJavaAssetManager (JNIEnv *env, jobject obj, jlong shell_holder, jobject jAssetManager, jstring jAssetBundlePath)
 
bool flutter::RegisterApi (JNIEnv *env)
 

Variables

static fml::jni::ScopedJavaGlobalRef< jclass > * flutter::g_flutter_callback_info_class
 
static fml::jni::ScopedJavaGlobalRef< jclass > * flutter::g_flutter_jni_class = nullptr
 
static fml::jni::ScopedJavaGlobalRef< jclass > * flutter::g_java_weak_reference_class
 
static fml::jni::ScopedJavaGlobalRef< jclass > * flutter::g_texture_wrapper_class = nullptr
 
static fml::jni::ScopedJavaGlobalRef< jclass > * flutter::g_image_consumer_texture_registry_interface = nullptr
 
static fml::jni::ScopedJavaGlobalRef< jclass > * flutter::g_image_class = nullptr
 
static fml::jni::ScopedJavaGlobalRef< jclass > * flutter::g_hardware_buffer_class = nullptr
 
static fml::jni::ScopedJavaGlobalRef< jclass > * flutter::g_java_long_class = nullptr
 
static fml::jni::ScopedJavaGlobalRef< jclass > * flutter::g_bitmap_class = nullptr
 
static fml::jni::ScopedJavaGlobalRef< jclass > * flutter::g_bitmap_config_class = nullptr
 
static jmethodID flutter::g_flutter_callback_info_constructor = nullptr
 
static jfieldID flutter::g_jni_shell_holder_field = nullptr
 
static jmethodID flutter::g_jni_constructor = nullptr
 
static jmethodID flutter::g_long_constructor = nullptr
 
static jmethodID flutter::g_handle_platform_message_method = nullptr
 
static jmethodID flutter::g_handle_platform_message_response_method = nullptr
 
static jmethodID flutter::g_update_semantics_method = nullptr
 
static jmethodID flutter::g_update_custom_accessibility_actions_method = nullptr
 
static jmethodID flutter::g_get_scaled_font_size_method = nullptr
 
static jmethodID flutter::g_on_first_frame_method = nullptr
 
static jmethodID flutter::g_on_engine_restart_method = nullptr
 
static jmethodID flutter::g_create_overlay_surface_method = nullptr
 
static jmethodID flutter::g_destroy_overlay_surfaces_method = nullptr
 
static jmethodID flutter::g_on_begin_frame_method = nullptr
 
static jmethodID flutter::g_on_end_frame_method = nullptr
 
static jmethodID flutter::g_java_weak_reference_get_method = nullptr
 
static jmethodID flutter::g_attach_to_gl_context_method = nullptr
 
static jmethodID flutter::g_surface_texture_wrapper_should_update = nullptr
 
static jmethodID flutter::g_update_tex_image_method = nullptr
 
static jmethodID flutter::g_get_transform_matrix_method = nullptr
 
static jmethodID flutter::g_detach_from_gl_context_method = nullptr
 
static jmethodID flutter::g_acquire_latest_image_method = nullptr
 
static jmethodID flutter::g_image_get_hardware_buffer_method = nullptr
 
static jmethodID flutter::g_image_close_method = nullptr
 
static jmethodID flutter::g_hardware_buffer_close_method = nullptr
 
static jmethodID flutter::g_compute_platform_resolved_locale_method = nullptr
 
static jmethodID flutter::g_request_dart_deferred_library_method = nullptr
 
static jmethodID flutter::g_on_display_platform_view_method = nullptr
 
static jmethodID flutter::g_on_display_overlay_surface_method = nullptr
 
static jmethodID flutter::g_overlay_surface_id_method = nullptr
 
static jmethodID flutter::g_overlay_surface_surface_method = nullptr
 
static jmethodID flutter::g_bitmap_create_bitmap_method = nullptr
 
static jmethodID flutter::g_bitmap_copy_pixels_from_buffer_method = nullptr
 
static jmethodID flutter::g_bitmap_config_value_of = nullptr
 
static fml::jni::ScopedJavaGlobalRef< jclass > * flutter::g_mutators_stack_class = nullptr
 
static jmethodID flutter::g_mutators_stack_init_method = nullptr
 
static jmethodID flutter::g_mutators_stack_push_transform_method = nullptr
 
static jmethodID flutter::g_mutators_stack_push_cliprect_method = nullptr
 
static jmethodID flutter::g_mutators_stack_push_cliprrect_method = nullptr
 

Macro Definition Documentation

◆ ANDROID_SHELL_HOLDER

#define ANDROID_SHELL_HOLDER    (reinterpret_cast<AndroidShellHolder*>(shell_holder))

Definition at line 38 of file platform_view_android_jni_impl.cc.

40 {
41
43 nullptr;
44
46
48 nullptr;
49
51
54
56
58
60
62
64
65// Called By Native
66
67static jmethodID g_flutter_callback_info_constructor = nullptr;
69 JNIEnv* env,
70 const std::string& callbackName,
71 const std::string& callbackClassName,
72 const std::string& callbackLibraryPath) {
73 return env->NewObject(g_flutter_callback_info_class->obj(),
74 g_flutter_callback_info_constructor,
75 env->NewStringUTF(callbackName.c_str()),
76 env->NewStringUTF(callbackClassName.c_str()),
77 env->NewStringUTF(callbackLibraryPath.c_str()));
78}
79
80static jfieldID g_jni_shell_holder_field = nullptr;
81
82static jmethodID g_jni_constructor = nullptr;
83
84static jmethodID g_long_constructor = nullptr;
85
86static jmethodID g_handle_platform_message_method = nullptr;
87
88static jmethodID g_handle_platform_message_response_method = nullptr;
89
90static jmethodID g_update_semantics_method = nullptr;
91
92static jmethodID g_update_custom_accessibility_actions_method = nullptr;
93
94static jmethodID g_get_scaled_font_size_method = nullptr;
95
96static jmethodID g_on_first_frame_method = nullptr;
97
98static jmethodID g_on_engine_restart_method = nullptr;
99
100static jmethodID g_create_overlay_surface_method = nullptr;
101
102static jmethodID g_destroy_overlay_surfaces_method = nullptr;
103
104static jmethodID g_on_begin_frame_method = nullptr;
105
106static jmethodID g_on_end_frame_method = nullptr;
107
108static jmethodID g_java_weak_reference_get_method = nullptr;
109
110static jmethodID g_attach_to_gl_context_method = nullptr;
111
112static jmethodID g_surface_texture_wrapper_should_update = nullptr;
113
114static jmethodID g_update_tex_image_method = nullptr;
115
116static jmethodID g_get_transform_matrix_method = nullptr;
117
118static jmethodID g_detach_from_gl_context_method = nullptr;
119
120static jmethodID g_acquire_latest_image_method = nullptr;
121
122static jmethodID g_image_get_hardware_buffer_method = nullptr;
123
124static jmethodID g_image_close_method = nullptr;
125
126static jmethodID g_hardware_buffer_close_method = nullptr;
127
128static jmethodID g_compute_platform_resolved_locale_method = nullptr;
129
130static jmethodID g_request_dart_deferred_library_method = nullptr;
131
132// Called By Java
133static jmethodID g_on_display_platform_view_method = nullptr;
134
135// static jmethodID g_on_composite_platform_view_method = nullptr;
136
137static jmethodID g_on_display_overlay_surface_method = nullptr;
138
139static jmethodID g_overlay_surface_id_method = nullptr;
140
141static jmethodID g_overlay_surface_surface_method = nullptr;
142
143static jmethodID g_bitmap_create_bitmap_method = nullptr;
144
145static jmethodID g_bitmap_copy_pixels_from_buffer_method = nullptr;
146
147static jmethodID g_bitmap_config_value_of = nullptr;
148
149// Mutators
151static jmethodID g_mutators_stack_init_method = nullptr;
152static jmethodID g_mutators_stack_push_transform_method = nullptr;
153static jmethodID g_mutators_stack_push_cliprect_method = nullptr;
154static jmethodID g_mutators_stack_push_cliprrect_method = nullptr;
155
156// Called By Java
157static jlong AttachJNI(JNIEnv* env, jclass clazz, jobject flutterJNI) {
158 fml::jni::JavaObjectWeakGlobalRef java_object(env, flutterJNI);
159 std::shared_ptr<PlatformViewAndroidJNI> jni_facade =
160 std::make_shared<PlatformViewAndroidJNIImpl>(java_object);
161 auto shell_holder = std::make_unique<AndroidShellHolder>(
162 FlutterMain::Get().GetSettings(), jni_facade);
163 if (shell_holder->IsValid()) {
164 return reinterpret_cast<jlong>(shell_holder.release());
165 } else {
166 return 0;
167 }
168}
169
170static void DestroyJNI(JNIEnv* env, jobject jcaller, jlong shell_holder) {
172}
173
174// Signature is similar to RunBundleAndSnapshotFromLibrary but it can't change
175// the bundle path or asset manager since we can only spawn with the same
176// AOT.
177//
178// The shell_holder instance must be a pointer address to the current
179// AndroidShellHolder whose Shell will be used to spawn a new Shell.
180//
181// This creates a Java Long that points to the newly created
182// AndroidShellHolder's raw pointer, connects that Long to a newly created
183// FlutterJNI instance, then returns the FlutterJNI instance.
184static jobject SpawnJNI(JNIEnv* env,
185 jobject jcaller,
186 jlong shell_holder,
187 jstring jEntrypoint,
188 jstring jLibraryUrl,
189 jstring jInitialRoute,
190 jobject jEntrypointArgs) {
191 jobject jni = env->NewObject(g_flutter_jni_class->obj(), g_jni_constructor);
192 if (jni == nullptr) {
193 FML_LOG(ERROR) << "Could not create a FlutterJNI instance";
194 return nullptr;
195 }
196
198 std::shared_ptr<PlatformViewAndroidJNI> jni_facade =
199 std::make_shared<PlatformViewAndroidJNIImpl>(java_jni);
200
201 auto entrypoint = fml::jni::JavaStringToString(env, jEntrypoint);
202 auto libraryUrl = fml::jni::JavaStringToString(env, jLibraryUrl);
203 auto initial_route = fml::jni::JavaStringToString(env, jInitialRoute);
204 auto entrypoint_args = fml::jni::StringListToVector(env, jEntrypointArgs);
205
206 auto spawned_shell_holder = ANDROID_SHELL_HOLDER->Spawn(
207 jni_facade, entrypoint, libraryUrl, initial_route, entrypoint_args);
208
209 if (spawned_shell_holder == nullptr || !spawned_shell_holder->IsValid()) {
210 FML_LOG(ERROR) << "Could not spawn Shell";
211 return nullptr;
212 }
213
214 jobject javaLong = env->CallStaticObjectMethod(
215 g_java_long_class->obj(), g_long_constructor,
216 reinterpret_cast<jlong>(spawned_shell_holder.release()));
217 if (javaLong == nullptr) {
218 FML_LOG(ERROR) << "Could not create a Long instance";
219 return nullptr;
220 }
221
222 env->SetObjectField(jni, g_jni_shell_holder_field, javaLong);
223
224 return jni;
225}
226
227static void SurfaceCreated(JNIEnv* env,
228 jobject jcaller,
229 jlong shell_holder,
230 jobject jsurface) {
231 // Note: This frame ensures that any local references used by
232 // ANativeWindow_fromSurface are released immediately. This is needed as a
233 // workaround for https://code.google.com/p/android/issues/detail?id=68174
234 fml::jni::ScopedJavaLocalFrame scoped_local_reference_frame(env);
235 auto window = fml::MakeRefCounted<AndroidNativeWindow>(
236 ANativeWindow_fromSurface(env, jsurface));
237 ANDROID_SHELL_HOLDER->GetPlatformView()->NotifyCreated(std::move(window));
238}
239
240static void SurfaceWindowChanged(JNIEnv* env,
241 jobject jcaller,
242 jlong shell_holder,
243 jobject jsurface) {
244 // Note: This frame ensures that any local references used by
245 // ANativeWindow_fromSurface are released immediately. This is needed as a
246 // workaround for https://code.google.com/p/android/issues/detail?id=68174
247 fml::jni::ScopedJavaLocalFrame scoped_local_reference_frame(env);
248 auto window = fml::MakeRefCounted<AndroidNativeWindow>(
249 ANativeWindow_fromSurface(env, jsurface));
250 ANDROID_SHELL_HOLDER->GetPlatformView()->NotifySurfaceWindowChanged(
251 std::move(window));
252}
253
254static void SurfaceChanged(JNIEnv* env,
255 jobject jcaller,
256 jlong shell_holder,
257 jint width,
258 jint height) {
259 ANDROID_SHELL_HOLDER->GetPlatformView()->NotifyChanged(
261}
262
263static void SurfaceDestroyed(JNIEnv* env, jobject jcaller, jlong shell_holder) {
264 ANDROID_SHELL_HOLDER->GetPlatformView()->NotifyDestroyed();
265}
266
267static void RunBundleAndSnapshotFromLibrary(JNIEnv* env,
268 jobject jcaller,
269 jlong shell_holder,
270 jstring jBundlePath,
271 jstring jEntrypoint,
272 jstring jLibraryUrl,
273 jobject jAssetManager,
274 jobject jEntrypointArgs) {
275 auto apk_asset_provider = std::make_unique<flutter::APKAssetProvider>(
276 env, // jni environment
277 jAssetManager, // asset manager
278 fml::jni::JavaStringToString(env, jBundlePath) // apk asset dir
279 );
280 auto entrypoint = fml::jni::JavaStringToString(env, jEntrypoint);
281 auto libraryUrl = fml::jni::JavaStringToString(env, jLibraryUrl);
282 auto entrypoint_args = fml::jni::StringListToVector(env, jEntrypointArgs);
283
284 ANDROID_SHELL_HOLDER->Launch(std::move(apk_asset_provider), entrypoint,
285 libraryUrl, entrypoint_args);
286}
287
288static jobject LookupCallbackInformation(JNIEnv* env,
289 /* unused */ jobject,
290 jlong handle) {
292 if (cbInfo == nullptr) {
293 return nullptr;
294 }
295 return CreateFlutterCallbackInformation(env, cbInfo->name, cbInfo->class_name,
296 cbInfo->library_path);
297}
298
299static void SetViewportMetrics(JNIEnv* env,
300 jobject jcaller,
301 jlong shell_holder,
302 jfloat devicePixelRatio,
303 jint physicalWidth,
304 jint physicalHeight,
305 jint physicalPaddingTop,
306 jint physicalPaddingRight,
307 jint physicalPaddingBottom,
308 jint physicalPaddingLeft,
309 jint physicalViewInsetTop,
310 jint physicalViewInsetRight,
311 jint physicalViewInsetBottom,
312 jint physicalViewInsetLeft,
313 jint systemGestureInsetTop,
314 jint systemGestureInsetRight,
315 jint systemGestureInsetBottom,
316 jint systemGestureInsetLeft,
317 jint physicalTouchSlop,
318 jintArray javaDisplayFeaturesBounds,
319 jintArray javaDisplayFeaturesType,
320 jintArray javaDisplayFeaturesState) {
321 // Convert java->c++. javaDisplayFeaturesBounds, javaDisplayFeaturesType and
322 // javaDisplayFeaturesState cannot be null
323 jsize rectSize = env->GetArrayLength(javaDisplayFeaturesBounds);
324 std::vector<int> boundsIntVector(rectSize);
325 env->GetIntArrayRegion(javaDisplayFeaturesBounds, 0, rectSize,
326 &boundsIntVector[0]);
327 std::vector<double> displayFeaturesBounds(boundsIntVector.begin(),
328 boundsIntVector.end());
329 jsize typeSize = env->GetArrayLength(javaDisplayFeaturesType);
330 std::vector<int> displayFeaturesType(typeSize);
331 env->GetIntArrayRegion(javaDisplayFeaturesType, 0, typeSize,
332 &displayFeaturesType[0]);
333
334 jsize stateSize = env->GetArrayLength(javaDisplayFeaturesState);
335 std::vector<int> displayFeaturesState(stateSize);
336 env->GetIntArrayRegion(javaDisplayFeaturesState, 0, stateSize,
337 &displayFeaturesState[0]);
338
339 const flutter::ViewportMetrics metrics{
340 static_cast<double>(devicePixelRatio),
341 static_cast<double>(physicalWidth),
342 static_cast<double>(physicalHeight),
343 static_cast<double>(physicalPaddingTop),
344 static_cast<double>(physicalPaddingRight),
345 static_cast<double>(physicalPaddingBottom),
346 static_cast<double>(physicalPaddingLeft),
347 static_cast<double>(physicalViewInsetTop),
348 static_cast<double>(physicalViewInsetRight),
349 static_cast<double>(physicalViewInsetBottom),
350 static_cast<double>(physicalViewInsetLeft),
351 static_cast<double>(systemGestureInsetTop),
352 static_cast<double>(systemGestureInsetRight),
353 static_cast<double>(systemGestureInsetBottom),
354 static_cast<double>(systemGestureInsetLeft),
355 static_cast<double>(physicalTouchSlop),
356 displayFeaturesBounds,
357 displayFeaturesType,
358 displayFeaturesState,
359 0, // Display ID
360 };
361
362 ANDROID_SHELL_HOLDER->GetPlatformView()->SetViewportMetrics(
363 kFlutterImplicitViewId, metrics);
364}
365
366static void UpdateDisplayMetrics(JNIEnv* env,
367 jobject jcaller,
368 jlong shell_holder) {
369 ANDROID_SHELL_HOLDER->UpdateDisplayMetrics();
370}
371
372static jobject GetBitmap(JNIEnv* env, jobject jcaller, jlong shell_holder) {
373 auto screenshot = ANDROID_SHELL_HOLDER->Screenshot(
374 Rasterizer::ScreenshotType::UncompressedImage, false);
375 if (screenshot.data == nullptr) {
376 return nullptr;
377 }
378
379 jstring argb = env->NewStringUTF("ARGB_8888");
380 if (argb == nullptr) {
381 return nullptr;
382 }
383
384 jobject bitmap_config = env->CallStaticObjectMethod(
385 g_bitmap_config_class->obj(), g_bitmap_config_value_of, argb);
386 if (bitmap_config == nullptr) {
387 return nullptr;
388 }
389
390 auto bitmap = env->CallStaticObjectMethod(
391 g_bitmap_class->obj(), g_bitmap_create_bitmap_method,
392 screenshot.frame_size.width(), screenshot.frame_size.height(),
393 bitmap_config);
394
396 env,
397 env->NewDirectByteBuffer(const_cast<uint8_t*>(screenshot.data->bytes()),
398 screenshot.data->size()));
399
400 env->CallVoidMethod(bitmap, g_bitmap_copy_pixels_from_buffer_method,
401 buffer.obj());
402
403 return bitmap;
404}
405
406static void DispatchPlatformMessage(JNIEnv* env,
407 jobject jcaller,
408 jlong shell_holder,
409 jstring channel,
410 jobject message,
411 jint position,
412 jint responseId) {
413 ANDROID_SHELL_HOLDER->GetPlatformView()->DispatchPlatformMessage(
414 env, //
416 message, //
417 position, //
418 responseId //
419 );
420}
421
422static void DispatchEmptyPlatformMessage(JNIEnv* env,
423 jobject jcaller,
424 jlong shell_holder,
425 jstring channel,
426 jint responseId) {
427 ANDROID_SHELL_HOLDER->GetPlatformView()->DispatchEmptyPlatformMessage(
428 env, //
430 responseId //
431 );
432}
433
434static void CleanupMessageData(JNIEnv* env,
435 jobject jcaller,
436 jlong message_data) {
437 // Called from any thread.
438 free(reinterpret_cast<void*>(message_data));
439}
440
441static void DispatchPointerDataPacket(JNIEnv* env,
442 jobject jcaller,
443 jlong shell_holder,
444 jobject buffer,
445 jint position) {
446 uint8_t* data = static_cast<uint8_t*>(env->GetDirectBufferAddress(buffer));
447 auto packet = std::make_unique<flutter::PointerDataPacket>(data, position);
448 ANDROID_SHELL_HOLDER->GetPlatformView()->DispatchPointerDataPacket(
449 std::move(packet));
450}
451
452static void DispatchSemanticsAction(JNIEnv* env,
453 jobject jcaller,
454 jlong shell_holder,
455 jint id,
456 jint action,
457 jobject args,
458 jint args_position) {
459 ANDROID_SHELL_HOLDER->GetPlatformView()->DispatchSemanticsAction(
460 env, //
461 id, //
462 action, //
463 args, //
464 args_position //
465 );
466}
467
468static void SetSemanticsEnabled(JNIEnv* env,
469 jobject jcaller,
470 jlong shell_holder,
471 jboolean enabled) {
472 ANDROID_SHELL_HOLDER->GetPlatformView()->SetSemanticsEnabled(enabled);
473}
474
475static void SetAccessibilityFeatures(JNIEnv* env,
476 jobject jcaller,
477 jlong shell_holder,
478 jint flags) {
479 ANDROID_SHELL_HOLDER->GetPlatformView()->SetAccessibilityFeatures(flags);
480}
481
482static jboolean GetIsSoftwareRendering(JNIEnv* env, jobject jcaller) {
483 return FlutterMain::Get().GetSettings().enable_software_rendering;
484}
485
486static void RegisterTexture(JNIEnv* env,
487 jobject jcaller,
488 jlong shell_holder,
489 jlong texture_id,
490 jobject surface_texture) {
491 ANDROID_SHELL_HOLDER->GetPlatformView()->RegisterExternalTexture(
492 static_cast<int64_t>(texture_id), //
494 );
495}
496
497static void RegisterImageTexture(JNIEnv* env,
498 jobject jcaller,
499 jlong shell_holder,
500 jlong texture_id,
501 jobject image_texture_entry) {
502 ANDROID_SHELL_HOLDER->GetPlatformView()->RegisterImageTexture(
503 static_cast<int64_t>(texture_id), //
504 fml::jni::ScopedJavaGlobalRef<jobject>(env, image_texture_entry) //
505 );
506}
507
508static void UnregisterTexture(JNIEnv* env,
509 jobject jcaller,
510 jlong shell_holder,
511 jlong texture_id) {
512 ANDROID_SHELL_HOLDER->GetPlatformView()->UnregisterTexture(
513 static_cast<int64_t>(texture_id));
514}
515
516static void MarkTextureFrameAvailable(JNIEnv* env,
517 jobject jcaller,
518 jlong shell_holder,
519 jlong texture_id) {
520 ANDROID_SHELL_HOLDER->GetPlatformView()->MarkTextureFrameAvailable(
521 static_cast<int64_t>(texture_id));
522}
523
524static void ScheduleFrame(JNIEnv* env, jobject jcaller, jlong shell_holder) {
525 ANDROID_SHELL_HOLDER->GetPlatformView()->ScheduleFrame();
526}
527
529 jobject jcaller,
530 jlong shell_holder,
531 jint responseId,
532 jobject message,
533 jint position) {
534 uint8_t* response_data =
535 static_cast<uint8_t*>(env->GetDirectBufferAddress(message));
536 FML_DCHECK(response_data != nullptr);
537 auto mapping = std::make_unique<fml::MallocMapping>(
538 fml::MallocMapping::Copy(response_data, response_data + position));
539 ANDROID_SHELL_HOLDER->GetPlatformMessageHandler()
540 ->InvokePlatformMessageResponseCallback(responseId, std::move(mapping));
541}
542
544 jobject jcaller,
545 jlong shell_holder,
546 jint responseId) {
547 ANDROID_SHELL_HOLDER->GetPlatformMessageHandler()
548 ->InvokePlatformMessageEmptyResponseCallback(responseId);
549}
550
551static void NotifyLowMemoryWarning(JNIEnv* env,
552 jobject obj,
553 jlong shell_holder) {
554 ANDROID_SHELL_HOLDER->NotifyLowMemoryWarning();
555}
556
557static jboolean FlutterTextUtilsIsEmoji(JNIEnv* env,
558 jobject obj,
559 jint codePoint) {
560 return u_hasBinaryProperty(codePoint, UProperty::UCHAR_EMOJI);
561}
562
563static jboolean FlutterTextUtilsIsEmojiModifier(JNIEnv* env,
564 jobject obj,
565 jint codePoint) {
566 return u_hasBinaryProperty(codePoint, UProperty::UCHAR_EMOJI_MODIFIER);
567}
568
569static jboolean FlutterTextUtilsIsEmojiModifierBase(JNIEnv* env,
570 jobject obj,
571 jint codePoint) {
572 return u_hasBinaryProperty(codePoint, UProperty::UCHAR_EMOJI_MODIFIER_BASE);
573}
574
575static jboolean FlutterTextUtilsIsVariationSelector(JNIEnv* env,
576 jobject obj,
577 jint codePoint) {
578 return u_hasBinaryProperty(codePoint, UProperty::UCHAR_VARIATION_SELECTOR);
579}
580
581static jboolean FlutterTextUtilsIsRegionalIndicator(JNIEnv* env,
582 jobject obj,
583 jint codePoint) {
584 return u_hasBinaryProperty(codePoint, UProperty::UCHAR_REGIONAL_INDICATOR);
585}
586
587static void LoadLoadingUnitFailure(intptr_t loading_unit_id,
588 const std::string& message,
589 bool transient) {
590 // TODO(garyq): Implement
591}
592
593static void DeferredComponentInstallFailure(JNIEnv* env,
594 jobject obj,
595 jint jLoadingUnitId,
596 jstring jError,
597 jboolean jTransient) {
598 LoadLoadingUnitFailure(static_cast<intptr_t>(jLoadingUnitId),
600 static_cast<bool>(jTransient));
601}
602
603static void LoadDartDeferredLibrary(JNIEnv* env,
604 jobject obj,
605 jlong shell_holder,
606 jint jLoadingUnitId,
607 jobjectArray jSearchPaths) {
608 // Convert java->c++
609 intptr_t loading_unit_id = static_cast<intptr_t>(jLoadingUnitId);
610 std::vector<std::string> search_paths =
611 fml::jni::StringArrayToVector(env, jSearchPaths);
612
613 // Use dlopen here to directly check if handle is nullptr before creating a
614 // NativeLibrary.
615 void* handle = nullptr;
616 while (handle == nullptr && !search_paths.empty()) {
617 std::string path = search_paths.back();
618 handle = ::dlopen(path.c_str(), RTLD_NOW);
619 search_paths.pop_back();
620 }
621 if (handle == nullptr) {
622 LoadLoadingUnitFailure(loading_unit_id,
623 "No lib .so found for provided search paths.", true);
624 return;
625 }
628
629 // Resolve symbols.
630 std::unique_ptr<const fml::SymbolMapping> data_mapping =
631 std::make_unique<const fml::SymbolMapping>(
632 native_lib, DartSnapshot::kIsolateDataSymbol);
633 std::unique_ptr<const fml::SymbolMapping> instructions_mapping =
634 std::make_unique<const fml::SymbolMapping>(
635 native_lib, DartSnapshot::kIsolateInstructionsSymbol);
636
637 ANDROID_SHELL_HOLDER->GetPlatformView()->LoadDartDeferredLibrary(
638 loading_unit_id, std::move(data_mapping),
639 std::move(instructions_mapping));
640}
641
642static void UpdateJavaAssetManager(JNIEnv* env,
643 jobject obj,
644 jlong shell_holder,
645 jobject jAssetManager,
646 jstring jAssetBundlePath) {
647 auto asset_resolver = std::make_unique<flutter::APKAssetProvider>(
648 env, // jni environment
649 jAssetManager, // asset manager
650 fml::jni::JavaStringToString(env, jAssetBundlePath)); // apk asset dir
651
652 ANDROID_SHELL_HOLDER->GetPlatformView()->UpdateAssetResolverByType(
653 std::move(asset_resolver),
654 AssetResolver::AssetResolverType::kApkAssetProvider);
655}
656
657bool RegisterApi(JNIEnv* env) {
658 static const JNINativeMethod flutter_jni_methods[] = {
659 // Start of methods from FlutterJNI
660 {
661 .name = "nativeAttach",
662 .signature = "(Lio/flutter/embedding/engine/FlutterJNI;)J",
663 .fnPtr = reinterpret_cast<void*>(&AttachJNI),
664 },
665 {
666 .name = "nativeDestroy",
667 .signature = "(J)V",
668 .fnPtr = reinterpret_cast<void*>(&DestroyJNI),
669 },
670 {
671 .name = "nativeSpawn",
672 .signature = "(JLjava/lang/String;Ljava/lang/String;Ljava/lang/"
673 "String;Ljava/util/List;)Lio/flutter/"
674 "embedding/engine/FlutterJNI;",
675 .fnPtr = reinterpret_cast<void*>(&SpawnJNI),
676 },
677 {
678 .name = "nativeRunBundleAndSnapshotFromLibrary",
679 .signature = "(JLjava/lang/String;Ljava/lang/String;"
680 "Ljava/lang/String;Landroid/content/res/"
681 "AssetManager;Ljava/util/List;)V",
682 .fnPtr = reinterpret_cast<void*>(&RunBundleAndSnapshotFromLibrary),
683 },
684 {
685 .name = "nativeDispatchEmptyPlatformMessage",
686 .signature = "(JLjava/lang/String;I)V",
687 .fnPtr = reinterpret_cast<void*>(&DispatchEmptyPlatformMessage),
688 },
689 {
690 .name = "nativeCleanupMessageData",
691 .signature = "(J)V",
692 .fnPtr = reinterpret_cast<void*>(&CleanupMessageData),
693 },
694 {
695 .name = "nativeDispatchPlatformMessage",
696 .signature = "(JLjava/lang/String;Ljava/nio/ByteBuffer;II)V",
697 .fnPtr = reinterpret_cast<void*>(&DispatchPlatformMessage),
698 },
699 {
700 .name = "nativeInvokePlatformMessageResponseCallback",
701 .signature = "(JILjava/nio/ByteBuffer;I)V",
702 .fnPtr =
703 reinterpret_cast<void*>(&InvokePlatformMessageResponseCallback),
704 },
705 {
706 .name = "nativeInvokePlatformMessageEmptyResponseCallback",
707 .signature = "(JI)V",
708 .fnPtr = reinterpret_cast<void*>(
710 },
711 {
712 .name = "nativeNotifyLowMemoryWarning",
713 .signature = "(J)V",
714 .fnPtr = reinterpret_cast<void*>(&NotifyLowMemoryWarning),
715 },
716
717 // Start of methods from FlutterView
718 {
719 .name = "nativeGetBitmap",
720 .signature = "(J)Landroid/graphics/Bitmap;",
721 .fnPtr = reinterpret_cast<void*>(&GetBitmap),
722 },
723 {
724 .name = "nativeSurfaceCreated",
725 .signature = "(JLandroid/view/Surface;)V",
726 .fnPtr = reinterpret_cast<void*>(&SurfaceCreated),
727 },
728 {
729 .name = "nativeSurfaceWindowChanged",
730 .signature = "(JLandroid/view/Surface;)V",
731 .fnPtr = reinterpret_cast<void*>(&SurfaceWindowChanged),
732 },
733 {
734 .name = "nativeSurfaceChanged",
735 .signature = "(JII)V",
736 .fnPtr = reinterpret_cast<void*>(&SurfaceChanged),
737 },
738 {
739 .name = "nativeSurfaceDestroyed",
740 .signature = "(J)V",
741 .fnPtr = reinterpret_cast<void*>(&SurfaceDestroyed),
742 },
743 {
744 .name = "nativeSetViewportMetrics",
745 .signature = "(JFIIIIIIIIIIIIIII[I[I[I)V",
746 .fnPtr = reinterpret_cast<void*>(&SetViewportMetrics),
747 },
748 {
749 .name = "nativeDispatchPointerDataPacket",
750 .signature = "(JLjava/nio/ByteBuffer;I)V",
751 .fnPtr = reinterpret_cast<void*>(&DispatchPointerDataPacket),
752 },
753 {
754 .name = "nativeDispatchSemanticsAction",
755 .signature = "(JIILjava/nio/ByteBuffer;I)V",
756 .fnPtr = reinterpret_cast<void*>(&DispatchSemanticsAction),
757 },
758 {
759 .name = "nativeSetSemanticsEnabled",
760 .signature = "(JZ)V",
761 .fnPtr = reinterpret_cast<void*>(&SetSemanticsEnabled),
762 },
763 {
764 .name = "nativeSetAccessibilityFeatures",
765 .signature = "(JI)V",
766 .fnPtr = reinterpret_cast<void*>(&SetAccessibilityFeatures),
767 },
768 {
769 .name = "nativeGetIsSoftwareRenderingEnabled",
770 .signature = "()Z",
771 .fnPtr = reinterpret_cast<void*>(&GetIsSoftwareRendering),
772 },
773 {
774 .name = "nativeRegisterTexture",
775 .signature = "(JJLjava/lang/ref/"
776 "WeakReference;)V",
777 .fnPtr = reinterpret_cast<void*>(&RegisterTexture),
778 },
779 {
780 .name = "nativeRegisterImageTexture",
781 .signature = "(JJLjava/lang/ref/"
782 "WeakReference;)V",
783 .fnPtr = reinterpret_cast<void*>(&RegisterImageTexture),
784 },
785 {
786 .name = "nativeMarkTextureFrameAvailable",
787 .signature = "(JJ)V",
788 .fnPtr = reinterpret_cast<void*>(&MarkTextureFrameAvailable),
789 },
790 {
791 .name = "nativeScheduleFrame",
792 .signature = "(J)V",
793 .fnPtr = reinterpret_cast<void*>(&ScheduleFrame),
794 },
795 {
796 .name = "nativeUnregisterTexture",
797 .signature = "(JJ)V",
798 .fnPtr = reinterpret_cast<void*>(&UnregisterTexture),
799 },
800 // Methods for Dart callback functionality.
801 {
802 .name = "nativeLookupCallbackInformation",
803 .signature = "(J)Lio/flutter/view/FlutterCallbackInformation;",
804 .fnPtr = reinterpret_cast<void*>(&LookupCallbackInformation),
805 },
806
807 // Start of methods for FlutterTextUtils
808 {
809 .name = "nativeFlutterTextUtilsIsEmoji",
810 .signature = "(I)Z",
811 .fnPtr = reinterpret_cast<void*>(&FlutterTextUtilsIsEmoji),
812 },
813 {
814 .name = "nativeFlutterTextUtilsIsEmojiModifier",
815 .signature = "(I)Z",
816 .fnPtr = reinterpret_cast<void*>(&FlutterTextUtilsIsEmojiModifier),
817 },
818 {
819 .name = "nativeFlutterTextUtilsIsEmojiModifierBase",
820 .signature = "(I)Z",
821 .fnPtr =
822 reinterpret_cast<void*>(&FlutterTextUtilsIsEmojiModifierBase),
823 },
824 {
825 .name = "nativeFlutterTextUtilsIsVariationSelector",
826 .signature = "(I)Z",
827 .fnPtr =
828 reinterpret_cast<void*>(&FlutterTextUtilsIsVariationSelector),
829 },
830 {
831 .name = "nativeFlutterTextUtilsIsRegionalIndicator",
832 .signature = "(I)Z",
833 .fnPtr =
834 reinterpret_cast<void*>(&FlutterTextUtilsIsRegionalIndicator),
835 },
836 {
837 .name = "nativeLoadDartDeferredLibrary",
838 .signature = "(JI[Ljava/lang/String;)V",
839 .fnPtr = reinterpret_cast<void*>(&LoadDartDeferredLibrary),
840 },
841 {
842 .name = "nativeUpdateJavaAssetManager",
843 .signature =
844 "(JLandroid/content/res/AssetManager;Ljava/lang/String;)V",
845 .fnPtr = reinterpret_cast<void*>(&UpdateJavaAssetManager),
846 },
847 {
848 .name = "nativeDeferredComponentInstallFailure",
849 .signature = "(ILjava/lang/String;Z)V",
850 .fnPtr = reinterpret_cast<void*>(&DeferredComponentInstallFailure),
851 },
852 {
853 .name = "nativeUpdateDisplayMetrics",
854 .signature = "(J)V",
855 .fnPtr = reinterpret_cast<void*>(&UpdateDisplayMetrics),
856 },
857 };
858
859 if (env->RegisterNatives(g_flutter_jni_class->obj(), flutter_jni_methods,
860 fml::size(flutter_jni_methods)) != 0) {
861 FML_LOG(ERROR) << "Failed to RegisterNatives with FlutterJNI";
862 return false;
863 }
864
865 g_jni_shell_holder_field = env->GetFieldID(
866 g_flutter_jni_class->obj(), "nativeShellHolderId", "Ljava/lang/Long;");
867
868 if (g_jni_shell_holder_field == nullptr) {
869 FML_LOG(ERROR) << "Could not locate FlutterJNI's nativeShellHolderId field";
870 return false;
871 }
872
874 env->GetMethodID(g_flutter_jni_class->obj(), "<init>", "()V");
875
876 if (g_jni_constructor == nullptr) {
877 FML_LOG(ERROR) << "Could not locate FlutterJNI's constructor";
878 return false;
879 }
880
881 g_long_constructor = env->GetStaticMethodID(g_java_long_class->obj(),
882 "valueOf", "(J)Ljava/lang/Long;");
883 if (g_long_constructor == nullptr) {
884 FML_LOG(ERROR) << "Could not locate Long's constructor";
885 return false;
886 }
887
889 env->GetMethodID(g_flutter_jni_class->obj(), "handlePlatformMessage",
890 "(Ljava/lang/String;Ljava/nio/ByteBuffer;IJ)V");
891
892 if (g_handle_platform_message_method == nullptr) {
893 FML_LOG(ERROR) << "Could not locate handlePlatformMessage method";
894 return false;
895 }
896
898 g_flutter_jni_class->obj(), "handlePlatformMessageResponse",
899 "(ILjava/nio/ByteBuffer;)V");
900
901 if (g_handle_platform_message_response_method == nullptr) {
902 FML_LOG(ERROR) << "Could not locate handlePlatformMessageResponse method";
903 return false;
904 }
905
906 g_get_scaled_font_size_method = env->GetMethodID(
907 g_flutter_jni_class->obj(), "getScaledFontSize", "(FI)F");
908
909 if (g_get_scaled_font_size_method == nullptr) {
910 FML_LOG(ERROR) << "Could not locate FlutterJNI#getScaledFontSize method";
911 return false;
912 }
913
914 g_update_semantics_method = env->GetMethodID(
915 g_flutter_jni_class->obj(), "updateSemantics",
916 "(Ljava/nio/ByteBuffer;[Ljava/lang/String;[Ljava/nio/ByteBuffer;)V");
917
918 if (g_update_semantics_method == nullptr) {
919 FML_LOG(ERROR) << "Could not locate updateSemantics method";
920 return false;
921 }
922
924 g_flutter_jni_class->obj(), "updateCustomAccessibilityActions",
925 "(Ljava/nio/ByteBuffer;[Ljava/lang/String;)V");
926
927 if (g_update_custom_accessibility_actions_method == nullptr) {
929 << "Could not locate updateCustomAccessibilityActions method";
930 return false;
931 }
932
934 env->GetMethodID(g_flutter_jni_class->obj(), "onFirstFrame", "()V");
935
936 if (g_on_first_frame_method == nullptr) {
937 FML_LOG(ERROR) << "Could not locate onFirstFrame method";
938 return false;
939 }
940
942 env->GetMethodID(g_flutter_jni_class->obj(), "onPreEngineRestart", "()V");
943
944 if (g_on_engine_restart_method == nullptr) {
945 FML_LOG(ERROR) << "Could not locate onEngineRestart method";
946 return false;
947 }
948
950 env->GetMethodID(g_flutter_jni_class->obj(), "createOverlaySurface",
951 "()Lio/flutter/embedding/engine/FlutterOverlaySurface;");
952
953 if (g_create_overlay_surface_method == nullptr) {
954 FML_LOG(ERROR) << "Could not locate createOverlaySurface method";
955 return false;
956 }
957
959 g_flutter_jni_class->obj(), "destroyOverlaySurfaces", "()V");
960
961 if (g_destroy_overlay_surfaces_method == nullptr) {
962 FML_LOG(ERROR) << "Could not locate destroyOverlaySurfaces method";
963 return false;
964 }
965
966 fml::jni::ScopedJavaLocalRef<jclass> overlay_surface_class(
967 env, env->FindClass("io/flutter/embedding/engine/FlutterOverlaySurface"));
968 if (overlay_surface_class.is_null()) {
969 FML_LOG(ERROR) << "Could not locate FlutterOverlaySurface class";
970 return false;
971 }
973 env->GetMethodID(overlay_surface_class.obj(), "getId", "()I");
974 if (g_overlay_surface_id_method == nullptr) {
975 FML_LOG(ERROR) << "Could not locate FlutterOverlaySurface#getId() method";
976 return false;
977 }
979 overlay_surface_class.obj(), "getSurface", "()Landroid/view/Surface;");
980 if (g_overlay_surface_surface_method == nullptr) {
982 << "Could not locate FlutterOverlaySurface#getSurface() method";
983 return false;
984 }
985
987 env, env->FindClass("android/graphics/Bitmap"));
988 if (g_bitmap_class->is_null()) {
989 FML_LOG(ERROR) << "Could not locate Bitmap Class";
990 return false;
991 }
992
993 g_bitmap_create_bitmap_method = env->GetStaticMethodID(
994 g_bitmap_class->obj(), "createBitmap",
995 "(IILandroid/graphics/Bitmap$Config;)Landroid/graphics/Bitmap;");
996 if (g_bitmap_create_bitmap_method == nullptr) {
997 FML_LOG(ERROR) << "Could not locate Bitmap.createBitmap method";
998 return false;
999 }
1000
1002 g_bitmap_class->obj(), "copyPixelsFromBuffer", "(Ljava/nio/Buffer;)V");
1003 if (g_bitmap_copy_pixels_from_buffer_method == nullptr) {
1004 FML_LOG(ERROR) << "Could not locate Bitmap.copyPixelsFromBuffer method";
1005 return false;
1006 }
1007
1009 env, env->FindClass("android/graphics/Bitmap$Config"));
1010 if (g_bitmap_config_class->is_null()) {
1011 FML_LOG(ERROR) << "Could not locate Bitmap.Config Class";
1012 return false;
1013 }
1014
1015 g_bitmap_config_value_of = env->GetStaticMethodID(
1016 g_bitmap_config_class->obj(), "valueOf",
1017 "(Ljava/lang/String;)Landroid/graphics/Bitmap$Config;");
1018 if (g_bitmap_config_value_of == nullptr) {
1019 FML_LOG(ERROR) << "Could not locate Bitmap.Config.valueOf method";
1020 return false;
1021 }
1022
1023 return true;
1024}
1025
1026bool PlatformViewAndroid::Register(JNIEnv* env) {
1027 if (env == nullptr) {
1028 FML_LOG(ERROR) << "No JNIEnv provided";
1029 return false;
1030 }
1031
1033 env, env->FindClass("io/flutter/view/FlutterCallbackInformation"));
1034 if (g_flutter_callback_info_class->is_null()) {
1035 FML_LOG(ERROR) << "Could not locate FlutterCallbackInformation class";
1036 return false;
1037 }
1038
1040 g_flutter_callback_info_class->obj(), "<init>",
1041 "(Ljava/lang/String;Ljava/lang/String;Ljava/lang/String;)V");
1042 if (g_flutter_callback_info_constructor == nullptr) {
1043 FML_LOG(ERROR) << "Could not locate FlutterCallbackInformation constructor";
1044 return false;
1045 }
1046
1048 env, env->FindClass("io/flutter/embedding/engine/FlutterJNI"));
1049 if (g_flutter_jni_class->is_null()) {
1050 FML_LOG(ERROR) << "Failed to find FlutterJNI Class.";
1051 return false;
1052 }
1053
1055 env,
1056 env->FindClass(
1057 "io/flutter/embedding/engine/mutatorsstack/FlutterMutatorsStack"));
1058 if (g_mutators_stack_class == nullptr) {
1059 FML_LOG(ERROR) << "Could not locate FlutterMutatorsStack";
1060 return false;
1061 }
1062
1064 env->GetMethodID(g_mutators_stack_class->obj(), "<init>", "()V");
1065 if (g_mutators_stack_init_method == nullptr) {
1066 FML_LOG(ERROR) << "Could not locate FlutterMutatorsStack.init method";
1067 return false;
1068 }
1069
1071 env->GetMethodID(g_mutators_stack_class->obj(), "pushTransform", "([F)V");
1072 if (g_mutators_stack_push_transform_method == nullptr) {
1073 FML_LOG(ERROR)
1074 << "Could not locate FlutterMutatorsStack.pushTransform method";
1075 return false;
1076 }
1077
1079 g_mutators_stack_class->obj(), "pushClipRect", "(IIII)V");
1080 if (g_mutators_stack_push_cliprect_method == nullptr) {
1081 FML_LOG(ERROR)
1082 << "Could not locate FlutterMutatorsStack.pushClipRect method";
1083 return false;
1084 }
1085
1087 g_mutators_stack_class->obj(), "pushClipRRect", "(IIII[F)V");
1088 if (g_mutators_stack_push_cliprrect_method == nullptr) {
1089 FML_LOG(ERROR)
1090 << "Could not locate FlutterMutatorsStack.pushClipRRect method";
1091 return false;
1092 }
1093
1095 env->GetMethodID(g_flutter_jni_class->obj(), "onDisplayPlatformView",
1096 "(IIIIIIILio/flutter/embedding/engine/mutatorsstack/"
1097 "FlutterMutatorsStack;)V");
1098
1099 if (g_on_display_platform_view_method == nullptr) {
1100 FML_LOG(ERROR) << "Could not locate onDisplayPlatformView method";
1101 return false;
1102 }
1103
1105 env->GetMethodID(g_flutter_jni_class->obj(), "onBeginFrame", "()V");
1106
1107 if (g_on_begin_frame_method == nullptr) {
1108 FML_LOG(ERROR) << "Could not locate onBeginFrame method";
1109 return false;
1110 }
1111
1113 env->GetMethodID(g_flutter_jni_class->obj(), "onEndFrame", "()V");
1114
1115 if (g_on_end_frame_method == nullptr) {
1116 FML_LOG(ERROR) << "Could not locate onEndFrame method";
1117 return false;
1118 }
1119
1121 g_flutter_jni_class->obj(), "onDisplayOverlaySurface", "(IIIII)V");
1122
1123 if (g_on_display_overlay_surface_method == nullptr) {
1124 FML_LOG(ERROR) << "Could not locate onDisplayOverlaySurface method";
1125 return false;
1126 }
1127
1129 env, env->FindClass("java/lang/ref/WeakReference"));
1130 if (g_java_weak_reference_class->is_null()) {
1131 FML_LOG(ERROR) << "Could not locate WeakReference class";
1132 return false;
1133 }
1134
1136 g_java_weak_reference_class->obj(), "get", "()Ljava/lang/Object;");
1137 if (g_java_weak_reference_get_method == nullptr) {
1138 FML_LOG(ERROR) << "Could not locate WeakReference.get method";
1139 return false;
1140 }
1141
1143 env, env->FindClass(
1144 "io/flutter/embedding/engine/renderer/SurfaceTextureWrapper"));
1145 if (g_texture_wrapper_class->is_null()) {
1146 FML_LOG(ERROR) << "Could not locate SurfaceTextureWrapper class";
1147 return false;
1148 }
1149
1150 g_attach_to_gl_context_method = env->GetMethodID(
1151 g_texture_wrapper_class->obj(), "attachToGLContext", "(I)V");
1152
1153 if (g_attach_to_gl_context_method == nullptr) {
1154 FML_LOG(ERROR) << "Could not locate attachToGlContext method";
1155 return false;
1156 }
1157
1159 env->GetMethodID(g_texture_wrapper_class->obj(), "shouldUpdate", "()Z");
1160
1161 if (g_surface_texture_wrapper_should_update == nullptr) {
1162 FML_LOG(ERROR)
1163 << "Could not locate SurfaceTextureWrapper.shouldUpdate method";
1164 return false;
1165 }
1166
1168 env->GetMethodID(g_texture_wrapper_class->obj(), "updateTexImage", "()V");
1169
1170 if (g_update_tex_image_method == nullptr) {
1171 FML_LOG(ERROR) << "Could not locate updateTexImage method";
1172 return false;
1173 }
1174
1175 g_get_transform_matrix_method = env->GetMethodID(
1176 g_texture_wrapper_class->obj(), "getTransformMatrix", "([F)V");
1177
1178 if (g_get_transform_matrix_method == nullptr) {
1179 FML_LOG(ERROR) << "Could not locate getTransformMatrix method";
1180 return false;
1181 }
1182
1183 g_detach_from_gl_context_method = env->GetMethodID(
1184 g_texture_wrapper_class->obj(), "detachFromGLContext", "()V");
1185
1186 if (g_detach_from_gl_context_method == nullptr) {
1187 FML_LOG(ERROR) << "Could not locate detachFromGlContext method";
1188 return false;
1189 }
1192 env, env->FindClass("io/flutter/view/TextureRegistry$ImageConsumer"));
1194 FML_LOG(ERROR) << "Could not locate TextureRegistry.ImageConsumer class";
1195 return false;
1196 }
1197
1200 "acquireLatestImage", "()Landroid/media/Image;");
1201 if (g_acquire_latest_image_method == nullptr) {
1202 FML_LOG(ERROR) << "Could not locate acquireLatestImage on "
1203 "TextureRegistry.ImageConsumer class";
1204 return false;
1205 }
1206
1208 env, env->FindClass("android/media/Image"));
1209 if (g_image_class->is_null()) {
1210 FML_LOG(ERROR) << "Could not locate Image class";
1211 return false;
1212 }
1213
1214 // Ensure we don't have any pending exceptions.
1216
1218 env->GetMethodID(g_image_class->obj(), "getHardwareBuffer",
1219 "()Landroid/hardware/HardwareBuffer;");
1220
1221 if (g_image_get_hardware_buffer_method == nullptr) {
1222 // Continue on as this method may not exist at API <= 29.
1224 }
1225
1226 g_image_close_method = env->GetMethodID(g_image_class->obj(), "close", "()V");
1227
1228 if (g_image_close_method == nullptr) {
1229 FML_LOG(ERROR) << "Could not locate close on Image class";
1230 return false;
1231 }
1232
1233 // Ensure we don't have any pending exceptions.
1236 env, env->FindClass("android/hardware/HardwareBuffer"));
1237
1238 if (!g_hardware_buffer_class->is_null()) {
1240 env->GetMethodID(g_hardware_buffer_class->obj(), "close", "()V");
1241 if (g_hardware_buffer_close_method == nullptr) {
1242 // Continue on as this class may not exist at API <= 26.
1244 }
1245 } else {
1246 // Continue on as this class may not exist at API <= 26.
1248 }
1249
1251 g_flutter_jni_class->obj(), "computePlatformResolvedLocale",
1252 "([Ljava/lang/String;)[Ljava/lang/String;");
1253
1254 if (g_compute_platform_resolved_locale_method == nullptr) {
1255 FML_LOG(ERROR) << "Could not locate computePlatformResolvedLocale method";
1256 return false;
1257 }
1258
1260 g_flutter_jni_class->obj(), "requestDartDeferredLibrary", "(I)V");
1261
1262 if (g_request_dart_deferred_library_method == nullptr) {
1263 FML_LOG(ERROR) << "Could not locate requestDartDeferredLibrary method";
1264 return false;
1265 }
1266
1268 env, env->FindClass("java/lang/Long"));
1269 if (g_java_long_class->is_null()) {
1270 FML_LOG(ERROR) << "Could not locate java.lang.Long class";
1271 return false;
1272 }
1273
1274 return RegisterApi(env);
1275}
1276
1277PlatformViewAndroidJNIImpl::PlatformViewAndroidJNIImpl(
1278 const fml::jni::JavaObjectWeakGlobalRef& java_object)
1279 : java_object_(java_object) {}
1280
1281PlatformViewAndroidJNIImpl::~PlatformViewAndroidJNIImpl() = default;
1282
1283void PlatformViewAndroidJNIImpl::FlutterViewHandlePlatformMessage(
1284 std::unique_ptr<flutter::PlatformMessage> message,
1285 int responseId) {
1286 // Called from any thread.
1288
1289 auto java_object = java_object_.get(env);
1290 if (java_object.is_null()) {
1291 return;
1292 }
1293
1296
1297 if (message->hasData()) {
1299 env, env->NewDirectByteBuffer(
1300 const_cast<uint8_t*>(message->data().GetMapping()),
1301 message->data().GetSize()));
1302 // Message data is deleted in CleanupMessageData.
1303 fml::MallocMapping mapping = message->releaseData();
1304 env->CallVoidMethod(java_object.obj(), g_handle_platform_message_method,
1305 java_channel.obj(), message_array.obj(), responseId,
1306 reinterpret_cast<jlong>(mapping.Release()));
1307 } else {
1308 env->CallVoidMethod(java_object.obj(), g_handle_platform_message_method,
1309 java_channel.obj(), nullptr, responseId, nullptr);
1310 }
1311
1313}
1314
1315void PlatformViewAndroidJNIImpl::FlutterViewHandlePlatformMessageResponse(
1316 int responseId,
1317 std::unique_ptr<fml::Mapping> data) {
1318 // We are on the platform thread. Attempt to get the strong reference to
1319 // the Java object.
1321
1322 auto java_object = java_object_.get(env);
1323 if (java_object.is_null()) {
1324 // The Java object was collected before this message response got to
1325 // it. Drop the response on the floor.
1326 return;
1327 }
1328 if (data == nullptr) { // Empty response.
1329 env->CallVoidMethod(java_object.obj(),
1330 g_handle_platform_message_response_method, responseId,
1331 nullptr);
1332 } else {
1333 // Convert the vector to a Java byte array.
1335 env, env->NewDirectByteBuffer(const_cast<uint8_t*>(data->GetMapping()),
1336 data->GetSize()));
1337
1338 env->CallVoidMethod(java_object.obj(),
1339 g_handle_platform_message_response_method, responseId,
1340 data_array.obj());
1341 }
1342
1344}
1345
1346double PlatformViewAndroidJNIImpl::FlutterViewGetScaledFontSize(
1347 double font_size,
1348 int configuration_id) const {
1350
1351 auto java_object = java_object_.get(env);
1352 if (java_object.is_null()) {
1353 return -3;
1354 }
1355
1356 const jfloat scaledSize =
1357 env->CallFloatMethod(java_object.obj(), g_get_scaled_font_size_method,
1358 (jfloat)font_size, (jint)configuration_id);
1360 return (double)scaledSize;
1361}
1362
1363void PlatformViewAndroidJNIImpl::FlutterViewUpdateSemantics(
1364 std::vector<uint8_t> buffer,
1365 std::vector<std::string> strings,
1366 std::vector<std::vector<uint8_t>> string_attribute_args) {
1368
1369 auto java_object = java_object_.get(env);
1370 if (java_object.is_null()) {
1371 return;
1372 }
1373
1375 env, env->NewDirectByteBuffer(buffer.data(), buffer.size()));
1378 fml::jni::ScopedJavaLocalRef<jobjectArray> jstring_attribute_args =
1379 fml::jni::VectorToBufferArray(env, string_attribute_args);
1380
1381 env->CallVoidMethod(java_object.obj(), g_update_semantics_method,
1382 direct_buffer.obj(), jstrings.obj(),
1383 jstring_attribute_args.obj());
1384
1386}
1387
1388void PlatformViewAndroidJNIImpl::FlutterViewUpdateCustomAccessibilityActions(
1389 std::vector<uint8_t> actions_buffer,
1390 std::vector<std::string> strings) {
1392
1393 auto java_object = java_object_.get(env);
1394 if (java_object.is_null()) {
1395 return;
1396 }
1397
1398 fml::jni::ScopedJavaLocalRef<jobject> direct_actions_buffer(
1399 env,
1400 env->NewDirectByteBuffer(actions_buffer.data(), actions_buffer.size()));
1401
1404
1405 env->CallVoidMethod(java_object.obj(),
1406 g_update_custom_accessibility_actions_method,
1407 direct_actions_buffer.obj(), jstrings.obj());
1408
1410}
1411
1412void PlatformViewAndroidJNIImpl::FlutterViewOnFirstFrame() {
1414
1415 auto java_object = java_object_.get(env);
1416 if (java_object.is_null()) {
1417 return;
1418 }
1419
1420 env->CallVoidMethod(java_object.obj(), g_on_first_frame_method);
1421
1423}
1424
1425void PlatformViewAndroidJNIImpl::FlutterViewOnPreEngineRestart() {
1427
1428 auto java_object = java_object_.get(env);
1429 if (java_object.is_null()) {
1430 return;
1431 }
1432
1433 env->CallVoidMethod(java_object.obj(), g_on_engine_restart_method);
1434
1436}
1437
1438void PlatformViewAndroidJNIImpl::SurfaceTextureAttachToGLContext(
1439 JavaLocalRef surface_texture,
1440 int textureId) {
1442
1443 if (surface_texture.is_null()) {
1444 return;
1445 }
1446
1447 fml::jni::ScopedJavaLocalRef<jobject> surface_texture_local_ref(
1448 env, env->CallObjectMethod(surface_texture.obj(),
1449 g_java_weak_reference_get_method));
1450
1451 if (surface_texture_local_ref.is_null()) {
1452 return;
1453 }
1454
1455 env->CallVoidMethod(surface_texture_local_ref.obj(),
1456 g_attach_to_gl_context_method, textureId);
1457
1459}
1460
1461bool PlatformViewAndroidJNIImpl::SurfaceTextureShouldUpdate(
1462 JavaLocalRef surface_texture) {
1464
1465 if (surface_texture.is_null()) {
1466 return false;
1467 }
1468
1469 fml::jni::ScopedJavaLocalRef<jobject> surface_texture_local_ref(
1470 env, env->CallObjectMethod(surface_texture.obj(),
1471 g_java_weak_reference_get_method));
1472 if (surface_texture_local_ref.is_null()) {
1473 return false;
1474 }
1475
1476 jboolean shouldUpdate = env->CallBooleanMethod(
1477 surface_texture_local_ref.obj(), g_surface_texture_wrapper_should_update);
1478
1480
1481 return shouldUpdate;
1482}
1483
1484void PlatformViewAndroidJNIImpl::SurfaceTextureUpdateTexImage(
1485 JavaLocalRef surface_texture) {
1487
1488 if (surface_texture.is_null()) {
1489 return;
1490 }
1491
1492 fml::jni::ScopedJavaLocalRef<jobject> surface_texture_local_ref(
1493 env, env->CallObjectMethod(surface_texture.obj(),
1494 g_java_weak_reference_get_method));
1495 if (surface_texture_local_ref.is_null()) {
1496 return;
1497 }
1498
1499 env->CallVoidMethod(surface_texture_local_ref.obj(),
1500 g_update_tex_image_method);
1501
1503}
1504
1505void PlatformViewAndroidJNIImpl::SurfaceTextureGetTransformMatrix(
1506 JavaLocalRef surface_texture,
1509
1510 if (surface_texture.is_null()) {
1511 return;
1512 }
1513
1514 fml::jni::ScopedJavaLocalRef<jobject> surface_texture_local_ref(
1515 env, env->CallObjectMethod(surface_texture.obj(),
1516 g_java_weak_reference_get_method));
1517 if (surface_texture_local_ref.is_null()) {
1518 return;
1519 }
1520
1522 env, env->NewFloatArray(16));
1523
1524 env->CallVoidMethod(surface_texture_local_ref.obj(),
1525 g_get_transform_matrix_method, transformMatrix.obj());
1527
1528 float* m = env->GetFloatArrayElements(transformMatrix.obj(), nullptr);
1529
1530 // SurfaceTexture 4x4 Column Major -> Skia 3x3 Row Major
1531
1532 // SurfaceTexture 4x4 (Column Major):
1533 // | m[0] m[4] m[ 8] m[12] |
1534 // | m[1] m[5] m[ 9] m[13] |
1535 // | m[2] m[6] m[10] m[14] |
1536 // | m[3] m[7] m[11] m[15] |
1537
1538 // According to Android documentation, the 4x4 matrix returned should be used
1539 // with texture coordinates in the form (s, t, 0, 1). Since the z component is
1540 // always 0.0, we are free to ignore any element that multiplies with the z
1541 // component. Converting this to a 3x3 matrix is easy:
1542
1543 // SurfaceTexture 3x3 (Column Major):
1544 // | m[0] m[4] m[12] |
1545 // | m[1] m[5] m[13] |
1546 // | m[3] m[7] m[15] |
1547
1548 // Skia (Row Major):
1549 // | m[0] m[1] m[2] |
1550 // | m[3] m[4] m[5] |
1551 // | m[6] m[7] m[8] |
1552
1553 SkScalar matrix3[] = {
1554 m[0], m[4], m[12], //
1555 m[1], m[5], m[13], //
1556 m[3], m[7], m[15], //
1557 };
1558 env->ReleaseFloatArrayElements(transformMatrix.obj(), m, JNI_ABORT);
1559 transform.set9(matrix3);
1560}
1561
1562void PlatformViewAndroidJNIImpl::SurfaceTextureDetachFromGLContext(
1563 JavaLocalRef surface_texture) {
1565
1566 if (surface_texture.is_null()) {
1567 return;
1568 }
1569
1570 fml::jni::ScopedJavaLocalRef<jobject> surface_texture_local_ref(
1571 env, env->CallObjectMethod(surface_texture.obj(),
1572 g_java_weak_reference_get_method));
1573 if (surface_texture_local_ref.is_null()) {
1574 return;
1575 }
1576
1577 env->CallVoidMethod(surface_texture_local_ref.obj(),
1578 g_detach_from_gl_context_method);
1579
1581}
1582
1584PlatformViewAndroidJNIImpl::ImageProducerTextureEntryAcquireLatestImage(
1585 JavaLocalRef image_producer_texture_entry) {
1587
1588 if (image_producer_texture_entry.is_null()) {
1589 // Return null.
1590 return JavaLocalRef();
1591 }
1592
1593 // Convert the weak reference to ImageTextureEntry into a strong local
1594 // reference.
1595 fml::jni::ScopedJavaLocalRef<jobject> image_producer_texture_entry_local_ref(
1596 env, env->CallObjectMethod(image_producer_texture_entry.obj(),
1597 g_java_weak_reference_get_method));
1598
1599 if (image_producer_texture_entry_local_ref.is_null()) {
1600 // Return null.
1601 return JavaLocalRef();
1602 }
1603
1605 env, env->CallObjectMethod(image_producer_texture_entry_local_ref.obj(),
1606 g_acquire_latest_image_method));
1608 return r;
1609}
1610
1611JavaLocalRef PlatformViewAndroidJNIImpl::ImageGetHardwareBuffer(
1612 JavaLocalRef image) {
1613 FML_CHECK(g_image_get_hardware_buffer_method != nullptr);
1615 if (image.is_null()) {
1616 // Return null.
1617 return JavaLocalRef();
1618 }
1620 env,
1621 env->CallObjectMethod(image.obj(), g_image_get_hardware_buffer_method));
1623 return r;
1624}
1625
1626void PlatformViewAndroidJNIImpl::ImageClose(JavaLocalRef image) {
1628 if (image.is_null()) {
1629 return;
1630 }
1631 env->CallVoidMethod(image.obj(), g_image_close_method);
1633}
1634
1635void PlatformViewAndroidJNIImpl::HardwareBufferClose(
1636 JavaLocalRef hardware_buffer) {
1637 FML_CHECK(g_hardware_buffer_close_method != nullptr);
1639 if (hardware_buffer.is_null()) {
1640 return;
1641 }
1642 env->CallVoidMethod(hardware_buffer.obj(), g_hardware_buffer_close_method);
1644}
1645
1646void PlatformViewAndroidJNIImpl::FlutterViewOnDisplayPlatformView(
1647 int view_id,
1648 int x,
1649 int y,
1650 int width,
1651 int height,
1652 int viewWidth,
1653 int viewHeight,
1654 MutatorsStack mutators_stack) {
1656 auto java_object = java_object_.get(env);
1657 if (java_object.is_null()) {
1658 return;
1659 }
1660
1661 jobject mutatorsStack = env->NewObject(g_mutators_stack_class->obj(),
1662 g_mutators_stack_init_method);
1663
1664 std::vector<std::shared_ptr<Mutator>>::const_iterator iter =
1665 mutators_stack.Begin();
1666 while (iter != mutators_stack.End()) {
1667 switch ((*iter)->GetType()) {
1668 case kTransform: {
1669 const SkMatrix& matrix = (*iter)->GetMatrix();
1670 SkScalar matrix_array[9];
1671 matrix.get9(matrix_array);
1673 env, env->NewFloatArray(9));
1674
1675 env->SetFloatArrayRegion(transformMatrix.obj(), 0, 9, matrix_array);
1676 env->CallVoidMethod(mutatorsStack,
1677 g_mutators_stack_push_transform_method,
1678 transformMatrix.obj());
1679 break;
1680 }
1681 case kClipRect: {
1682 const SkRect& rect = (*iter)->GetRect();
1683 env->CallVoidMethod(
1684 mutatorsStack, g_mutators_stack_push_cliprect_method,
1685 static_cast<int>(rect.left()), static_cast<int>(rect.top()),
1686 static_cast<int>(rect.right()), static_cast<int>(rect.bottom()));
1687 break;
1688 }
1689 case kClipRRect: {
1690 const SkRRect& rrect = (*iter)->GetRRect();
1691 const SkRect& rect = rrect.rect();
1692 const SkVector& upper_left = rrect.radii(SkRRect::kUpperLeft_Corner);
1693 const SkVector& upper_right = rrect.radii(SkRRect::kUpperRight_Corner);
1694 const SkVector& lower_right = rrect.radii(SkRRect::kLowerRight_Corner);
1695 const SkVector& lower_left = rrect.radii(SkRRect::kLowerLeft_Corner);
1696 SkScalar radiis[8] = {
1697 upper_left.x(), upper_left.y(), upper_right.x(), upper_right.y(),
1698 lower_right.x(), lower_right.y(), lower_left.x(), lower_left.y(),
1699 };
1701 env, env->NewFloatArray(8));
1702 env->SetFloatArrayRegion(radiisArray.obj(), 0, 8, radiis);
1703 env->CallVoidMethod(
1704 mutatorsStack, g_mutators_stack_push_cliprrect_method,
1705 static_cast<int>(rect.left()), static_cast<int>(rect.top()),
1706 static_cast<int>(rect.right()), static_cast<int>(rect.bottom()),
1707 radiisArray.obj());
1708 break;
1709 }
1710 // TODO(cyanglaz): Implement other mutators.
1711 // https://github.com/flutter/flutter/issues/58426
1712 case kClipPath:
1713 case kOpacity:
1714 case kBackdropFilter:
1715 break;
1716 }
1717 ++iter;
1718 }
1719
1720 env->CallVoidMethod(java_object.obj(), g_on_display_platform_view_method,
1721 view_id, x, y, width, height, viewWidth, viewHeight,
1722 mutatorsStack);
1723
1725}
1726
1727void PlatformViewAndroidJNIImpl::FlutterViewDisplayOverlaySurface(
1728 int surface_id,
1729 int x,
1730 int y,
1731 int width,
1732 int height) {
1734
1735 auto java_object = java_object_.get(env);
1736 if (java_object.is_null()) {
1737 return;
1738 }
1739
1740 env->CallVoidMethod(java_object.obj(), g_on_display_overlay_surface_method,
1741 surface_id, x, y, width, height);
1742
1744}
1745
1746void PlatformViewAndroidJNIImpl::FlutterViewBeginFrame() {
1748
1749 auto java_object = java_object_.get(env);
1750 if (java_object.is_null()) {
1751 return;
1752 }
1753
1754 env->CallVoidMethod(java_object.obj(), g_on_begin_frame_method);
1755
1757}
1758
1759void PlatformViewAndroidJNIImpl::FlutterViewEndFrame() {
1761
1762 auto java_object = java_object_.get(env);
1763 if (java_object.is_null()) {
1764 return;
1765 }
1766
1767 env->CallVoidMethod(java_object.obj(), g_on_end_frame_method);
1768
1770}
1771
1772std::unique_ptr<PlatformViewAndroidJNI::OverlayMetadata>
1773PlatformViewAndroidJNIImpl::FlutterViewCreateOverlaySurface() {
1775
1776 auto java_object = java_object_.get(env);
1777 if (java_object.is_null()) {
1778 return nullptr;
1779 }
1780
1782 env, env->CallObjectMethod(java_object.obj(),
1783 g_create_overlay_surface_method));
1785
1786 if (overlay.is_null()) {
1787 return std::make_unique<PlatformViewAndroidJNI::OverlayMetadata>(0,
1788 nullptr);
1789 }
1790
1791 jint overlay_id =
1792 env->CallIntMethod(overlay.obj(), g_overlay_surface_id_method);
1793
1794 jobject overlay_surface =
1795 env->CallObjectMethod(overlay.obj(), g_overlay_surface_surface_method);
1796
1797 auto overlay_window = fml::MakeRefCounted<AndroidNativeWindow>(
1798 ANativeWindow_fromSurface(env, overlay_surface));
1799
1800 return std::make_unique<PlatformViewAndroidJNI::OverlayMetadata>(
1801 overlay_id, std::move(overlay_window));
1802}
1803
1804void PlatformViewAndroidJNIImpl::FlutterViewDestroyOverlaySurfaces() {
1806
1807 auto java_object = java_object_.get(env);
1808 if (java_object.is_null()) {
1809 return;
1810 }
1811
1812 env->CallVoidMethod(java_object.obj(), g_destroy_overlay_surfaces_method);
1813
1815}
1816
1817std::unique_ptr<std::vector<std::string>>
1818PlatformViewAndroidJNIImpl::FlutterViewComputePlatformResolvedLocale(
1819 std::vector<std::string> supported_locales_data) {
1821
1822 std::unique_ptr<std::vector<std::string>> out =
1823 std::make_unique<std::vector<std::string>>();
1824
1825 auto java_object = java_object_.get(env);
1826 if (java_object.is_null()) {
1827 return out;
1828 }
1830 fml::jni::VectorToStringArray(env, supported_locales_data);
1831 jobjectArray result = static_cast<jobjectArray>(env->CallObjectMethod(
1832 java_object.obj(), g_compute_platform_resolved_locale_method,
1833 j_locales_data.obj()));
1834
1836
1837 int length = env->GetArrayLength(result);
1838 for (int i = 0; i < length; i++) {
1839 out->emplace_back(fml::jni::JavaStringToString(
1840 env, static_cast<jstring>(env->GetObjectArrayElement(result, i))));
1841 }
1842 return out;
1843}
1844
1845double PlatformViewAndroidJNIImpl::GetDisplayRefreshRate() {
1847
1848 auto java_object = java_object_.get(env);
1849 if (java_object.is_null()) {
1850 return kUnknownDisplayRefreshRate;
1851 }
1852
1854 env, env->GetObjectClass(java_object.obj()));
1855 if (clazz.is_null()) {
1856 return kUnknownDisplayRefreshRate;
1857 }
1858
1859 jfieldID fid = env->GetStaticFieldID(clazz.obj(), "refreshRateFPS", "F");
1860 return static_cast<double>(env->GetStaticFloatField(clazz.obj(), fid));
1861}
1862
1863double PlatformViewAndroidJNIImpl::GetDisplayWidth() {
1865
1866 auto java_object = java_object_.get(env);
1867 if (java_object.is_null()) {
1868 return -1;
1869 }
1870
1872 env, env->GetObjectClass(java_object.obj()));
1873 if (clazz.is_null()) {
1874 return -1;
1875 }
1876
1877 jfieldID fid = env->GetStaticFieldID(clazz.obj(), "displayWidth", "F");
1878 return static_cast<double>(env->GetStaticFloatField(clazz.obj(), fid));
1879}
1880
1881double PlatformViewAndroidJNIImpl::GetDisplayHeight() {
1883
1884 auto java_object = java_object_.get(env);
1885 if (java_object.is_null()) {
1886 return -1;
1887 }
1888
1890 env, env->GetObjectClass(java_object.obj()));
1891 if (clazz.is_null()) {
1892 return -1;
1893 }
1894
1895 jfieldID fid = env->GetStaticFieldID(clazz.obj(), "displayHeight", "F");
1896 return static_cast<double>(env->GetStaticFloatField(clazz.obj(), fid));
1897}
1898
1899double PlatformViewAndroidJNIImpl::GetDisplayDensity() {
1901
1902 auto java_object = java_object_.get(env);
1903 if (java_object.is_null()) {
1904 return -1;
1905 }
1906
1908 env, env->GetObjectClass(java_object.obj()));
1909 if (clazz.is_null()) {
1910 return -1;
1911 }
1912
1913 jfieldID fid = env->GetStaticFieldID(clazz.obj(), "displayDensity", "F");
1914 return static_cast<double>(env->GetStaticFloatField(clazz.obj(), fid));
1915}
1916
1917bool PlatformViewAndroidJNIImpl::RequestDartDeferredLibrary(
1918 int loading_unit_id) {
1920
1921 auto java_object = java_object_.get(env);
1922 if (java_object.is_null()) {
1923 return true;
1924 }
1925
1926 env->CallVoidMethod(java_object.obj(), g_request_dart_deferred_library_method,
1927 loading_unit_id);
1928
1930 return true;
1931}
1932
1933} // namespace flutter
const SkRect & rect() const
Definition SkRRect.h:264
SkVector radii(Corner corner) const
Definition SkRRect.h:271
@ kUpperLeft_Corner
index of top-left corner radii
Definition SkRRect.h:252
@ kLowerRight_Corner
index of bottom-right corner radii
Definition SkRRect.h:254
@ kUpperRight_Corner
index of top-right corner radii
Definition SkRRect.h:253
@ kLowerLeft_Corner
index of bottom-left corner radii
Definition SkRRect.h:255
static std::unique_ptr< DartCallbackRepresentation > GetCallbackInformation(int64_t handle)
A Mapping like NonOwnedMapping, but uses Free as its release proc.
Definition mapping.h:144
static MallocMapping Copy(const T *begin, const T *end)
Definition mapping.h:162
uint8_t * Release()
Definition mapping.cc:155
static fml::RefPtr< NativeLibrary > CreateWithHandle(Handle handle, bool close_handle_when_done)
GLFWwindow * window
Definition main.cc:45
sk_sp< SkImage > image
Definition examples.cpp:29
float SkScalar
Definition extension.cpp:12
FlutterSemanticsFlag flags
G_BEGIN_DECLS G_MODULE_EXPORT FlValue * args
static const uint8_t buffer[]
GAsyncResult * result
static constexpr char kTransform[]
#define FML_LOG(severity)
Definition logging.h:82
#define FML_CHECK(condition)
Definition logging.h:85
#define FML_DCHECK(condition)
Definition logging.h:103
size_t length
Win32Message message
double y
double x
unsigned useCenter Optional< SkMatrix > matrix
Definition SkRecords.h:258
SkRRect rrect
Definition SkRecords.h:232
sk_sp< SkBlender > blender SkRect rect
Definition SkRecords.h:350
Definition __init__.py:1
static jmethodID g_hardware_buffer_close_method
static jmethodID g_mutators_stack_init_method
static void RunBundleAndSnapshotFromLibrary(JNIEnv *env, jobject jcaller, jlong shell_holder, jstring jBundlePath, jstring jEntrypoint, jstring jLibraryUrl, jobject jAssetManager, jobject jEntrypointArgs)
static jmethodID g_handle_platform_message_method
static jfieldID g_jni_shell_holder_field
static void InvokePlatformMessageResponseCallback(JNIEnv *env, jobject jcaller, jlong shell_holder, jint responseId, jobject message, jint position)
static jmethodID g_request_dart_deferred_library_method
static jboolean GetIsSoftwareRendering(JNIEnv *env, jobject jcaller)
static void DispatchPointerDataPacket(JNIEnv *env, jobject jcaller, jlong shell_holder, jobject buffer, jint position)
bool RegisterApi(JNIEnv *env)
static jboolean FlutterTextUtilsIsEmojiModifier(JNIEnv *env, jobject obj, jint codePoint)
static fml::jni::ScopedJavaGlobalRef< jclass > * g_java_long_class
static void LoadLoadingUnitFailure(intptr_t loading_unit_id, const std::string &message, bool transient)
static jmethodID g_on_engine_restart_method
static jmethodID g_on_display_overlay_surface_method
static void InvokePlatformMessageEmptyResponseCallback(JNIEnv *env, jobject jcaller, jlong shell_holder, jint responseId)
static jmethodID g_handle_platform_message_response_method
static jmethodID g_acquire_latest_image_method
static jmethodID g_mutators_stack_push_transform_method
static jmethodID g_on_begin_frame_method
static fml::jni::ScopedJavaGlobalRef< jclass > * g_bitmap_class
std::nullptr_t JavaLocalRef
static void SurfaceDestroyed(JNIEnv *env, jobject jcaller, jlong shell_holder)
static jmethodID g_create_overlay_surface_method
static jmethodID g_destroy_overlay_surfaces_method
DEF_SWITCHES_START aot vmservice shared library Name of the *so containing AOT compiled Dart assets for launching the service isolate vm snapshot The VM snapshot data that will be memory mapped as read only SnapshotAssetPath must be present isolate snapshot The isolate snapshot data that will be memory mapped as read only SnapshotAssetPath must be present cache dir path
Definition switches.h:57
static jmethodID g_long_constructor
static void DestroyJNI(JNIEnv *env, jobject jcaller, jlong shell_holder)
static jmethodID g_get_scaled_font_size_method
static void DispatchSemanticsAction(JNIEnv *env, jobject jcaller, jlong shell_holder, jint id, jint action, jobject args, jint args_position)
static jmethodID g_jni_constructor
static void MarkTextureFrameAvailable(JNIEnv *env, jobject jcaller, jlong shell_holder, jlong texture_id)
static jmethodID g_attach_to_gl_context_method
static void RegisterImageTexture(JNIEnv *env, jobject jcaller, jlong shell_holder, jlong texture_id, jobject image_texture_entry)
static void SetSemanticsEnabled(JNIEnv *env, jobject jcaller, jlong shell_holder, jboolean enabled)
static void DeferredComponentInstallFailure(JNIEnv *env, jobject obj, jint jLoadingUnitId, jstring jError, jboolean jTransient)
static fml::jni::ScopedJavaGlobalRef< jclass > * g_texture_wrapper_class
static void LoadDartDeferredLibrary(JNIEnv *env, jobject obj, jlong shell_holder, jint jLoadingUnitId, jobjectArray jSearchPaths)
static jmethodID g_java_weak_reference_get_method
static void NotifyLowMemoryWarning(JNIEnv *env, jobject obj, jlong shell_holder)
static jboolean FlutterTextUtilsIsVariationSelector(JNIEnv *env, jobject obj, jint codePoint)
static jmethodID g_image_get_hardware_buffer_method
static jmethodID g_update_custom_accessibility_actions_method
static void CleanupMessageData(JNIEnv *env, jobject jcaller, jlong message_data)
static jmethodID g_mutators_stack_push_cliprect_method
static jmethodID g_overlay_surface_surface_method
DEF_SWITCHES_START aot vmservice shared library Name of the *so containing AOT compiled Dart assets for launching the service isolate vm snapshot data
Definition switches.h:41
static void DispatchPlatformMessage(JNIEnv *env, jobject jcaller, jlong shell_holder, jstring channel, jobject message, jint position, jint responseId)
static jmethodID g_overlay_surface_id_method
static jmethodID g_mutators_stack_push_cliprrect_method
static jmethodID g_get_transform_matrix_method
static jmethodID g_compute_platform_resolved_locale_method
static void SurfaceWindowChanged(JNIEnv *env, jobject jcaller, jlong shell_holder, jobject jsurface)
static jmethodID g_bitmap_copy_pixels_from_buffer_method
static void SetViewportMetrics(JNIEnv *env, jobject jcaller, jlong shell_holder, jfloat devicePixelRatio, jint physicalWidth, jint physicalHeight, jint physicalPaddingTop, jint physicalPaddingRight, jint physicalPaddingBottom, jint physicalPaddingLeft, jint physicalViewInsetTop, jint physicalViewInsetRight, jint physicalViewInsetBottom, jint physicalViewInsetLeft, jint systemGestureInsetTop, jint systemGestureInsetRight, jint systemGestureInsetBottom, jint systemGestureInsetLeft, jint physicalTouchSlop, jintArray javaDisplayFeaturesBounds, jintArray javaDisplayFeaturesType, jintArray javaDisplayFeaturesState)
static fml::jni::ScopedJavaGlobalRef< jclass > * g_flutter_jni_class
static fml::jni::ScopedJavaGlobalRef< jclass > * g_bitmap_config_class
static jmethodID g_surface_texture_wrapper_should_update
static fml::jni::ScopedJavaGlobalRef< jclass > * g_image_class
static void SurfaceCreated(JNIEnv *env, jobject jcaller, jlong shell_holder, jobject jsurface)
static jmethodID g_flutter_callback_info_constructor
static void DispatchEmptyPlatformMessage(JNIEnv *env, jobject jcaller, jlong shell_holder, jstring channel, jint responseId)
static void ScheduleFrame(JNIEnv *env, jobject jcaller, jlong shell_holder)
static jlong AttachJNI(JNIEnv *env, jclass clazz, jobject flutterJNI)
static void SetAccessibilityFeatures(JNIEnv *env, jobject jcaller, jlong shell_holder, jint flags)
static jmethodID g_update_tex_image_method
static fml::jni::ScopedJavaGlobalRef< jclass > * g_java_weak_reference_class
static jmethodID g_on_display_platform_view_method
static jmethodID g_on_end_frame_method
static jmethodID g_image_close_method
static void UpdateDisplayMetrics(JNIEnv *env, jobject jcaller, jlong shell_holder)
static void SurfaceChanged(JNIEnv *env, jobject jcaller, jlong shell_holder, jint width, jint height)
static jmethodID g_bitmap_config_value_of
static fml::jni::ScopedJavaGlobalRef< jclass > * g_image_consumer_texture_registry_interface
static jmethodID g_on_first_frame_method
static void UpdateJavaAssetManager(JNIEnv *env, jobject obj, jlong shell_holder, jobject jAssetManager, jstring jAssetBundlePath)
static jobject GetBitmap(JNIEnv *env, jobject jcaller, jlong shell_holder)
jobject CreateFlutterCallbackInformation(JNIEnv *env, const std::string &callbackName, const std::string &callbackClassName, const std::string &callbackLibraryPath)
static jmethodID g_bitmap_create_bitmap_method
static jmethodID g_update_semantics_method
static void UnregisterTexture(JNIEnv *env, jobject jcaller, jlong shell_holder, jlong texture_id)
static fml::jni::ScopedJavaGlobalRef< jclass > * g_flutter_callback_info_class
static fml::jni::ScopedJavaGlobalRef< jclass > * g_mutators_stack_class
static jboolean FlutterTextUtilsIsEmojiModifierBase(JNIEnv *env, jobject obj, jint codePoint)
static jobject LookupCallbackInformation(JNIEnv *env, jobject, jlong handle)
static jboolean FlutterTextUtilsIsRegionalIndicator(JNIEnv *env, jobject obj, jint codePoint)
static jmethodID g_detach_from_gl_context_method
static jobject SpawnJNI(JNIEnv *env, jobject jcaller, jlong shell_holder, jstring jEntrypoint, jstring jLibraryUrl, jstring jInitialRoute, jobject jEntrypointArgs)
static fml::jni::ScopedJavaGlobalRef< jclass > * g_hardware_buffer_class
static jboolean FlutterTextUtilsIsEmoji(JNIEnv *env, jobject obj, jint codePoint)
static void RegisterTexture(JNIEnv *env, jobject jcaller, jlong shell_holder, jlong texture_id, jobject surface_texture)
JNIEnv * AttachCurrentThread()
Definition jni_util.cc:34
ScopedJavaLocalRef< jobjectArray > VectorToBufferArray(JNIEnv *env, const std::vector< std::vector< uint8_t > > &vector)
Definition jni_util.cc:164
std::string JavaStringToString(JNIEnv *env, jstring str)
Definition jni_util.cc:70
bool ClearException(JNIEnv *env, bool silent)
Definition jni_util.cc:188
bool CheckException(JNIEnv *env)
Definition jni_util.cc:199
ScopedJavaLocalRef< jobjectArray > VectorToStringArray(JNIEnv *env, const std::vector< std::string > &vector)
Definition jni_util.cc:147
std::vector< std::string > StringListToVector(JNIEnv *env, jobject list)
Definition jni_util.cc:118
std::vector< std::string > StringArrayToVector(JNIEnv *env, jobjectArray array)
Definition jni_util.cc:96
ScopedJavaLocalRef< jstring > StringToJavaString(JNIEnv *env, const std::string &u8_string)
Definition jni_util.cc:86
constexpr std::size_t size(T(&array)[N])
Definition size.h:13
static SkColor4f transform(SkColor4f c, SkColorSpace *src, SkColorSpace *dst)
Definition p3.cpp:47
#define ANDROID_SHELL_HOLDER
int32_t height
int32_t width
static constexpr SkISize Make(int32_t w, int32_t h)
Definition SkSize.h:20
constexpr float y() const
constexpr float x() const
int64_t texture_id
#define ERROR(message)