Flutter Engine Uber Docs
Docs for the entire Flutter Engine repo.
 
Loading...
Searching...
No Matches
platform_view_android_jni_impl.cc
Go to the documentation of this file.
1// Copyright 2013 The Flutter Authors. All rights reserved.
2// Use of this source code is governed by a BSD-style license that can be
3// found in the LICENSE file.
4
6
7#include <android/hardware_buffer_jni.h>
8#include <android/native_window_jni.h>
9#include <dlfcn.h>
10#include <jni.h>
11#include <memory>
12#include <utility>
13
14#include "unicode/uchar.h"
15
18#include "flutter/fml/mapping.h"
30
31#define ANDROID_SHELL_HOLDER \
32 (reinterpret_cast<AndroidShellHolder*>(shell_holder))
33
34namespace flutter {
35
37 nullptr;
38
40
42 nullptr;
43
45
48
50
52
54
56
58
59// Called By Native
60
61static jmethodID g_flutter_callback_info_constructor = nullptr;
62
63static jfieldID g_jni_shell_holder_field = nullptr;
64
65#define FLUTTER_FOR_EACH_JNI_METHOD(V) \
66 V(g_handle_platform_message_method, handlePlatformMessage, \
67 "(Ljava/lang/String;Ljava/nio/ByteBuffer;IJ)V") \
68 V(g_handle_platform_message_response_method, handlePlatformMessageResponse, \
69 "(ILjava/nio/ByteBuffer;)V") \
70 V(g_update_semantics_method, updateSemantics, \
71 "(Ljava/nio/ByteBuffer;[Ljava/lang/String;[Ljava/nio/ByteBuffer;)V") \
72 V(g_set_application_locale_method, setApplicationLocale, \
73 "(Ljava/lang/String;)V") \
74 V(g_set_semantics_tree_enabled_method, setSemanticsTreeEnabled, "(Z)V") \
75 V(g_on_display_platform_view_method, onDisplayPlatformView, \
76 "(IIIIIIILio/flutter/embedding/engine/mutatorsstack/" \
77 "FlutterMutatorsStack;)V") \
78 V(g_on_begin_frame_method, onBeginFrame, "()V") \
79 V(g_on_end_frame_method, onEndFrame, "()V") \
80 V(g_on_display_overlay_surface_method, onDisplayOverlaySurface, "(IIIII)V") \
81 V(g_create_transaction_method, createTransaction, \
82 "()Landroid/view/SurfaceControl$Transaction;") \
83 V(g_swap_transaction_method, swapTransactions, "()V") \
84 V(g_apply_transaction_method, applyTransactions, "()V") \
85 V(g_create_overlay_surface2_method, createOverlaySurface2, \
86 "()Lio/flutter/embedding/engine/FlutterOverlaySurface;") \
87 V(g_destroy_overlay_surface2_method, destroyOverlaySurface2, "()V") \
88 V(g_on_display_platform_view2_method, onDisplayPlatformView2, \
89 "(IIIIIIILio/flutter/embedding/engine/mutatorsstack/" \
90 "FlutterMutatorsStack;)V") \
91 V(g_hide_platform_view2_method, hidePlatformView2, "(I)V") \
92 V(g_on_end_frame2_method, endFrame2, "()V") \
93 V(g_show_overlay_surface2_method, showOverlaySurface2, "()V") \
94 V(g_hide_overlay_surface2_method, hideOverlaySurface2, "()V") \
95 V(g_get_scaled_font_size_method, getScaledFontSize, "(FI)F") \
96 V(g_update_custom_accessibility_actions_method, \
97 updateCustomAccessibilityActions, \
98 "(Ljava/nio/ByteBuffer;[Ljava/lang/String;)V") \
99 V(g_on_first_frame_method, onFirstFrame, "()V") \
100 V(g_on_engine_restart_method, onPreEngineRestart, "()V") \
101 V(g_create_overlay_surface_method, createOverlaySurface, \
102 "()Lio/flutter/embedding/engine/FlutterOverlaySurface;") \
103 V(g_destroy_overlay_surfaces_method, destroyOverlaySurfaces, "()V") \
104 V(g_maybe_resize_surface_view, maybeResizeSurfaceView, "(II)V") \
105 //
106
107#define FLUTTER_DECLARE_JNI(global_field, jni_name, jni_arg) \
108 static jmethodID global_field = nullptr;
109
110#define FLUTTER_BIND_JNI(global_field, jni_name, jni_arg) \
111 global_field = \
112 env->GetMethodID(g_flutter_jni_class->obj(), #jni_name, jni_arg); \
113 if (global_field == nullptr) { \
114 FML_LOG(ERROR) << "Could not locate " << #jni_name << " method."; \
115 return false; \
116 }
117
118static jmethodID g_jni_constructor = nullptr;
119
120static jmethodID g_long_constructor = nullptr;
121
123
124static jmethodID g_java_weak_reference_get_method = nullptr;
125
126static jmethodID g_attach_to_gl_context_method = nullptr;
127
129
130static jmethodID g_update_tex_image_method = nullptr;
131
132static jmethodID g_get_transform_matrix_method = nullptr;
133
134static jmethodID g_detach_from_gl_context_method = nullptr;
135
136static jmethodID g_acquire_latest_image_method = nullptr;
137
138static jmethodID g_image_get_hardware_buffer_method = nullptr;
139
140static jmethodID g_image_close_method = nullptr;
141
142static jmethodID g_hardware_buffer_close_method = nullptr;
143
145
146static jmethodID g_request_dart_deferred_library_method = nullptr;
147
148// Called By Java
149
150static jmethodID g_overlay_surface_id_method = nullptr;
151
152static jmethodID g_overlay_surface_surface_method = nullptr;
153
154static jmethodID g_bitmap_create_bitmap_method = nullptr;
155
157
158static jmethodID g_bitmap_config_value_of = nullptr;
159
160// Mutators
161static fml::jni::ScopedJavaGlobalRef<jclass>* g_mutators_stack_class = nullptr;
162static jmethodID g_mutators_stack_init_method = nullptr;
163static jmethodID g_mutators_stack_push_transform_method = nullptr;
164static jmethodID g_mutators_stack_push_cliprect_method = nullptr;
165static jmethodID g_mutators_stack_push_cliprrect_method = nullptr;
166static jmethodID g_mutators_stack_push_opacity_method = nullptr;
167static jmethodID g_mutators_stack_push_clippath_method = nullptr;
168
169// android.graphics.Path class, methods, and nested classes.
170static fml::jni::ScopedJavaGlobalRef<jclass>* path_class = nullptr;
171static jmethodID path_constructor = nullptr;
172static jmethodID path_move_to_method = nullptr;
173static jmethodID path_line_to_method = nullptr;
174static jmethodID path_quad_to_method = nullptr;
175static jmethodID path_cubic_to_method = nullptr;
176static jmethodID path_conic_to_method = nullptr;
177static jmethodID path_close_method = nullptr;
178static jmethodID path_set_fill_type_method = nullptr;
179
180static fml::jni::ScopedJavaGlobalRef<jclass>* g_path_fill_type_class = nullptr;
181static jfieldID g_path_fill_type_winding_field = nullptr;
182static jfieldID g_path_fill_type_even_odd_field = nullptr;
183
184// Called By Java
185static jlong AttachJNI(JNIEnv* env, jclass clazz, jobject flutterJNI) {
186 fml::jni::JavaObjectWeakGlobalRef java_object(env, flutterJNI);
187 std::shared_ptr<PlatformViewAndroidJNI> jni_facade =
188 std::make_shared<PlatformViewAndroidJNIImpl>(java_object);
189 auto shell_holder = std::make_unique<AndroidShellHolder>(
190 FlutterMain::Get().GetSettings(), jni_facade,
191 FlutterMain::Get().GetAndroidRenderingAPI());
192 if (shell_holder->IsValid()) {
193 return reinterpret_cast<jlong>(shell_holder.release());
194 } else {
195 return 0;
196 }
197}
198
199static void DestroyJNI(JNIEnv* env, jobject jcaller, jlong shell_holder) {
201}
202
203// Signature is similar to RunBundleAndSnapshotFromLibrary but it can't change
204// the bundle path or asset manager since we can only spawn with the same
205// AOT.
206//
207// The shell_holder instance must be a pointer address to the current
208// AndroidShellHolder whose Shell will be used to spawn a new Shell.
209//
210// This creates a Java Long that points to the newly created
211// AndroidShellHolder's raw pointer, connects that Long to a newly created
212// FlutterJNI instance, then returns the FlutterJNI instance.
213static jobject SpawnJNI(JNIEnv* env,
214 jobject jcaller,
215 jlong shell_holder,
216 jstring jEntrypoint,
217 jstring jLibraryUrl,
218 jstring jInitialRoute,
219 jobject jEntrypointArgs,
220 jlong engineId) {
221 jobject jni = env->NewObject(g_flutter_jni_class->obj(), g_jni_constructor);
222 if (jni == nullptr) {
223 FML_LOG(ERROR) << "Could not create a FlutterJNI instance";
224 return nullptr;
225 }
226
227 fml::jni::JavaObjectWeakGlobalRef java_jni(env, jni);
228 std::shared_ptr<PlatformViewAndroidJNI> jni_facade =
229 std::make_shared<PlatformViewAndroidJNIImpl>(java_jni);
230
231 auto entrypoint = fml::jni::JavaStringToString(env, jEntrypoint);
232 auto libraryUrl = fml::jni::JavaStringToString(env, jLibraryUrl);
233 auto initial_route = fml::jni::JavaStringToString(env, jInitialRoute);
234 auto entrypoint_args = fml::jni::StringListToVector(env, jEntrypointArgs);
235
236 auto spawned_shell_holder =
237 ANDROID_SHELL_HOLDER->Spawn(jni_facade, entrypoint, libraryUrl,
238 initial_route, entrypoint_args, engineId);
239
240 if (spawned_shell_holder == nullptr || !spawned_shell_holder->IsValid()) {
241 FML_LOG(ERROR) << "Could not spawn Shell";
242 return nullptr;
243 }
244
245 jobject javaLong = env->CallStaticObjectMethod(
247 reinterpret_cast<jlong>(spawned_shell_holder.release()));
248 if (javaLong == nullptr) {
249 FML_LOG(ERROR) << "Could not create a Long instance";
250 return nullptr;
251 }
252
253 env->SetObjectField(jni, g_jni_shell_holder_field, javaLong);
254
255 return jni;
256}
257
258static void SurfaceCreated(JNIEnv* env,
259 jobject jcaller,
260 jlong shell_holder,
261 jobject jsurface) {
262 // Note: This frame ensures that any local references used by
263 // ANativeWindow_fromSurface are released immediately. This is needed as a
264 // workaround for https://code.google.com/p/android/issues/detail?id=68174
265 fml::jni::ScopedJavaLocalFrame scoped_local_reference_frame(env);
266 auto window = fml::MakeRefCounted<AndroidNativeWindow>(
267 ANativeWindow_fromSurface(env, jsurface));
268 ANDROID_SHELL_HOLDER->GetPlatformView()->NotifyCreated(std::move(window));
269}
270
271static void SurfaceWindowChanged(JNIEnv* env,
272 jobject jcaller,
273 jlong shell_holder,
274 jobject jsurface) {
275 // Note: This frame ensures that any local references used by
276 // ANativeWindow_fromSurface are released immediately. This is needed as a
277 // workaround for https://code.google.com/p/android/issues/detail?id=68174
278 fml::jni::ScopedJavaLocalFrame scoped_local_reference_frame(env);
279 auto window = fml::MakeRefCounted<AndroidNativeWindow>(
280 ANativeWindow_fromSurface(env, jsurface));
281 ANDROID_SHELL_HOLDER->GetPlatformView()->NotifySurfaceWindowChanged(
282 std::move(window));
283}
284
285static void SurfaceChanged(JNIEnv* env,
286 jobject jcaller,
287 jlong shell_holder,
288 jint width,
289 jint height) {
290 ANDROID_SHELL_HOLDER->GetPlatformView()->NotifyChanged(
292}
293
294static void SurfaceDestroyed(JNIEnv* env, jobject jcaller, jlong shell_holder) {
295 ANDROID_SHELL_HOLDER->GetPlatformView()->NotifyDestroyed();
296}
297
298static void RunBundleAndSnapshotFromLibrary(JNIEnv* env,
299 jobject jcaller,
300 jlong shell_holder,
301 jstring jBundlePath,
302 jstring jEntrypoint,
303 jstring jLibraryUrl,
304 jobject jAssetManager,
305 jobject jEntrypointArgs,
306 jlong engineId) {
307 auto apk_asset_provider = std::make_unique<flutter::APKAssetProvider>(
308 env, // jni environment
309 jAssetManager, // asset manager
310 fml::jni::JavaStringToString(env, jBundlePath) // apk asset dir
311 );
312 auto entrypoint = fml::jni::JavaStringToString(env, jEntrypoint);
313 auto libraryUrl = fml::jni::JavaStringToString(env, jLibraryUrl);
314 auto entrypoint_args = fml::jni::StringListToVector(env, jEntrypointArgs);
315
316 ANDROID_SHELL_HOLDER->Launch(std::move(apk_asset_provider), entrypoint,
317 libraryUrl, entrypoint_args, engineId);
318}
319
320static jobject LookupCallbackInformation(JNIEnv* env,
321 /* unused */ jobject,
322 jlong handle) {
324 if (cbInfo == nullptr) {
325 return nullptr;
326 }
327 return env->NewObject(g_flutter_callback_info_class->obj(),
329 env->NewStringUTF(cbInfo->name.c_str()),
330 env->NewStringUTF(cbInfo->class_name.c_str()),
331 env->NewStringUTF(cbInfo->library_path.c_str()));
332}
333
334static void SetViewportMetrics(JNIEnv* env,
335 jobject jcaller,
336 jlong shell_holder,
337 jfloat devicePixelRatio,
338 jint physicalWidth,
339 jint physicalHeight,
340 jint physicalPaddingTop,
341 jint physicalPaddingRight,
342 jint physicalPaddingBottom,
343 jint physicalPaddingLeft,
344 jint physicalViewInsetTop,
345 jint physicalViewInsetRight,
346 jint physicalViewInsetBottom,
347 jint physicalViewInsetLeft,
348 jint systemGestureInsetTop,
349 jint systemGestureInsetRight,
350 jint systemGestureInsetBottom,
351 jint systemGestureInsetLeft,
352 jint physicalTouchSlop,
353 jintArray javaDisplayFeaturesBounds,
354 jintArray javaDisplayFeaturesType,
355 jintArray javaDisplayFeaturesState,
356 jint physicalMinWidth,
357 jint physicalMaxWidth,
358 jint physicalMinHeight,
359 jint physicalMaxHeight,
360 jint physicalDisplayCornerRadiusTopLeft,
361 jint physicalDisplayCornerRadiusTopRight,
362 jint physicalDisplayCornerRadiusBottomRight,
363 jint physicalDisplayCornerRadiusBottomLeft) {
364 // Convert java->c++. javaDisplayFeaturesBounds, javaDisplayFeaturesType and
365 // javaDisplayFeaturesState cannot be null
366 jsize rectSize = env->GetArrayLength(javaDisplayFeaturesBounds);
367 std::vector<int> boundsIntVector(rectSize);
368 if (rectSize > 0) {
369 env->GetIntArrayRegion(javaDisplayFeaturesBounds, 0, rectSize,
370 &boundsIntVector[0]);
371 }
372 std::vector<double> displayFeaturesBounds(boundsIntVector.begin(),
373 boundsIntVector.end());
374 jsize typeSize = env->GetArrayLength(javaDisplayFeaturesType);
375 std::vector<int> displayFeaturesType(typeSize);
376 if (typeSize > 0) {
377 env->GetIntArrayRegion(javaDisplayFeaturesType, 0, typeSize,
378 &displayFeaturesType[0]);
379 }
380
381 jsize stateSize = env->GetArrayLength(javaDisplayFeaturesState);
382 std::vector<int> displayFeaturesState(stateSize);
383 if (stateSize > 0) {
384 env->GetIntArrayRegion(javaDisplayFeaturesState, 0, stateSize,
385 &displayFeaturesState[0]);
386 }
387
388 const flutter::ViewportMetrics metrics{
389 static_cast<double>(devicePixelRatio), // p_device_pixel_ratio
390 static_cast<double>(physicalWidth), // p_physical_width
391 static_cast<double>(physicalHeight), // p_physical_height
392 static_cast<double>(physicalMinWidth), // p_physical_min_width_constraint
393 static_cast<double>(physicalMaxWidth), // p_physical_max_width_constraint
394 static_cast<double>(
395 physicalMinHeight), // p_physical_min_height_constraint
396 static_cast<double>(
397 physicalMaxHeight), // p_physical_max_height_constraint
398 static_cast<double>(physicalPaddingTop), // p_physical_padding_top
399 static_cast<double>(physicalPaddingRight), // p_physical_padding_right
400 static_cast<double>(physicalPaddingBottom), // p_physical_padding_bottom
401 static_cast<double>(physicalPaddingLeft), // p_physical_padding_left
402 static_cast<double>(physicalViewInsetTop), // p_physical_view_inset_top
403 static_cast<double>(
404 physicalViewInsetRight), // p_physical_view_inset_right
405 static_cast<double>(
406 physicalViewInsetBottom), // p_physical_view_inset_bottom
407 static_cast<double>(physicalViewInsetLeft), // p_physical_view_inset_left
408 static_cast<double>(
409 systemGestureInsetTop), // p_physical_system_gesture_inset_top
410 static_cast<double>(
411 systemGestureInsetRight), // p_physical_system_gesture_inset_right
412 static_cast<double>(
413 systemGestureInsetBottom), // p_physical_system_gesture_inset_bottom
414 static_cast<double>(
415 systemGestureInsetLeft), // p_physical_system_gesture_inset_left
416 static_cast<double>(physicalTouchSlop), // p_physical_touch_slop
417 displayFeaturesBounds, // p_physical_display_features_bounds
418 displayFeaturesType, // p_physical_display_features_type
419 displayFeaturesState, // p_physical_display_features_state
420 0, // p_display_id,
421 static_cast<double>(
422 physicalDisplayCornerRadiusTopLeft), // p_physical_display_corner_radius_top_left
423 static_cast<double>(
424 physicalDisplayCornerRadiusTopRight), // p_physical_display_corner_radius_top_right
425 static_cast<double>(
426 physicalDisplayCornerRadiusBottomRight), // p_physical_display_corner_radius_bottom_right
427 static_cast<double>(
428 physicalDisplayCornerRadiusBottomLeft), // p_physical_display_corner_radius_bottom_left
429 };
430
431 ANDROID_SHELL_HOLDER->GetPlatformView()->SetViewportMetrics(
432 kFlutterImplicitViewId, metrics);
433}
434
435static void UpdateDisplayMetrics(JNIEnv* env,
436 jobject jcaller,
437 jlong shell_holder) {
438 ANDROID_SHELL_HOLDER->UpdateDisplayMetrics();
439}
440
441static bool IsSurfaceControlEnabled(JNIEnv* env,
442 jobject jcaller,
443 jlong shell_holder) {
444 return ANDROID_SHELL_HOLDER->IsSurfaceControlEnabled();
445}
446
447static jobject GetBitmap(JNIEnv* env, jobject jcaller, jlong shell_holder) {
448 auto screenshot = ANDROID_SHELL_HOLDER->Screenshot(
450 if (screenshot.data == nullptr) {
451 return nullptr;
452 }
453
454 jstring argb = env->NewStringUTF("ARGB_8888");
455 if (argb == nullptr) {
456 return nullptr;
457 }
458
459 jobject bitmap_config = env->CallStaticObjectMethod(
461 if (bitmap_config == nullptr) {
462 return nullptr;
463 }
464
465 auto bitmap = env->CallStaticObjectMethod(
467 screenshot.frame_size.width, screenshot.frame_size.height, bitmap_config);
468
470 env,
471 env->NewDirectByteBuffer(const_cast<uint8_t*>(screenshot.data->bytes()),
472 screenshot.data->size()));
473
475 buffer.obj());
476
477 return bitmap;
478}
479
480static void DispatchPlatformMessage(JNIEnv* env,
481 jobject jcaller,
482 jlong shell_holder,
483 jstring channel,
484 jobject message,
485 jint position,
486 jint responseId) {
487 ANDROID_SHELL_HOLDER->GetPlatformView()->DispatchPlatformMessage(
488 env, //
490 message, //
491 position, //
492 responseId //
493 );
494}
495
496static void DispatchEmptyPlatformMessage(JNIEnv* env,
497 jobject jcaller,
498 jlong shell_holder,
499 jstring channel,
500 jint responseId) {
501 ANDROID_SHELL_HOLDER->GetPlatformView()->DispatchEmptyPlatformMessage(
502 env, //
504 responseId //
505 );
506}
507
508static void CleanupMessageData(JNIEnv* env,
509 jobject jcaller,
510 jlong message_data) {
511 // Called from any thread.
512 free(reinterpret_cast<void*>(message_data));
513}
514
515static void DispatchPointerDataPacket(JNIEnv* env,
516 jobject jcaller,
517 jlong shell_holder,
518 jobject buffer,
519 jint position) {
520 uint8_t* data = static_cast<uint8_t*>(env->GetDirectBufferAddress(buffer));
521 auto packet = std::make_unique<flutter::PointerDataPacket>(data, position);
522 ANDROID_SHELL_HOLDER->GetPlatformView()->DispatchPointerDataPacket(
523 std::move(packet));
524}
525
526static void DispatchSemanticsAction(JNIEnv* env,
527 jobject jcaller,
528 jlong shell_holder,
529 jint id,
530 jint action,
531 jobject args,
532 jint args_position) {
533 ANDROID_SHELL_HOLDER->GetPlatformView()->DispatchSemanticsAction(
534 env, //
535 id, //
536 action, //
537 args, //
538 args_position //
539 );
540}
541
542static void SetSemanticsEnabled(JNIEnv* env,
543 jobject jcaller,
544 jlong shell_holder,
545 jboolean enabled) {
546 ANDROID_SHELL_HOLDER->GetPlatformView()->SetSemanticsEnabled(enabled);
547}
548
549static void SetAccessibilityFeatures(JNIEnv* env,
550 jobject jcaller,
551 jlong shell_holder,
552 jint flags) {
553 ANDROID_SHELL_HOLDER->GetPlatformView()->SetAccessibilityFeatures(flags);
554}
555
556static jboolean GetIsSoftwareRendering(JNIEnv* env, jobject jcaller) {
558}
559
560static void RegisterTexture(JNIEnv* env,
561 jobject jcaller,
562 jlong shell_holder,
563 jlong texture_id,
564 jobject surface_texture) {
565 ANDROID_SHELL_HOLDER->GetPlatformView()->RegisterExternalTexture(
566 static_cast<int64_t>(texture_id), //
567 fml::jni::ScopedJavaGlobalRef<jobject>(env, surface_texture) //
568 );
569}
570
571static void RegisterImageTexture(JNIEnv* env,
572 jobject jcaller,
573 jlong shell_holder,
574 jlong texture_id,
575 jobject image_texture_entry,
576 jboolean reset_on_background) {
580
581 ANDROID_SHELL_HOLDER->GetPlatformView()->RegisterImageTexture(
582 static_cast<int64_t>(texture_id), //
583 fml::jni::ScopedJavaGlobalRef<jobject>(env, image_texture_entry), //
584 lifecycle //
585 );
586}
587
588static void UnregisterTexture(JNIEnv* env,
589 jobject jcaller,
590 jlong shell_holder,
591 jlong texture_id) {
592 ANDROID_SHELL_HOLDER->GetPlatformView()->UnregisterTexture(
593 static_cast<int64_t>(texture_id));
594}
595
596static void MarkTextureFrameAvailable(JNIEnv* env,
597 jobject jcaller,
598 jlong shell_holder,
599 jlong texture_id) {
600 ANDROID_SHELL_HOLDER->GetPlatformView()->MarkTextureFrameAvailable(
601 static_cast<int64_t>(texture_id));
602}
603
604static void ScheduleFrame(JNIEnv* env, jobject jcaller, jlong shell_holder) {
605 ANDROID_SHELL_HOLDER->GetPlatformView()->ScheduleFrame();
606}
607
609 jobject jcaller,
610 jlong shell_holder,
611 jint responseId,
612 jobject message,
613 jint position) {
614 uint8_t* response_data =
615 static_cast<uint8_t*>(env->GetDirectBufferAddress(message));
616 FML_DCHECK(response_data != nullptr);
617 auto mapping = std::make_unique<fml::MallocMapping>(
618 fml::MallocMapping::Copy(response_data, response_data + position));
619 ANDROID_SHELL_HOLDER->GetPlatformMessageHandler()
620 ->InvokePlatformMessageResponseCallback(responseId, std::move(mapping));
621}
622
624 jobject jcaller,
625 jlong shell_holder,
626 jint responseId) {
627 ANDROID_SHELL_HOLDER->GetPlatformMessageHandler()
628 ->InvokePlatformMessageEmptyResponseCallback(responseId);
629}
630
631static void NotifyLowMemoryWarning(JNIEnv* env,
632 jobject obj,
633 jlong shell_holder) {
634 ANDROID_SHELL_HOLDER->NotifyLowMemoryWarning();
635}
636
637static jboolean FlutterTextUtilsIsEmoji(JNIEnv* env,
638 jobject obj,
639 jint codePoint) {
640 return u_hasBinaryProperty(codePoint, UProperty::UCHAR_EMOJI);
641}
642
643static jboolean FlutterTextUtilsIsEmojiModifier(JNIEnv* env,
644 jobject obj,
645 jint codePoint) {
646 return u_hasBinaryProperty(codePoint, UProperty::UCHAR_EMOJI_MODIFIER);
647}
648
649static jboolean FlutterTextUtilsIsEmojiModifierBase(JNIEnv* env,
650 jobject obj,
651 jint codePoint) {
652 return u_hasBinaryProperty(codePoint, UProperty::UCHAR_EMOJI_MODIFIER_BASE);
653}
654
655static jboolean FlutterTextUtilsIsVariationSelector(JNIEnv* env,
656 jobject obj,
657 jint codePoint) {
658 return u_hasBinaryProperty(codePoint, UProperty::UCHAR_VARIATION_SELECTOR);
659}
660
661static jboolean FlutterTextUtilsIsRegionalIndicator(JNIEnv* env,
662 jobject obj,
663 jint codePoint) {
664 return u_hasBinaryProperty(codePoint, UProperty::UCHAR_REGIONAL_INDICATOR);
665}
666
667static void LoadLoadingUnitFailure(intptr_t loading_unit_id,
668 const std::string& message,
669 bool transient) {
670 // TODO(garyq): Implement
671}
672
673static void DeferredComponentInstallFailure(JNIEnv* env,
674 jobject obj,
675 jint jLoadingUnitId,
676 jstring jError,
677 jboolean jTransient) {
678 LoadLoadingUnitFailure(static_cast<intptr_t>(jLoadingUnitId),
679 fml::jni::JavaStringToString(env, jError),
680 static_cast<bool>(jTransient));
681}
682
683static void LoadDartDeferredLibrary(JNIEnv* env,
684 jobject obj,
685 jlong shell_holder,
686 jint jLoadingUnitId,
687 jobjectArray jSearchPaths) {
688 // Convert java->c++
689 intptr_t loading_unit_id = static_cast<intptr_t>(jLoadingUnitId);
690 std::vector<std::string> search_paths =
691 fml::jni::StringArrayToVector(env, jSearchPaths);
692
693 // Use dlopen here to directly check if handle is nullptr before creating a
694 // NativeLibrary.
695 void* handle = nullptr;
696 while (handle == nullptr && !search_paths.empty()) {
697 std::string path = search_paths.back();
698 handle = ::dlopen(path.c_str(), RTLD_NOW);
699 search_paths.pop_back();
700 }
701 if (handle == nullptr) {
702 LoadLoadingUnitFailure(loading_unit_id,
703 "No lib .so found for provided search paths.", true);
704 return;
705 }
708
709 // Resolve symbols.
710 std::unique_ptr<const fml::SymbolMapping> data_mapping =
711 std::make_unique<const fml::SymbolMapping>(
713 std::unique_ptr<const fml::SymbolMapping> instructions_mapping =
714 std::make_unique<const fml::SymbolMapping>(
716
717 ANDROID_SHELL_HOLDER->GetPlatformView()->LoadDartDeferredLibrary(
718 loading_unit_id, std::move(data_mapping),
719 std::move(instructions_mapping));
720}
721
722static void UpdateJavaAssetManager(JNIEnv* env,
723 jobject obj,
724 jlong shell_holder,
725 jobject jAssetManager,
726 jstring jAssetBundlePath) {
727 auto asset_resolver = std::make_unique<flutter::APKAssetProvider>(
728 env, // jni environment
729 jAssetManager, // asset manager
730 fml::jni::JavaStringToString(env, jAssetBundlePath)); // apk asset dir
731
732 ANDROID_SHELL_HOLDER->GetPlatformView()->UpdateAssetResolverByType(
733 std::move(asset_resolver),
735}
736
737bool RegisterApi(JNIEnv* env) {
738 static const JNINativeMethod flutter_jni_methods[] = {
739 // Start of methods from FlutterJNI
740 {
741 .name = "nativeAttach",
742 .signature = "(Lio/flutter/embedding/engine/FlutterJNI;)J",
743 .fnPtr = reinterpret_cast<void*>(&AttachJNI),
744 },
745 {
746 .name = "nativeDestroy",
747 .signature = "(J)V",
748 .fnPtr = reinterpret_cast<void*>(&DestroyJNI),
749 },
750 {
751 .name = "nativeSpawn",
752 .signature = "(JLjava/lang/String;Ljava/lang/String;Ljava/lang/"
753 "String;Ljava/util/List;J)Lio/flutter/"
754 "embedding/engine/FlutterJNI;",
755 .fnPtr = reinterpret_cast<void*>(&SpawnJNI),
756 },
757 {
758 .name = "nativeRunBundleAndSnapshotFromLibrary",
759 .signature = "(JLjava/lang/String;Ljava/lang/String;"
760 "Ljava/lang/String;Landroid/content/res/"
761 "AssetManager;Ljava/util/List;J)V",
762 .fnPtr = reinterpret_cast<void*>(&RunBundleAndSnapshotFromLibrary),
763 },
764 {
765 .name = "nativeDispatchEmptyPlatformMessage",
766 .signature = "(JLjava/lang/String;I)V",
767 .fnPtr = reinterpret_cast<void*>(&DispatchEmptyPlatformMessage),
768 },
769 {
770 .name = "nativeCleanupMessageData",
771 .signature = "(J)V",
772 .fnPtr = reinterpret_cast<void*>(&CleanupMessageData),
773 },
774 {
775 .name = "nativeDispatchPlatformMessage",
776 .signature = "(JLjava/lang/String;Ljava/nio/ByteBuffer;II)V",
777 .fnPtr = reinterpret_cast<void*>(&DispatchPlatformMessage),
778 },
779 {
780 .name = "nativeInvokePlatformMessageResponseCallback",
781 .signature = "(JILjava/nio/ByteBuffer;I)V",
782 .fnPtr =
783 reinterpret_cast<void*>(&InvokePlatformMessageResponseCallback),
784 },
785 {
786 .name = "nativeInvokePlatformMessageEmptyResponseCallback",
787 .signature = "(JI)V",
788 .fnPtr = reinterpret_cast<void*>(
790 },
791 {
792 .name = "nativeNotifyLowMemoryWarning",
793 .signature = "(J)V",
794 .fnPtr = reinterpret_cast<void*>(&NotifyLowMemoryWarning),
795 },
796
797 // Start of methods from FlutterView
798 {
799 .name = "nativeGetBitmap",
800 .signature = "(J)Landroid/graphics/Bitmap;",
801 .fnPtr = reinterpret_cast<void*>(&GetBitmap),
802 },
803 {
804 .name = "nativeSurfaceCreated",
805 .signature = "(JLandroid/view/Surface;)V",
806 .fnPtr = reinterpret_cast<void*>(&SurfaceCreated),
807 },
808 {
809 .name = "nativeSurfaceWindowChanged",
810 .signature = "(JLandroid/view/Surface;)V",
811 .fnPtr = reinterpret_cast<void*>(&SurfaceWindowChanged),
812 },
813 {
814 .name = "nativeSurfaceChanged",
815 .signature = "(JII)V",
816 .fnPtr = reinterpret_cast<void*>(&SurfaceChanged),
817 },
818 {
819 .name = "nativeSurfaceDestroyed",
820 .signature = "(J)V",
821 .fnPtr = reinterpret_cast<void*>(&SurfaceDestroyed),
822 },
823 {
824 .name = "nativeSetViewportMetrics",
825 .signature = "(JFIIIIIIIIIIIIIII[I[I[IIIIIIIII)V",
826 .fnPtr = reinterpret_cast<void*>(&SetViewportMetrics),
827 },
828 {
829 .name = "nativeDispatchPointerDataPacket",
830 .signature = "(JLjava/nio/ByteBuffer;I)V",
831 .fnPtr = reinterpret_cast<void*>(&DispatchPointerDataPacket),
832 },
833 {
834 .name = "nativeDispatchSemanticsAction",
835 .signature = "(JIILjava/nio/ByteBuffer;I)V",
836 .fnPtr = reinterpret_cast<void*>(&DispatchSemanticsAction),
837 },
838 {
839 .name = "nativeSetSemanticsEnabled",
840 .signature = "(JZ)V",
841 .fnPtr = reinterpret_cast<void*>(&SetSemanticsEnabled),
842 },
843 {
844 .name = "nativeSetAccessibilityFeatures",
845 .signature = "(JI)V",
846 .fnPtr = reinterpret_cast<void*>(&SetAccessibilityFeatures),
847 },
848 {
849 .name = "nativeGetIsSoftwareRenderingEnabled",
850 .signature = "()Z",
851 .fnPtr = reinterpret_cast<void*>(&GetIsSoftwareRendering),
852 },
853 {
854 .name = "nativeRegisterTexture",
855 .signature = "(JJLjava/lang/ref/"
856 "WeakReference;)V",
857 .fnPtr = reinterpret_cast<void*>(&RegisterTexture),
858 },
859 {
860 .name = "nativeRegisterImageTexture",
861 .signature = "(JJLjava/lang/ref/"
862 "WeakReference;Z)V",
863 .fnPtr = reinterpret_cast<void*>(&RegisterImageTexture),
864 },
865 {
866 .name = "nativeMarkTextureFrameAvailable",
867 .signature = "(JJ)V",
868 .fnPtr = reinterpret_cast<void*>(&MarkTextureFrameAvailable),
869 },
870 {
871 .name = "nativeScheduleFrame",
872 .signature = "(J)V",
873 .fnPtr = reinterpret_cast<void*>(&ScheduleFrame),
874 },
875 {
876 .name = "nativeUnregisterTexture",
877 .signature = "(JJ)V",
878 .fnPtr = reinterpret_cast<void*>(&UnregisterTexture),
879 },
880 // Methods for Dart callback functionality.
881 {
882 .name = "nativeLookupCallbackInformation",
883 .signature = "(J)Lio/flutter/view/FlutterCallbackInformation;",
884 .fnPtr = reinterpret_cast<void*>(&LookupCallbackInformation),
885 },
886
887 // Start of methods for FlutterTextUtils
888 {
889 .name = "nativeFlutterTextUtilsIsEmoji",
890 .signature = "(I)Z",
891 .fnPtr = reinterpret_cast<void*>(&FlutterTextUtilsIsEmoji),
892 },
893 {
894 .name = "nativeFlutterTextUtilsIsEmojiModifier",
895 .signature = "(I)Z",
896 .fnPtr = reinterpret_cast<void*>(&FlutterTextUtilsIsEmojiModifier),
897 },
898 {
899 .name = "nativeFlutterTextUtilsIsEmojiModifierBase",
900 .signature = "(I)Z",
901 .fnPtr =
902 reinterpret_cast<void*>(&FlutterTextUtilsIsEmojiModifierBase),
903 },
904 {
905 .name = "nativeFlutterTextUtilsIsVariationSelector",
906 .signature = "(I)Z",
907 .fnPtr =
908 reinterpret_cast<void*>(&FlutterTextUtilsIsVariationSelector),
909 },
910 {
911 .name = "nativeFlutterTextUtilsIsRegionalIndicator",
912 .signature = "(I)Z",
913 .fnPtr =
914 reinterpret_cast<void*>(&FlutterTextUtilsIsRegionalIndicator),
915 },
916 {
917 .name = "nativeLoadDartDeferredLibrary",
918 .signature = "(JI[Ljava/lang/String;)V",
919 .fnPtr = reinterpret_cast<void*>(&LoadDartDeferredLibrary),
920 },
921 {
922 .name = "nativeUpdateJavaAssetManager",
923 .signature =
924 "(JLandroid/content/res/AssetManager;Ljava/lang/String;)V",
925 .fnPtr = reinterpret_cast<void*>(&UpdateJavaAssetManager),
926 },
927 {
928 .name = "nativeDeferredComponentInstallFailure",
929 .signature = "(ILjava/lang/String;Z)V",
930 .fnPtr = reinterpret_cast<void*>(&DeferredComponentInstallFailure),
931 },
932 {
933 .name = "nativeUpdateDisplayMetrics",
934 .signature = "(J)V",
935 .fnPtr = reinterpret_cast<void*>(&UpdateDisplayMetrics),
936 },
937 {
938 .name = "nativeIsSurfaceControlEnabled",
939 .signature = "(J)Z",
940 .fnPtr = reinterpret_cast<void*>(&IsSurfaceControlEnabled),
941 }};
942
943 if (env->RegisterNatives(g_flutter_jni_class->obj(), flutter_jni_methods,
944 std::size(flutter_jni_methods)) != 0) {
945 FML_LOG(ERROR) << "Failed to RegisterNatives with FlutterJNI";
946 return false;
947 }
948
949 g_jni_shell_holder_field = env->GetFieldID(
950 g_flutter_jni_class->obj(), "nativeShellHolderId", "Ljava/lang/Long;");
951
952 if (g_jni_shell_holder_field == nullptr) {
953 FML_LOG(ERROR) << "Could not locate FlutterJNI's nativeShellHolderId field";
954 return false;
955 }
956
958 env->GetMethodID(g_flutter_jni_class->obj(), "<init>", "()V");
959
960 if (g_jni_constructor == nullptr) {
961 FML_LOG(ERROR) << "Could not locate FlutterJNI's constructor";
962 return false;
963 }
964
965 g_long_constructor = env->GetStaticMethodID(g_java_long_class->obj(),
966 "valueOf", "(J)Ljava/lang/Long;");
967 if (g_long_constructor == nullptr) {
968 FML_LOG(ERROR) << "Could not locate Long's constructor";
969 return false;
970 }
971
973
974 fml::jni::ScopedJavaLocalRef<jclass> overlay_surface_class(
975 env, env->FindClass("io/flutter/embedding/engine/FlutterOverlaySurface"));
976 if (overlay_surface_class.is_null()) {
977 FML_LOG(ERROR) << "Could not locate FlutterOverlaySurface class";
978 return false;
979 }
981 env->GetMethodID(overlay_surface_class.obj(), "getId", "()I");
982 if (g_overlay_surface_id_method == nullptr) {
983 FML_LOG(ERROR) << "Could not locate FlutterOverlaySurface#getId() method";
984 return false;
985 }
986 g_overlay_surface_surface_method = env->GetMethodID(
987 overlay_surface_class.obj(), "getSurface", "()Landroid/view/Surface;");
988 if (g_overlay_surface_surface_method == nullptr) {
989 FML_LOG(ERROR)
990 << "Could not locate FlutterOverlaySurface#getSurface() method";
991 return false;
992 }
993
995 env, env->FindClass("android/graphics/Bitmap"));
996 if (g_bitmap_class->is_null()) {
997 FML_LOG(ERROR) << "Could not locate Bitmap Class";
998 return false;
999 }
1000
1001 g_bitmap_create_bitmap_method = env->GetStaticMethodID(
1002 g_bitmap_class->obj(), "createBitmap",
1003 "(IILandroid/graphics/Bitmap$Config;)Landroid/graphics/Bitmap;");
1004 if (g_bitmap_create_bitmap_method == nullptr) {
1005 FML_LOG(ERROR) << "Could not locate Bitmap.createBitmap method";
1006 return false;
1007 }
1008
1009 g_bitmap_copy_pixels_from_buffer_method = env->GetMethodID(
1010 g_bitmap_class->obj(), "copyPixelsFromBuffer", "(Ljava/nio/Buffer;)V");
1012 FML_LOG(ERROR) << "Could not locate Bitmap.copyPixelsFromBuffer method";
1013 return false;
1014 }
1015
1017 env, env->FindClass("android/graphics/Bitmap$Config"));
1018 if (g_bitmap_config_class->is_null()) {
1019 FML_LOG(ERROR) << "Could not locate Bitmap.Config Class";
1020 return false;
1021 }
1022
1023 g_bitmap_config_value_of = env->GetStaticMethodID(
1024 g_bitmap_config_class->obj(), "valueOf",
1025 "(Ljava/lang/String;)Landroid/graphics/Bitmap$Config;");
1026 if (g_bitmap_config_value_of == nullptr) {
1027 FML_LOG(ERROR) << "Could not locate Bitmap.Config.valueOf method";
1028 return false;
1029 }
1030
1031 return true;
1032}
1033
1035 if (env == nullptr) {
1036 FML_LOG(ERROR) << "No JNIEnv provided";
1037 return false;
1038 }
1039
1041 env, env->FindClass("io/flutter/view/FlutterCallbackInformation"));
1042 if (g_flutter_callback_info_class->is_null()) {
1043 FML_LOG(ERROR) << "Could not locate FlutterCallbackInformation class";
1044 return false;
1045 }
1046
1047 g_flutter_callback_info_constructor = env->GetMethodID(
1048 g_flutter_callback_info_class->obj(), "<init>",
1049 "(Ljava/lang/String;Ljava/lang/String;Ljava/lang/String;)V");
1050 if (g_flutter_callback_info_constructor == nullptr) {
1051 FML_LOG(ERROR) << "Could not locate FlutterCallbackInformation constructor";
1052 return false;
1053 }
1054
1056 env, env->FindClass("io/flutter/embedding/engine/FlutterJNI"));
1057 if (g_flutter_jni_class->is_null()) {
1058 FML_LOG(ERROR) << "Failed to find FlutterJNI Class.";
1059 return false;
1060 }
1061
1063 env,
1064 env->FindClass(
1065 "io/flutter/embedding/engine/mutatorsstack/FlutterMutatorsStack"));
1066 if (g_mutators_stack_class == nullptr) {
1067 FML_LOG(ERROR) << "Could not locate FlutterMutatorsStack";
1068 return false;
1069 }
1070
1072 env->GetMethodID(g_mutators_stack_class->obj(), "<init>", "()V");
1073 if (g_mutators_stack_init_method == nullptr) {
1074 FML_LOG(ERROR) << "Could not locate FlutterMutatorsStack.init method";
1075 return false;
1076 }
1077
1079 env->GetMethodID(g_mutators_stack_class->obj(), "pushTransform", "([F)V");
1081 FML_LOG(ERROR)
1082 << "Could not locate FlutterMutatorsStack.pushTransform method";
1083 return false;
1084 }
1085
1086 g_mutators_stack_push_cliprect_method = env->GetMethodID(
1087 g_mutators_stack_class->obj(), "pushClipRect", "(IIII)V");
1089 FML_LOG(ERROR)
1090 << "Could not locate FlutterMutatorsStack.pushClipRect method";
1091 return false;
1092 }
1093
1094 g_mutators_stack_push_cliprrect_method = env->GetMethodID(
1095 g_mutators_stack_class->obj(), "pushClipRRect", "(IIII[F)V");
1097 FML_LOG(ERROR)
1098 << "Could not locate FlutterMutatorsStack.pushClipRRect method";
1099 return false;
1100 }
1101
1103 env->GetMethodID(g_mutators_stack_class->obj(), "pushOpacity", "(F)V");
1104 if (g_mutators_stack_push_opacity_method == nullptr) {
1105 FML_LOG(ERROR)
1106 << "Could not locate FlutterMutatorsStack.pushOpacity method";
1107 return false;
1108 }
1109
1111 env->GetMethodID(g_mutators_stack_class->obj(), "pushClipPath",
1112 "(Landroid/graphics/Path;)V");
1114 FML_LOG(ERROR)
1115 << "Could not locate FlutterMutatorsStack.pushClipPath method";
1116 return false;
1117 }
1118
1120 env, env->FindClass("java/lang/ref/WeakReference"));
1121 if (g_java_weak_reference_class->is_null()) {
1122 FML_LOG(ERROR) << "Could not locate WeakReference class";
1123 return false;
1124 }
1125
1126 g_java_weak_reference_get_method = env->GetMethodID(
1127 g_java_weak_reference_class->obj(), "get", "()Ljava/lang/Object;");
1128 if (g_java_weak_reference_get_method == nullptr) {
1129 FML_LOG(ERROR) << "Could not locate WeakReference.get method";
1130 return false;
1131 }
1132
1134 env, env->FindClass(
1135 "io/flutter/embedding/engine/renderer/SurfaceTextureWrapper"));
1136 if (g_texture_wrapper_class->is_null()) {
1137 FML_LOG(ERROR) << "Could not locate SurfaceTextureWrapper class";
1138 return false;
1139 }
1140
1141 g_attach_to_gl_context_method = env->GetMethodID(
1142 g_texture_wrapper_class->obj(), "attachToGLContext", "(I)V");
1143
1144 if (g_attach_to_gl_context_method == nullptr) {
1145 FML_LOG(ERROR) << "Could not locate attachToGlContext method";
1146 return false;
1147 }
1148
1150 env->GetMethodID(g_texture_wrapper_class->obj(), "shouldUpdate", "()Z");
1151
1153 FML_LOG(ERROR)
1154 << "Could not locate SurfaceTextureWrapper.shouldUpdate method";
1155 return false;
1156 }
1157
1159 env->GetMethodID(g_texture_wrapper_class->obj(), "updateTexImage", "()V");
1160
1161 if (g_update_tex_image_method == nullptr) {
1162 FML_LOG(ERROR) << "Could not locate updateTexImage method";
1163 return false;
1164 }
1165
1166 g_get_transform_matrix_method = env->GetMethodID(
1167 g_texture_wrapper_class->obj(), "getTransformMatrix", "([F)V");
1168
1169 if (g_get_transform_matrix_method == nullptr) {
1170 FML_LOG(ERROR) << "Could not locate getTransformMatrix method";
1171 return false;
1172 }
1173
1174 g_detach_from_gl_context_method = env->GetMethodID(
1175 g_texture_wrapper_class->obj(), "detachFromGLContext", "()V");
1176
1177 if (g_detach_from_gl_context_method == nullptr) {
1178 FML_LOG(ERROR) << "Could not locate detachFromGlContext method";
1179 return false;
1180 }
1183 env, env->FindClass("io/flutter/view/TextureRegistry$ImageConsumer"));
1185 FML_LOG(ERROR) << "Could not locate TextureRegistry.ImageConsumer class";
1186 return false;
1187 }
1188
1190 env->GetMethodID(g_image_consumer_texture_registry_interface->obj(),
1191 "acquireLatestImage", "()Landroid/media/Image;");
1192 if (g_acquire_latest_image_method == nullptr) {
1193 FML_LOG(ERROR) << "Could not locate acquireLatestImage on "
1194 "TextureRegistry.ImageConsumer class";
1195 return false;
1196 }
1197
1199 env, env->FindClass("android/media/Image"));
1200 if (g_image_class->is_null()) {
1201 FML_LOG(ERROR) << "Could not locate Image class";
1202 return false;
1203 }
1204
1205 // Ensure we don't have any pending exceptions.
1207
1209 env->GetMethodID(g_image_class->obj(), "getHardwareBuffer",
1210 "()Landroid/hardware/HardwareBuffer;");
1211
1212 if (g_image_get_hardware_buffer_method == nullptr) {
1213 // Continue on as this method may not exist at API <= 29.
1214 fml::jni::ClearException(env, true);
1215 }
1216
1217 g_image_close_method = env->GetMethodID(g_image_class->obj(), "close", "()V");
1218
1219 if (g_image_close_method == nullptr) {
1220 FML_LOG(ERROR) << "Could not locate close on Image class";
1221 return false;
1222 }
1223
1224 // Ensure we don't have any pending exceptions.
1227 env, env->FindClass("android/hardware/HardwareBuffer"));
1228
1229 if (!g_hardware_buffer_class->is_null()) {
1231 env->GetMethodID(g_hardware_buffer_class->obj(), "close", "()V");
1232 if (g_hardware_buffer_close_method == nullptr) {
1233 // Continue on as this class may not exist at API <= 26.
1234 fml::jni::ClearException(env, true);
1235 }
1236 } else {
1237 // Continue on as this class may not exist at API <= 26.
1238 fml::jni::ClearException(env, true);
1239 }
1240
1242 g_flutter_jni_class->obj(), "computePlatformResolvedLocale",
1243 "([Ljava/lang/String;)[Ljava/lang/String;");
1244
1246 FML_LOG(ERROR) << "Could not locate computePlatformResolvedLocale method";
1247 return false;
1248 }
1249
1250 g_request_dart_deferred_library_method = env->GetMethodID(
1251 g_flutter_jni_class->obj(), "requestDartDeferredLibrary", "(I)V");
1252
1254 FML_LOG(ERROR) << "Could not locate requestDartDeferredLibrary method";
1255 return false;
1256 }
1257
1259 env, env->FindClass("java/lang/Long"));
1260 if (g_java_long_class->is_null()) {
1261 FML_LOG(ERROR) << "Could not locate java.lang.Long class";
1262 return false;
1263 }
1264
1265 // Android path class and methods.
1267 env, env->FindClass("android/graphics/Path"));
1268 if (path_class->is_null()) {
1269 FML_LOG(ERROR) << "Could not locate android.graphics.Path class";
1270 return false;
1271 }
1272
1273 path_constructor = env->GetMethodID(path_class->obj(), "<init>", "()V");
1274 if (path_constructor == nullptr) {
1275 FML_LOG(ERROR) << "Could not locate android.graphics.Path constructor";
1276 return false;
1277 }
1278
1279 path_set_fill_type_method = env->GetMethodID(
1280 path_class->obj(), "setFillType", "(Landroid/graphics/Path$FillType;)V");
1281 if (path_set_fill_type_method == nullptr) {
1282 FML_LOG(ERROR)
1283 << "Could not locate android.graphics.Path.setFillType method";
1284 return false;
1285 }
1286
1287 path_move_to_method = env->GetMethodID(path_class->obj(), "moveTo", "(FF)V");
1288 if (path_move_to_method == nullptr) {
1289 FML_LOG(ERROR) << "Could not locate android.graphics.Path.moveTo method";
1290 return false;
1291 }
1292 path_line_to_method = env->GetMethodID(path_class->obj(), "lineTo", "(FF)V");
1293 if (path_line_to_method == nullptr) {
1294 FML_LOG(ERROR) << "Could not locate android.graphics.Path.lineTo method";
1295 return false;
1296 }
1298 env->GetMethodID(path_class->obj(), "quadTo", "(FFFF)V");
1299 if (path_quad_to_method == nullptr) {
1300 FML_LOG(ERROR) << "Could not locate android.graphics.Path.quadTo method";
1301 return false;
1302 }
1304 env->GetMethodID(path_class->obj(), "cubicTo", "(FFFFFF)V");
1305 if (path_cubic_to_method == nullptr) {
1306 FML_LOG(ERROR) << "Could not locate android.graphics.Path.cubicTo method";
1307 return false;
1308 }
1309 // Ensure we don't have any pending exceptions.
1311
1313 env->GetMethodID(path_class->obj(), "conicTo", "(FFFFF)V");
1314 if (path_conic_to_method == nullptr) {
1315 // Continue on as this method may not exist at API <= 34.
1316 fml::jni::ClearException(env, true);
1317 }
1318 path_close_method = env->GetMethodID(path_class->obj(), "close", "()V");
1319 if (path_close_method == nullptr) {
1320 FML_LOG(ERROR) << "Could not locate android.graphics.Path.close method";
1321 return false;
1322 }
1323
1325 env, env->FindClass("android/graphics/Path$FillType"));
1326 if (g_path_fill_type_class->is_null()) {
1327 FML_LOG(ERROR) << "Could not locate android.graphics.Path$FillType class";
1328 return false;
1329 }
1330
1332 env->GetStaticFieldID(g_path_fill_type_class->obj(), "WINDING",
1333 "Landroid/graphics/Path$FillType;");
1334 if (g_path_fill_type_winding_field == nullptr) {
1335 FML_LOG(ERROR) << "Could not locate Path.FillType.WINDING field";
1336 return false;
1337 }
1338
1340 env->GetStaticFieldID(g_path_fill_type_class->obj(), "EVEN_ODD",
1341 "Landroid/graphics/Path$FillType;");
1342 if (g_path_fill_type_even_odd_field == nullptr) {
1343 FML_LOG(ERROR) << "Could not locate Path.FillType.EVEN_ODD field";
1344 return false;
1345 }
1346
1347 return RegisterApi(env);
1348}
1349
1351 const fml::jni::JavaObjectWeakGlobalRef& java_object)
1352 : java_object_(java_object) {}
1353
1355
1357 std::unique_ptr<flutter::PlatformMessage> message,
1358 int responseId) {
1359 // Called from any thread.
1360 JNIEnv* env = fml::jni::AttachCurrentThread();
1361
1362 auto java_object = java_object_.get(env);
1363 if (java_object.is_null()) {
1364 return;
1365 }
1366
1368 fml::jni::StringToJavaString(env, message->channel());
1369
1370 if (message->hasData()) {
1372 env, env->NewDirectByteBuffer(
1373 const_cast<uint8_t*>(message->data().GetMapping()),
1374 message->data().GetSize()));
1375 // Message data is deleted in CleanupMessageData.
1376 fml::MallocMapping mapping = message->releaseData();
1377 env->CallVoidMethod(java_object.obj(), g_handle_platform_message_method,
1378 java_channel.obj(), message_array.obj(), responseId,
1379 reinterpret_cast<jlong>(mapping.Release()));
1380 } else {
1381 env->CallVoidMethod(java_object.obj(), g_handle_platform_message_method,
1382 java_channel.obj(), nullptr, responseId, nullptr);
1383 }
1384
1386}
1387
1389 std::string locale) {
1390 JNIEnv* env = fml::jni::AttachCurrentThread();
1391
1392 auto java_object = java_object_.get(env);
1393 if (java_object.is_null()) {
1394 return;
1395 }
1396
1398 fml::jni::StringToJavaString(env, locale);
1399
1400 env->CallVoidMethod(java_object.obj(), g_set_application_locale_method,
1401 jlocale.obj());
1402
1404}
1405
1407 bool enabled) {
1408 JNIEnv* env = fml::jni::AttachCurrentThread();
1409
1410 auto java_object = java_object_.get(env);
1411 if (java_object.is_null()) {
1412 return;
1413 }
1414
1415 env->CallVoidMethod(java_object.obj(), g_set_semantics_tree_enabled_method,
1416 enabled);
1417
1419}
1420
1422 int responseId,
1423 std::unique_ptr<fml::Mapping> data) {
1424 // We are on the platform thread. Attempt to get the strong reference to
1425 // the Java object.
1426 JNIEnv* env = fml::jni::AttachCurrentThread();
1427
1428 auto java_object = java_object_.get(env);
1429 if (java_object.is_null()) {
1430 // The Java object was collected before this message response got to
1431 // it. Drop the response on the floor.
1432 return;
1433 }
1434 if (data == nullptr) { // Empty response.
1435 env->CallVoidMethod(java_object.obj(),
1436 g_handle_platform_message_response_method, responseId,
1437 nullptr);
1438 } else {
1439 // Convert the vector to a Java byte array.
1441 env, env->NewDirectByteBuffer(const_cast<uint8_t*>(data->GetMapping()),
1442 data->GetSize()));
1443
1444 env->CallVoidMethod(java_object.obj(),
1445 g_handle_platform_message_response_method, responseId,
1446 data_array.obj());
1447 }
1448
1450}
1451
1453 double font_size,
1454 int configuration_id) const {
1455 JNIEnv* env = fml::jni::AttachCurrentThread();
1456
1457 auto java_object = java_object_.get(env);
1458 if (java_object.is_null()) {
1459 return -3;
1460 }
1461
1462 const jfloat scaledSize = env->CallFloatMethod(
1463 java_object.obj(), g_get_scaled_font_size_method,
1464 static_cast<jfloat>(font_size), static_cast<jint>(configuration_id));
1466 return static_cast<double>(scaledSize);
1467}
1468
1470 std::vector<uint8_t> buffer,
1471 std::vector<std::string> strings,
1472 std::vector<std::vector<uint8_t>> string_attribute_args) {
1473 JNIEnv* env = fml::jni::AttachCurrentThread();
1474
1475 auto java_object = java_object_.get(env);
1476 if (java_object.is_null()) {
1477 return;
1478 }
1479
1481 env, env->NewDirectByteBuffer(buffer.data(), buffer.size()));
1483 fml::jni::VectorToStringArray(env, strings);
1484 fml::jni::ScopedJavaLocalRef<jobjectArray> jstring_attribute_args =
1485 fml::jni::VectorToBufferArray(env, string_attribute_args);
1486
1487 env->CallVoidMethod(java_object.obj(), g_update_semantics_method,
1488 direct_buffer.obj(), jstrings.obj(),
1489 jstring_attribute_args.obj());
1490
1492}
1493
1495 std::vector<uint8_t> actions_buffer,
1496 std::vector<std::string> strings) {
1497 JNIEnv* env = fml::jni::AttachCurrentThread();
1498
1499 auto java_object = java_object_.get(env);
1500 if (java_object.is_null()) {
1501 return;
1502 }
1503
1504 fml::jni::ScopedJavaLocalRef<jobject> direct_actions_buffer(
1505 env,
1506 env->NewDirectByteBuffer(actions_buffer.data(), actions_buffer.size()));
1507
1509 fml::jni::VectorToStringArray(env, strings);
1510
1511 env->CallVoidMethod(java_object.obj(),
1512 g_update_custom_accessibility_actions_method,
1513 direct_actions_buffer.obj(), jstrings.obj());
1514
1516}
1517
1519 JNIEnv* env = fml::jni::AttachCurrentThread();
1520
1521 auto java_object = java_object_.get(env);
1522 if (java_object.is_null()) {
1523 return;
1524 }
1525
1526 env->CallVoidMethod(java_object.obj(), g_on_first_frame_method);
1527
1529}
1530
1532 JNIEnv* env = fml::jni::AttachCurrentThread();
1533
1534 auto java_object = java_object_.get(env);
1535 if (java_object.is_null()) {
1536 return;
1537 }
1538
1539 env->CallVoidMethod(java_object.obj(), g_on_engine_restart_method);
1540
1542}
1543
1545 JavaLocalRef surface_texture,
1546 int textureId) {
1547 JNIEnv* env = fml::jni::AttachCurrentThread();
1548
1549 if (surface_texture.is_null()) {
1550 return;
1551 }
1552
1553 fml::jni::ScopedJavaLocalRef<jobject> surface_texture_local_ref(
1554 env, env->CallObjectMethod(surface_texture.obj(),
1556
1557 if (surface_texture_local_ref.is_null()) {
1558 return;
1559 }
1560
1561 env->CallVoidMethod(surface_texture_local_ref.obj(),
1563
1565}
1566
1568 JavaLocalRef surface_texture) {
1569 JNIEnv* env = fml::jni::AttachCurrentThread();
1570
1571 if (surface_texture.is_null()) {
1572 return false;
1573 }
1574
1575 fml::jni::ScopedJavaLocalRef<jobject> surface_texture_local_ref(
1576 env, env->CallObjectMethod(surface_texture.obj(),
1578 if (surface_texture_local_ref.is_null()) {
1579 return false;
1580 }
1581
1582 jboolean shouldUpdate = env->CallBooleanMethod(
1583 surface_texture_local_ref.obj(), g_surface_texture_wrapper_should_update);
1584
1586
1587 return shouldUpdate;
1588}
1589
1591 JavaLocalRef surface_texture) {
1592 JNIEnv* env = fml::jni::AttachCurrentThread();
1593
1594 if (surface_texture.is_null()) {
1595 return;
1596 }
1597
1598 fml::jni::ScopedJavaLocalRef<jobject> surface_texture_local_ref(
1599 env, env->CallObjectMethod(surface_texture.obj(),
1601 if (surface_texture_local_ref.is_null()) {
1602 return;
1603 }
1604
1605 env->CallVoidMethod(surface_texture_local_ref.obj(),
1607
1609}
1610
1612 JavaLocalRef surface_texture) {
1613 JNIEnv* env = fml::jni::AttachCurrentThread();
1614
1615 if (surface_texture.is_null()) {
1616 return {};
1617 }
1618
1619 fml::jni::ScopedJavaLocalRef<jobject> surface_texture_local_ref(
1620 env, env->CallObjectMethod(surface_texture.obj(),
1622 if (surface_texture_local_ref.is_null()) {
1623 return {};
1624 }
1625
1627 env, env->NewFloatArray(16));
1628
1629 env->CallVoidMethod(surface_texture_local_ref.obj(),
1630 g_get_transform_matrix_method, transformMatrix.obj());
1632
1633 float* m = env->GetFloatArrayElements(transformMatrix.obj(), nullptr);
1634
1635 static_assert(sizeof(SkScalar) == sizeof(float));
1636 const auto transform = SkM44::ColMajor(m);
1637
1638 env->ReleaseFloatArrayElements(transformMatrix.obj(), m, JNI_ABORT);
1639
1640 return transform;
1641}
1642
1644 JavaLocalRef surface_texture) {
1645 JNIEnv* env = fml::jni::AttachCurrentThread();
1646
1647 if (surface_texture.is_null()) {
1648 return;
1649 }
1650
1651 fml::jni::ScopedJavaLocalRef<jobject> surface_texture_local_ref(
1652 env, env->CallObjectMethod(surface_texture.obj(),
1654 if (surface_texture_local_ref.is_null()) {
1655 return;
1656 }
1657
1658 env->CallVoidMethod(surface_texture_local_ref.obj(),
1660
1662}
1663
1666 JavaLocalRef image_producer_texture_entry) {
1667 JNIEnv* env = fml::jni::AttachCurrentThread();
1668
1669 if (image_producer_texture_entry.is_null()) {
1670 // Return null.
1671 return JavaLocalRef();
1672 }
1673
1674 // Convert the weak reference to ImageTextureEntry into a strong local
1675 // reference.
1676 fml::jni::ScopedJavaLocalRef<jobject> image_producer_texture_entry_local_ref(
1677 env, env->CallObjectMethod(image_producer_texture_entry.obj(),
1679
1680 if (image_producer_texture_entry_local_ref.is_null()) {
1681 // Return null.
1682 return JavaLocalRef();
1683 }
1684
1686 env, env->CallObjectMethod(image_producer_texture_entry_local_ref.obj(),
1688 if (fml::jni::CheckException(env)) {
1689 return r;
1690 }
1691 // Return null.
1692 return JavaLocalRef();
1693}
1694
1698 JNIEnv* env = fml::jni::AttachCurrentThread();
1699 if (image.is_null()) {
1700 // Return null.
1701 return JavaLocalRef();
1702 }
1704 env,
1705 env->CallObjectMethod(image.obj(), g_image_get_hardware_buffer_method));
1706 if (fml::jni::ClearException(env, false)) {
1707 return JavaLocalRef();
1708 }
1709 return r;
1710}
1711
1713 JNIEnv* env = fml::jni::AttachCurrentThread();
1714 if (image.is_null()) {
1715 return;
1716 }
1717 env->CallVoidMethod(image.obj(), g_image_close_method);
1719}
1720
1722 JavaLocalRef hardware_buffer) {
1724 JNIEnv* env = fml::jni::AttachCurrentThread();
1725 if (hardware_buffer.is_null()) {
1726 return;
1727 }
1728 env->CallVoidMethod(hardware_buffer.obj(), g_hardware_buffer_close_method);
1730}
1731
1733 int view_id,
1734 int x,
1735 int y,
1736 int width,
1737 int height,
1738 int viewWidth,
1739 int viewHeight,
1740 MutatorsStack mutators_stack) {
1741 JNIEnv* env = fml::jni::AttachCurrentThread();
1742 auto java_object = java_object_.get(env);
1743 if (java_object.is_null()) {
1744 return;
1745 }
1746
1747 jobject mutatorsStack = env->NewObject(g_mutators_stack_class->obj(),
1749
1750 std::vector<std::shared_ptr<Mutator>>::const_iterator iter =
1751 mutators_stack.Begin();
1752 while (iter != mutators_stack.End()) {
1753 switch ((*iter)->GetType()) {
1755 const DlMatrix& matrix = (*iter)->GetMatrix();
1756 DlScalar matrix_array[9]{
1757 matrix.m[0], matrix.m[4], matrix.m[12], //
1758 matrix.m[1], matrix.m[5], matrix.m[13], //
1759 matrix.m[3], matrix.m[7], matrix.m[15],
1760 };
1762 env, env->NewFloatArray(9));
1763
1764 env->SetFloatArrayRegion(transformMatrix.obj(), 0, 9, matrix_array);
1765 env->CallVoidMethod(mutatorsStack,
1767 transformMatrix.obj());
1768 break;
1769 }
1771 const DlRect& rect = (*iter)->GetRect();
1772 env->CallVoidMethod(mutatorsStack,
1774 static_cast<int>(rect.GetLeft()), //
1775 static_cast<int>(rect.GetTop()), //
1776 static_cast<int>(rect.GetRight()), //
1777 static_cast<int>(rect.GetBottom()));
1778 break;
1779 }
1781 const DlRoundRect& rrect = (*iter)->GetRRect();
1782 const DlRect& rect = rrect.GetBounds();
1783 const DlRoundingRadii radii = rrect.GetRadii();
1784 SkScalar radiis[8] = {
1785 radii.top_left.width, radii.top_left.height,
1786 radii.top_right.width, radii.top_right.height,
1788 radii.bottom_left.width, radii.bottom_left.height,
1789 };
1791 env, env->NewFloatArray(8));
1792 env->SetFloatArrayRegion(radiisArray.obj(), 0, 8, radiis);
1793 env->CallVoidMethod(mutatorsStack,
1795 static_cast<int>(rect.GetLeft()), //
1796 static_cast<int>(rect.GetTop()), //
1797 static_cast<int>(rect.GetRight()), //
1798 static_cast<int>(rect.GetBottom()), //
1799 radiisArray.obj());
1800 break;
1801 }
1802 case MutatorType::kClipRSE: {
1803 const DlRoundRect& rrect = (*iter)->GetRSEApproximation();
1804 const DlRect& rect = rrect.GetBounds();
1805 const DlRoundingRadii radii = rrect.GetRadii();
1806 SkScalar radiis[8] = {
1807 radii.top_left.width, radii.top_left.height,
1808 radii.top_right.width, radii.top_right.height,
1810 radii.bottom_left.width, radii.bottom_left.height,
1811 };
1813 env, env->NewFloatArray(8));
1814 env->SetFloatArrayRegion(radiisArray.obj(), 0, 8, radiis);
1815 env->CallVoidMethod(mutatorsStack,
1817 static_cast<int>(rect.GetLeft()), //
1818 static_cast<int>(rect.GetTop()), //
1819 static_cast<int>(rect.GetRight()), //
1820 static_cast<int>(rect.GetBottom()), //
1821 radiisArray.obj());
1822 break;
1823 }
1824 // TODO(cyanglaz): Implement other mutators.
1825 // https://github.com/flutter/flutter/issues/58426
1833 break;
1834 }
1835 ++iter;
1836 }
1837
1838 env->CallVoidMethod(java_object.obj(), g_on_display_platform_view_method,
1839 view_id, x, y, width, height, viewWidth, viewHeight,
1840 mutatorsStack);
1841
1843}
1844
1846 int surface_id,
1847 int x,
1848 int y,
1849 int width,
1850 int height) {
1851 JNIEnv* env = fml::jni::AttachCurrentThread();
1852
1853 auto java_object = java_object_.get(env);
1854 if (java_object.is_null()) {
1855 return;
1856 }
1857
1858 env->CallVoidMethod(java_object.obj(), g_on_display_overlay_surface_method,
1859 surface_id, x, y, width, height);
1860
1862}
1863
1865 JNIEnv* env = fml::jni::AttachCurrentThread();
1866
1867 auto java_object = java_object_.get(env);
1868 if (java_object.is_null()) {
1869 return;
1870 }
1871
1872 env->CallVoidMethod(java_object.obj(), g_on_begin_frame_method);
1873
1875}
1876
1878 JNIEnv* env = fml::jni::AttachCurrentThread();
1879
1880 auto java_object = java_object_.get(env);
1881 if (java_object.is_null()) {
1882 return;
1883 }
1884
1885 env->CallVoidMethod(java_object.obj(), g_on_end_frame_method);
1886
1888}
1889
1890std::unique_ptr<PlatformViewAndroidJNI::OverlayMetadata>
1892 JNIEnv* env = fml::jni::AttachCurrentThread();
1893
1894 auto java_object = java_object_.get(env);
1895 if (java_object.is_null()) {
1896 return nullptr;
1897 }
1898
1900 env, env->CallObjectMethod(java_object.obj(),
1901 g_create_overlay_surface_method));
1903
1904 if (overlay.is_null()) {
1905 return std::make_unique<PlatformViewAndroidJNI::OverlayMetadata>(0,
1906 nullptr);
1907 }
1908
1909 jint overlay_id =
1910 env->CallIntMethod(overlay.obj(), g_overlay_surface_id_method);
1911
1912 jobject overlay_surface =
1913 env->CallObjectMethod(overlay.obj(), g_overlay_surface_surface_method);
1914
1915 auto overlay_window = fml::MakeRefCounted<AndroidNativeWindow>(
1916 ANativeWindow_fromSurface(env, overlay_surface));
1917
1918 return std::make_unique<PlatformViewAndroidJNI::OverlayMetadata>(
1919 overlay_id, std::move(overlay_window));
1920}
1921
1923 JNIEnv* env = fml::jni::AttachCurrentThread();
1924
1925 auto java_object = java_object_.get(env);
1926 if (java_object.is_null()) {
1927 return;
1928 }
1929
1930 env->CallVoidMethod(java_object.obj(), g_destroy_overlay_surfaces_method);
1931
1933}
1934
1935std::unique_ptr<std::vector<std::string>>
1937 std::vector<std::string> supported_locales_data) {
1938 JNIEnv* env = fml::jni::AttachCurrentThread();
1939
1940 std::unique_ptr<std::vector<std::string>> out =
1941 std::make_unique<std::vector<std::string>>();
1942
1943 auto java_object = java_object_.get(env);
1944 if (java_object.is_null()) {
1945 return out;
1946 }
1948 fml::jni::VectorToStringArray(env, supported_locales_data);
1949 jobjectArray result = static_cast<jobjectArray>(env->CallObjectMethod(
1951 j_locales_data.obj()));
1952
1954
1955 int length = env->GetArrayLength(result);
1956 for (int i = 0; i < length; i++) {
1957 out->emplace_back(fml::jni::JavaStringToString(
1958 env, static_cast<jstring>(env->GetObjectArrayElement(result, i))));
1959 }
1960 return out;
1961}
1962
1964 JNIEnv* env = fml::jni::AttachCurrentThread();
1965
1966 auto java_object = java_object_.get(env);
1967 if (java_object.is_null()) {
1969 }
1970
1972 env, env->GetObjectClass(java_object.obj()));
1973 if (clazz.is_null()) {
1975 }
1976
1977 jfieldID fid = env->GetStaticFieldID(clazz.obj(), "refreshRateFPS", "F");
1978 return static_cast<double>(env->GetStaticFloatField(clazz.obj(), fid));
1979}
1980
1982 JNIEnv* env = fml::jni::AttachCurrentThread();
1983
1984 auto java_object = java_object_.get(env);
1985 if (java_object.is_null()) {
1986 return -1;
1987 }
1988
1990 env, env->GetObjectClass(java_object.obj()));
1991 if (clazz.is_null()) {
1992 return -1;
1993 }
1994
1995 jfieldID fid = env->GetStaticFieldID(clazz.obj(), "displayWidth", "F");
1996 return static_cast<double>(env->GetStaticFloatField(clazz.obj(), fid));
1997}
1998
2000 JNIEnv* env = fml::jni::AttachCurrentThread();
2001
2002 auto java_object = java_object_.get(env);
2003 if (java_object.is_null()) {
2004 return -1;
2005 }
2006
2008 env, env->GetObjectClass(java_object.obj()));
2009 if (clazz.is_null()) {
2010 return -1;
2011 }
2012
2013 jfieldID fid = env->GetStaticFieldID(clazz.obj(), "displayHeight", "F");
2014 return static_cast<double>(env->GetStaticFloatField(clazz.obj(), fid));
2015}
2016
2018 JNIEnv* env = fml::jni::AttachCurrentThread();
2019
2020 auto java_object = java_object_.get(env);
2021 if (java_object.is_null()) {
2022 return -1;
2023 }
2024
2026 env, env->GetObjectClass(java_object.obj()));
2027 if (clazz.is_null()) {
2028 return -1;
2029 }
2030
2031 jfieldID fid = env->GetStaticFieldID(clazz.obj(), "displayDensity", "F");
2032 return static_cast<double>(env->GetStaticFloatField(clazz.obj(), fid));
2033}
2034
2036 int loading_unit_id) {
2037 JNIEnv* env = fml::jni::AttachCurrentThread();
2038
2039 auto java_object = java_object_.get(env);
2040 if (java_object.is_null()) {
2041 return true;
2042 }
2043
2044 env->CallVoidMethod(java_object.obj(), g_request_dart_deferred_library_method,
2045 loading_unit_id);
2046
2048 return true;
2049}
2050
2051// New Platform View Support.
2052
2054 JNIEnv* env = fml::jni::AttachCurrentThread();
2055
2056 auto java_object = java_object_.get(env);
2057 if (java_object.is_null()) {
2058 return nullptr;
2059 }
2060
2062 env,
2063 env->CallObjectMethod(java_object.obj(), g_create_transaction_method));
2064 if (transaction.is_null()) {
2065 return nullptr;
2066 }
2068
2069 return impeller::android::GetProcTable().ASurfaceTransaction_fromJava(
2070 env, transaction.obj());
2071}
2072
2074 JNIEnv* env = fml::jni::AttachCurrentThread();
2075
2076 auto java_object = java_object_.get(env);
2077 if (java_object.is_null()) {
2078 return;
2079 }
2080
2081 env->CallVoidMethod(java_object.obj(), g_swap_transaction_method);
2082
2084}
2085
2087 JNIEnv* env = fml::jni::AttachCurrentThread();
2088
2089 auto java_object = java_object_.get(env);
2090 if (java_object.is_null()) {
2091 return;
2092 }
2093
2094 env->CallVoidMethod(java_object.obj(), g_apply_transaction_method);
2095
2097}
2098
2099std::unique_ptr<PlatformViewAndroidJNI::OverlayMetadata>
2101 JNIEnv* env = fml::jni::AttachCurrentThread();
2102
2103 auto java_object = java_object_.get(env);
2104 if (java_object.is_null()) {
2105 return nullptr;
2106 }
2107
2109 env, env->CallObjectMethod(java_object.obj(),
2110 g_create_overlay_surface2_method));
2112
2113 if (overlay.is_null()) {
2114 return std::make_unique<PlatformViewAndroidJNI::OverlayMetadata>(0,
2115 nullptr);
2116 }
2117
2118 jint overlay_id =
2119 env->CallIntMethod(overlay.obj(), g_overlay_surface_id_method);
2120
2121 jobject overlay_surface =
2122 env->CallObjectMethod(overlay.obj(), g_overlay_surface_surface_method);
2123
2124 auto overlay_window = fml::MakeRefCounted<AndroidNativeWindow>(
2125 ANativeWindow_fromSurface(env, overlay_surface));
2126
2127 return std::make_unique<PlatformViewAndroidJNI::OverlayMetadata>(
2128 overlay_id, std::move(overlay_window));
2129}
2130
2132 JNIEnv* env = fml::jni::AttachCurrentThread();
2133
2134 auto java_object = java_object_.get(env);
2135 if (java_object.is_null()) {
2136 return;
2137 }
2138
2139 env->CallVoidMethod(java_object.obj(), g_destroy_overlay_surface2_method);
2140
2142}
2143
2144namespace {
2145class AndroidPathReceiver final : public DlPathReceiver {
2146 public:
2147 explicit AndroidPathReceiver(JNIEnv* env)
2148 : env_(env),
2149 android_path_(env->NewObject(path_class->obj(), path_constructor)) {}
2150
2151 void SetFillType(DlPathFillType type) {
2152 jfieldID fill_type_field_id;
2153 switch (type) {
2154 case DlPathFillType::kOdd:
2155 fill_type_field_id = g_path_fill_type_even_odd_field;
2156 break;
2157 case DlPathFillType::kNonZero:
2158 fill_type_field_id = g_path_fill_type_winding_field;
2159 break;
2160 default:
2161 // DlPathFillType does not have corresponding kInverseEvenOdd or
2162 // kInverseWinding fill types.
2163 return;
2164 }
2165
2166 // Get the static enum field value (Path.FillType.WINDING or
2167 // Path.FillType.EVEN_ODD)
2170 env_, env_->GetStaticObjectField(g_path_fill_type_class->obj(),
2171 fill_type_field_id));
2173 FML_CHECK(!fill_type_enum.is_null());
2174
2175 // Call Path.setFillType(Path.FillType)
2176 env_->CallVoidMethod(android_path_, path_set_fill_type_method,
2177 fill_type_enum.obj());
2179 }
2180
2181 void MoveTo(const DlPoint& p2, bool will_be_closed) override {
2182 env_->CallVoidMethod(android_path_, path_move_to_method, p2.x, p2.y);
2183 }
2184 void LineTo(const DlPoint& p2) override {
2185 env_->CallVoidMethod(android_path_, path_line_to_method, p2.x, p2.y);
2186 }
2187 void QuadTo(const DlPoint& cp, const DlPoint& p2) override {
2188 env_->CallVoidMethod(android_path_, path_quad_to_method, //
2189 cp.x, cp.y, p2.x, p2.y);
2190 }
2191 bool ConicTo(const DlPoint& cp, const DlPoint& p2, DlScalar weight) override {
2192 if (!path_conic_to_method) {
2193 return false;
2194 }
2195 env_->CallVoidMethod(android_path_, path_conic_to_method, //
2196 cp.x, cp.y, p2.x, p2.y, weight);
2197 return true;
2198 };
2199 void CubicTo(const DlPoint& cp1,
2200 const DlPoint& cp2,
2201 const DlPoint& p2) override {
2202 env_->CallVoidMethod(android_path_, path_cubic_to_method, //
2203 cp1.x, cp1.y, cp2.x, cp2.y, p2.x, p2.y);
2204 }
2205 void Close() override {
2206 env_->CallVoidMethod(android_path_, path_close_method);
2207 }
2208
2209 jobject TakePath() const { return android_path_; }
2210
2211 private:
2212 JNIEnv* env_;
2213 jobject android_path_;
2214};
2215} // namespace
2216
2218 int32_t view_id,
2219 int32_t x,
2220 int32_t y,
2221 int32_t width,
2222 int32_t height,
2223 int32_t viewWidth,
2224 int32_t viewHeight,
2225 MutatorsStack mutators_stack) {
2226 JNIEnv* env = fml::jni::AttachCurrentThread();
2227 auto java_object = java_object_.get(env);
2228 if (java_object.is_null()) {
2229 return;
2230 }
2231
2232 jobject mutatorsStack = env->NewObject(g_mutators_stack_class->obj(),
2234
2235 std::vector<std::shared_ptr<Mutator>>::const_iterator iter =
2236 mutators_stack.Begin();
2237 while (iter != mutators_stack.End()) {
2238 switch ((*iter)->GetType()) {
2240 const DlMatrix& matrix = (*iter)->GetMatrix();
2241 DlScalar matrix_array[9]{
2242 matrix.m[0], matrix.m[4], matrix.m[12], //
2243 matrix.m[1], matrix.m[5], matrix.m[13], //
2244 matrix.m[3], matrix.m[7], matrix.m[15],
2245 };
2247 env, env->NewFloatArray(9));
2248
2249 env->SetFloatArrayRegion(transformMatrix.obj(), 0, 9, matrix_array);
2250 env->CallVoidMethod(mutatorsStack,
2252 transformMatrix.obj());
2253 break;
2254 }
2256 const DlRect& rect = (*iter)->GetRect();
2257 env->CallVoidMethod(mutatorsStack,
2259 static_cast<int>(rect.GetLeft()), //
2260 static_cast<int>(rect.GetTop()), //
2261 static_cast<int>(rect.GetRight()), //
2262 static_cast<int>(rect.GetBottom()));
2263 break;
2264 }
2266 const DlRoundRect& rrect = (*iter)->GetRRect();
2267 const DlRect& rect = rrect.GetBounds();
2268 const DlRoundingRadii& radii = rrect.GetRadii();
2269 SkScalar radiis[8] = {
2270 radii.top_left.width, radii.top_left.height,
2271 radii.top_right.width, radii.top_right.height,
2273 radii.bottom_left.width, radii.bottom_left.height,
2274 };
2276 env, env->NewFloatArray(8));
2277 env->SetFloatArrayRegion(radiisArray.obj(), 0, 8, radiis);
2278 env->CallVoidMethod(mutatorsStack,
2280 static_cast<int>(rect.GetLeft()), //
2281 static_cast<int>(rect.GetTop()), //
2282 static_cast<int>(rect.GetRight()), //
2283 static_cast<int>(rect.GetBottom()), //
2284 radiisArray.obj());
2285 break;
2286 }
2287 case MutatorType::kClipRSE: {
2288 const DlRoundRect& rrect = (*iter)->GetRSEApproximation();
2289 const DlRect& rect = rrect.GetBounds();
2290 const DlRoundingRadii& radii = rrect.GetRadii();
2291 SkScalar radiis[8] = {
2292 radii.top_left.width, radii.top_left.height,
2293 radii.top_right.width, radii.top_right.height,
2295 radii.bottom_left.width, radii.bottom_left.height,
2296 };
2298 env, env->NewFloatArray(8));
2299 env->SetFloatArrayRegion(radiisArray.obj(), 0, 8, radiis);
2300 env->CallVoidMethod(mutatorsStack,
2302 static_cast<int>(rect.GetLeft()), //
2303 static_cast<int>(rect.GetTop()), //
2304 static_cast<int>(rect.GetRight()), //
2305 static_cast<int>(rect.GetBottom()), //
2306 radiisArray.obj());
2307 break;
2308 }
2309 case MutatorType::kOpacity: {
2310 float opacity = (*iter)->GetAlphaFloat();
2311 env->CallVoidMethod(mutatorsStack, g_mutators_stack_push_opacity_method,
2312 opacity);
2313 break;
2314 }
2316 auto& dlPath = (*iter)->GetPath();
2317 // The layer mutator mechanism should have already caught and
2318 // redirected these simplified path cases, which is important because
2319 // the conics they generate (in the case of oval and rrect) will
2320 // not match the results of an impeller path conversion very closely.
2321 FML_DCHECK(!dlPath.IsRect());
2322 FML_DCHECK(!dlPath.IsOval());
2323 FML_DCHECK(!dlPath.IsRoundRect());
2324
2325 // Define and populate an Android Path with data from the DlPath
2326 AndroidPathReceiver receiver(env);
2327 receiver.SetFillType(dlPath.GetFillType());
2328
2329 // TODO(flar): https://github.com/flutter/flutter/issues/164808
2330 // Need to convert the fill type to the Android enum and
2331 // call setFillType on the path...
2332 dlPath.Dispatch(receiver);
2333
2334 env->CallVoidMethod(mutatorsStack,
2336 receiver.TakePath());
2337 break;
2338 }
2339 // TODO(cyanglaz): Implement other mutators.
2340 // https://github.com/flutter/flutter/issues/58426
2346 break;
2347 }
2348 ++iter;
2349 }
2350
2351 env->CallVoidMethod(java_object.obj(), g_on_display_platform_view2_method,
2352 view_id, x, y, width, height, viewWidth, viewHeight,
2353 mutatorsStack);
2354
2356}
2357
2359 JNIEnv* env = fml::jni::AttachCurrentThread();
2360 auto java_object = java_object_.get(env);
2361 if (java_object.is_null()) {
2362 return;
2363 }
2364
2365 env->CallVoidMethod(java_object.obj(), g_hide_platform_view2_method, view_id);
2366}
2367
2369 JNIEnv* env = fml::jni::AttachCurrentThread();
2370
2371 auto java_object = java_object_.get(env);
2372 if (java_object.is_null()) {
2373 return;
2374 }
2375
2376 env->CallVoidMethod(java_object.obj(), g_on_end_frame2_method);
2377
2379}
2380
2382 JNIEnv* env = fml::jni::AttachCurrentThread();
2383
2384 auto java_object = java_object_.get(env);
2385 if (java_object.is_null()) {
2386 return;
2387 }
2388
2389 env->CallVoidMethod(java_object.obj(), g_show_overlay_surface2_method);
2391}
2392
2394 JNIEnv* env = fml::jni::AttachCurrentThread();
2395
2396 auto java_object = java_object_.get(env);
2397 if (java_object.is_null()) {
2398 return;
2399 }
2400
2401 env->CallVoidMethod(java_object.obj(), g_hide_overlay_surface2_method);
2403}
2404
2406 int32_t height) const {
2407 JNIEnv* env = fml::jni::AttachCurrentThread();
2408
2409 auto java_object = java_object_.get(env);
2410 if (java_object.is_null()) {
2411 return;
2412 }
2413
2414 env->CallVoidMethod(java_object.obj(), g_maybe_resize_surface_view, width,
2415 height);
2417}
2418
2419} // namespace flutter
static std::unique_ptr< DartCallbackRepresentation > GetCallbackInformation(int64_t handle)
static const char * kIsolateDataSymbol
static const char * kIsolateInstructionsSymbol
const flutter::Settings & GetSettings() const
static FlutterMain & Get()
ImageLifecycle
Whether the last image should be reset when the context is destroyed.
const std::vector< std::shared_ptr< Mutator > >::const_iterator End() const
const std::vector< std::shared_ptr< Mutator > >::const_iterator Begin() const
void HardwareBufferClose(JavaLocalRef hardware_buffer) override
Call close on hardware_buffer.
bool RequestDartDeferredLibrary(int loading_unit_id) override
SkM44 SurfaceTextureGetTransformMatrix(JavaLocalRef surface_texture) override
Gets the transform matrix from the SurfaceTexture. Then, it updates the transform matrix,...
void MaybeResizeSurfaceView(int32_t width, int32_t height) const override
void FlutterViewDisplayOverlaySurface(int surface_id, int x, int y, int width, int height) override
Positions and sizes an overlay surface in hybrid composition.
void SurfaceTextureUpdateTexImage(JavaLocalRef surface_texture) override
Updates the texture image to the most recent frame from the image stream.
void FlutterViewEndFrame() override
Indicates that the current frame ended. It's used to clean up state.
void SurfaceTextureAttachToGLContext(JavaLocalRef surface_texture, int textureId) override
Attach the SurfaceTexture to the OpenGL ES context that is current on the calling thread.
void FlutterViewOnFirstFrame() override
Indicates that FlutterView should start painting pixels.
void FlutterViewSetApplicationLocale(std::string locale) override
Set application locale to a given language.
PlatformViewAndroidJNIImpl(const fml::jni::JavaObjectWeakGlobalRef &java_object)
void FlutterViewUpdateCustomAccessibilityActions(std::vector< uint8_t > actions_buffer, std::vector< std::string > strings) override
Sends new custom accessibility events.
void FlutterViewBeginFrame() override
Initiates a frame if using hybrid composition.
void SurfaceTextureDetachFromGLContext(JavaLocalRef surface_texture) override
Detaches a SurfaceTexture from the OpenGL ES context.
std::unique_ptr< PlatformViewAndroidJNI::OverlayMetadata > createOverlaySurface2() override
void onDisplayPlatformView2(int32_t view_id, int32_t x, int32_t y, int32_t width, int32_t height, int32_t viewWidth, int32_t viewHeight, MutatorsStack mutators_stack) override
bool SurfaceTextureShouldUpdate(JavaLocalRef surface_texture) override
Returns true if surface_texture should be updated.
void FlutterViewDestroyOverlaySurfaces() override
Destroys the overlay surfaces.
void FlutterViewOnDisplayPlatformView(int view_id, int x, int y, int width, int height, int viewWidth, int viewHeight, MutatorsStack mutators_stack) override
Positions and sizes a platform view if using hybrid composition.
void FlutterViewHandlePlatformMessageResponse(int responseId, std::unique_ptr< fml::Mapping > data) override
Responds to a platform message. The data may be a nullptr.
double FlutterViewGetScaledFontSize(double unscaled_font_size, int configuration_id) const override
JavaLocalRef ImageGetHardwareBuffer(JavaLocalRef image) override
Grab the HardwareBuffer from image.
std::unique_ptr< PlatformViewAndroidJNI::OverlayMetadata > FlutterViewCreateOverlaySurface() override
Instantiates an overlay surface in hybrid composition and provides the necessary metadata to operate ...
void FlutterViewSetSemanticsTreeEnabled(bool enabled) override
Enables or disables the semantics tree.
void FlutterViewUpdateSemantics(std::vector< uint8_t > buffer, std::vector< std::string > strings, std::vector< std::vector< uint8_t > > string_attribute_args) override
Sends semantics tree updates.
JavaLocalRef ImageProducerTextureEntryAcquireLatestImage(JavaLocalRef image_texture_entry) override
Acquire the latest image available.
void FlutterViewHandlePlatformMessage(std::unique_ptr< flutter::PlatformMessage > message, int responseId) override
Sends a platform message. The message may be empty.
void ImageClose(JavaLocalRef image) override
Call close on image.
void FlutterViewOnPreEngineRestart() override
Indicates that a hot restart is about to happen.
std::unique_ptr< std::vector< std::string > > FlutterViewComputePlatformResolvedLocale(std::vector< std::string > supported_locales_data) override
Computes the locale Android would select.
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)
ScopedJavaLocalRef< jobject > get(JNIEnv *env) const
Collection of functions to receive path segments from the underlying path representation via the DlPa...
Definition path_source.h:42
int32_t x
FlutterVulkanImage * image
GLFWwindow * window
Definition main.cc:60
const char * message
G_BEGIN_DECLS G_MODULE_EXPORT FlValue * args
const gchar * channel
G_BEGIN_DECLS FlutterViewId view_id
#define FML_LOG(severity)
Definition logging.h:101
#define FML_CHECK(condition)
Definition logging.h:104
#define FML_DCHECK(condition)
Definition logging.h:122
std::shared_ptr< SkBitmap > bitmap
size_t length
double y
static jmethodID g_hardware_buffer_close_method
impeller::Scalar DlScalar
static void RunBundleAndSnapshotFromLibrary(JNIEnv *env, jobject jcaller, jlong shell_holder, jstring jBundlePath, jstring jEntrypoint, jstring jLibraryUrl, jobject jAssetManager, jobject jEntrypointArgs, jlong engineId)
static jmethodID g_mutators_stack_init_method
constexpr int64_t kFlutterImplicitViewId
Definition constants.h:35
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 bool IsSurfaceControlEnabled(JNIEnv *env, jobject jcaller, jlong shell_holder)
static void DispatchPointerDataPacket(JNIEnv *env, jobject jcaller, jlong shell_holder, jobject buffer, jint position)
bool RegisterApi(JNIEnv *env)
static jmethodID g_mutators_stack_push_clippath_method
static jboolean FlutterTextUtilsIsEmojiModifier(JNIEnv *env, jobject obj, jint codePoint)
static fml::jni::ScopedJavaGlobalRef< jclass > * path_class
static fml::jni::ScopedJavaGlobalRef< jclass > * g_java_long_class
static void LoadLoadingUnitFailure(intptr_t loading_unit_id, const std::string &message, bool transient)
static void InvokePlatformMessageEmptyResponseCallback(JNIEnv *env, jobject jcaller, jlong shell_holder, jint responseId)
impeller::ISize32 DlISize
static jmethodID g_acquire_latest_image_method
static jmethodID g_mutators_stack_push_transform_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 path_line_to_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 switch_defs.h:52
static jmethodID path_quad_to_method
static jmethodID g_long_constructor
static void DestroyJNI(JNIEnv *env, jobject jcaller, jlong shell_holder)
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 jfieldID g_path_fill_type_even_odd_field
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 jobject SpawnJNI(JNIEnv *env, jobject jcaller, jlong shell_holder, jstring jEntrypoint, jstring jLibraryUrl, jstring jInitialRoute, jobject jEntrypointArgs, jlong engineId)
static jfieldID g_path_fill_type_winding_field
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 void CleanupMessageData(JNIEnv *env, jobject jcaller, jlong message_data)
static jmethodID g_mutators_stack_push_cliprect_method
static jmethodID g_overlay_surface_surface_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, jint physicalMinWidth, jint physicalMaxWidth, jint physicalMinHeight, jint physicalMaxHeight, jint physicalDisplayCornerRadiusTopLeft, jint physicalDisplayCornerRadiusTopRight, jint physicalDisplayCornerRadiusBottomRight, jint physicalDisplayCornerRadiusBottomLeft)
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 switch_defs.h:36
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 path_cubic_to_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
impeller::FillType DlPathFillType
Definition dl_path.h:16
static void RegisterImageTexture(JNIEnv *env, jobject jcaller, jlong shell_holder, jlong texture_id, jobject image_texture_entry, jboolean reset_on_background)
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 jmethodID path_set_fill_type_method
static void DispatchEmptyPlatformMessage(JNIEnv *env, jobject jcaller, jlong shell_holder, jstring channel, jint responseId)
static fml::jni::ScopedJavaGlobalRef< jclass > * g_path_fill_type_class
static void ScheduleFrame(JNIEnv *env, jobject jcaller, jlong shell_holder)
static jmethodID path_move_to_method
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_image_close_method
static void UpdateDisplayMetrics(JNIEnv *env, jobject jcaller, jlong shell_holder)
static jmethodID g_mutators_stack_push_opacity_method
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 void UpdateJavaAssetManager(JNIEnv *env, jobject obj, jlong shell_holder, jobject jAssetManager, jstring jAssetBundlePath)
static jobject GetBitmap(JNIEnv *env, jobject jcaller, jlong shell_holder)
static jmethodID path_constructor
static jmethodID g_bitmap_create_bitmap_method
static void UnregisterTexture(JNIEnv *env, jobject jcaller, jlong shell_holder, jlong texture_id)
impeller::Point DlPoint
static fml::jni::ScopedJavaGlobalRef< jclass > * g_flutter_callback_info_class
static fml::jni::ScopedJavaGlobalRef< jclass > * g_mutators_stack_class
static jmethodID path_close_method
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
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 to the cache directory This is different from the persistent_cache_path in embedder which is used for Skia shader cache icu native lib Path to the library file that exports the ICU data vm service The hostname IP address on which the Dart VM Service should be served If not defaults to or::depending on whether ipv6 is specified disable vm Disable the Dart VM Service The Dart VM Service is never available in release mode Bind to the IPv6 localhost address for the Dart VM Service Ignored if vm service host is set profile Make the profiler discard new samples once the profiler sample buffer is full When this flag is not the profiler sample buffer is used as a ring buffer
Definition switch_defs.h:98
static jmethodID path_conic_to_method
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)
static constexpr double kUnknownDisplayRefreshRate
To be used when the display refresh rate is unknown.
Definition display.h:20
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
const ProcTable & GetProcTable()
Definition proc_table.cc:12
void MoveTo(PathBuilder *builder, Scalar x, Scalar y)
void LineTo(PathBuilder *builder, Scalar x, Scalar y)
void CubicTo(PathBuilder *builder, Scalar x1, Scalar y1, Scalar x2, Scalar y2, Scalar x3, Scalar y3)
void Close(PathBuilder *builder)
#define ANDROID_SHELL_HOLDER
#define FLUTTER_BIND_JNI(global_field, jni_name, jni_arg)
#define FLUTTER_DECLARE_JNI(global_field, jni_name, jni_arg)
*end#*‍/
#define FLUTTER_FOR_EACH_JNI_METHOD(V)
impeller::ShaderType type
int32_t height
int32_t width
bool enable_software_rendering
Definition settings.h:320
A 4x4 matrix using column-major storage.
Definition matrix.h:37
Scalar m[16]
Definition matrix.h:39
constexpr const RoundingRadii & GetRadii() const
Definition round_rect.h:55
constexpr const Rect & GetBounds() const
Definition round_rect.h:53
constexpr auto GetBottom() const
Definition rect.h:391
constexpr auto GetTop() const
Definition rect.h:387
constexpr auto GetLeft() const
Definition rect.h:385
constexpr auto GetRight() const
Definition rect.h:389
Type height
Definition size.h:29
Type width
Definition size.h:28
Scalar font_size
int64_t texture_id