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 env->GetIntArrayRegion(javaDisplayFeaturesBounds, 0, rectSize,
369 &boundsIntVector[0]);
370 std::vector<double> displayFeaturesBounds(boundsIntVector.begin(),
371 boundsIntVector.end());
372 jsize typeSize = env->GetArrayLength(javaDisplayFeaturesType);
373 std::vector<int> displayFeaturesType(typeSize);
374 env->GetIntArrayRegion(javaDisplayFeaturesType, 0, typeSize,
375 &displayFeaturesType[0]);
376
377 jsize stateSize = env->GetArrayLength(javaDisplayFeaturesState);
378 std::vector<int> displayFeaturesState(stateSize);
379 env->GetIntArrayRegion(javaDisplayFeaturesState, 0, stateSize,
380 &displayFeaturesState[0]);
381
382 const flutter::ViewportMetrics metrics{
383 static_cast<double>(devicePixelRatio), // p_device_pixel_ratio
384 static_cast<double>(physicalWidth), // p_physical_width
385 static_cast<double>(physicalHeight), // p_physical_height
386 static_cast<double>(physicalMinWidth), // p_physical_min_width_constraint
387 static_cast<double>(physicalMaxWidth), // p_physical_max_width_constraint
388 static_cast<double>(
389 physicalMinHeight), // p_physical_min_height_constraint
390 static_cast<double>(
391 physicalMaxHeight), // p_physical_max_height_constraint
392 static_cast<double>(physicalPaddingTop), // p_physical_padding_top
393 static_cast<double>(physicalPaddingRight), // p_physical_padding_right
394 static_cast<double>(physicalPaddingBottom), // p_physical_padding_bottom
395 static_cast<double>(physicalPaddingLeft), // p_physical_padding_left
396 static_cast<double>(physicalViewInsetTop), // p_physical_view_inset_top
397 static_cast<double>(
398 physicalViewInsetRight), // p_physical_view_inset_right
399 static_cast<double>(
400 physicalViewInsetBottom), // p_physical_view_inset_bottom
401 static_cast<double>(physicalViewInsetLeft), // p_physical_view_inset_left
402 static_cast<double>(
403 systemGestureInsetTop), // p_physical_system_gesture_inset_top
404 static_cast<double>(
405 systemGestureInsetRight), // p_physical_system_gesture_inset_right
406 static_cast<double>(
407 systemGestureInsetBottom), // p_physical_system_gesture_inset_bottom
408 static_cast<double>(
409 systemGestureInsetLeft), // p_physical_system_gesture_inset_left
410 static_cast<double>(physicalTouchSlop), // p_physical_touch_slop
411 displayFeaturesBounds, // p_physical_display_features_bounds
412 displayFeaturesType, // p_physical_display_features_type
413 displayFeaturesState, // p_physical_display_features_state
414 0, // p_display_id,
415 static_cast<double>(
416 physicalDisplayCornerRadiusTopLeft), // p_physical_display_corner_radius_top_left
417 static_cast<double>(
418 physicalDisplayCornerRadiusTopRight), // p_physical_display_corner_radius_top_right
419 static_cast<double>(
420 physicalDisplayCornerRadiusBottomRight), // p_physical_display_corner_radius_bottom_right
421 static_cast<double>(
422 physicalDisplayCornerRadiusBottomLeft), // p_physical_display_corner_radius_bottom_left
423 };
424
425 ANDROID_SHELL_HOLDER->GetPlatformView()->SetViewportMetrics(
426 kFlutterImplicitViewId, metrics);
427}
428
429static void UpdateDisplayMetrics(JNIEnv* env,
430 jobject jcaller,
431 jlong shell_holder) {
432 ANDROID_SHELL_HOLDER->UpdateDisplayMetrics();
433}
434
435static bool IsSurfaceControlEnabled(JNIEnv* env,
436 jobject jcaller,
437 jlong shell_holder) {
438 return ANDROID_SHELL_HOLDER->IsSurfaceControlEnabled();
439}
440
441static jobject GetBitmap(JNIEnv* env, jobject jcaller, jlong shell_holder) {
442 auto screenshot = ANDROID_SHELL_HOLDER->Screenshot(
444 if (screenshot.data == nullptr) {
445 return nullptr;
446 }
447
448 jstring argb = env->NewStringUTF("ARGB_8888");
449 if (argb == nullptr) {
450 return nullptr;
451 }
452
453 jobject bitmap_config = env->CallStaticObjectMethod(
455 if (bitmap_config == nullptr) {
456 return nullptr;
457 }
458
459 auto bitmap = env->CallStaticObjectMethod(
461 screenshot.frame_size.width, screenshot.frame_size.height, bitmap_config);
462
464 env,
465 env->NewDirectByteBuffer(const_cast<uint8_t*>(screenshot.data->bytes()),
466 screenshot.data->size()));
467
469 buffer.obj());
470
471 return bitmap;
472}
473
474static void DispatchPlatformMessage(JNIEnv* env,
475 jobject jcaller,
476 jlong shell_holder,
477 jstring channel,
478 jobject message,
479 jint position,
480 jint responseId) {
481 ANDROID_SHELL_HOLDER->GetPlatformView()->DispatchPlatformMessage(
482 env, //
484 message, //
485 position, //
486 responseId //
487 );
488}
489
490static void DispatchEmptyPlatformMessage(JNIEnv* env,
491 jobject jcaller,
492 jlong shell_holder,
493 jstring channel,
494 jint responseId) {
495 ANDROID_SHELL_HOLDER->GetPlatformView()->DispatchEmptyPlatformMessage(
496 env, //
498 responseId //
499 );
500}
501
502static void CleanupMessageData(JNIEnv* env,
503 jobject jcaller,
504 jlong message_data) {
505 // Called from any thread.
506 free(reinterpret_cast<void*>(message_data));
507}
508
509static void DispatchPointerDataPacket(JNIEnv* env,
510 jobject jcaller,
511 jlong shell_holder,
512 jobject buffer,
513 jint position) {
514 uint8_t* data = static_cast<uint8_t*>(env->GetDirectBufferAddress(buffer));
515 auto packet = std::make_unique<flutter::PointerDataPacket>(data, position);
516 ANDROID_SHELL_HOLDER->GetPlatformView()->DispatchPointerDataPacket(
517 std::move(packet));
518}
519
520static void DispatchSemanticsAction(JNIEnv* env,
521 jobject jcaller,
522 jlong shell_holder,
523 jint id,
524 jint action,
525 jobject args,
526 jint args_position) {
527 ANDROID_SHELL_HOLDER->GetPlatformView()->DispatchSemanticsAction(
528 env, //
529 id, //
530 action, //
531 args, //
532 args_position //
533 );
534}
535
536static void SetSemanticsEnabled(JNIEnv* env,
537 jobject jcaller,
538 jlong shell_holder,
539 jboolean enabled) {
540 ANDROID_SHELL_HOLDER->GetPlatformView()->SetSemanticsEnabled(enabled);
541}
542
543static void SetAccessibilityFeatures(JNIEnv* env,
544 jobject jcaller,
545 jlong shell_holder,
546 jint flags) {
547 ANDROID_SHELL_HOLDER->GetPlatformView()->SetAccessibilityFeatures(flags);
548}
549
550static jboolean GetIsSoftwareRendering(JNIEnv* env, jobject jcaller) {
552}
553
554static void RegisterTexture(JNIEnv* env,
555 jobject jcaller,
556 jlong shell_holder,
557 jlong texture_id,
558 jobject surface_texture) {
559 ANDROID_SHELL_HOLDER->GetPlatformView()->RegisterExternalTexture(
560 static_cast<int64_t>(texture_id), //
561 fml::jni::ScopedJavaGlobalRef<jobject>(env, surface_texture) //
562 );
563}
564
565static void RegisterImageTexture(JNIEnv* env,
566 jobject jcaller,
567 jlong shell_holder,
568 jlong texture_id,
569 jobject image_texture_entry,
570 jboolean reset_on_background) {
574
575 ANDROID_SHELL_HOLDER->GetPlatformView()->RegisterImageTexture(
576 static_cast<int64_t>(texture_id), //
577 fml::jni::ScopedJavaGlobalRef<jobject>(env, image_texture_entry), //
578 lifecycle //
579 );
580}
581
582static void UnregisterTexture(JNIEnv* env,
583 jobject jcaller,
584 jlong shell_holder,
585 jlong texture_id) {
586 ANDROID_SHELL_HOLDER->GetPlatformView()->UnregisterTexture(
587 static_cast<int64_t>(texture_id));
588}
589
590static void MarkTextureFrameAvailable(JNIEnv* env,
591 jobject jcaller,
592 jlong shell_holder,
593 jlong texture_id) {
594 ANDROID_SHELL_HOLDER->GetPlatformView()->MarkTextureFrameAvailable(
595 static_cast<int64_t>(texture_id));
596}
597
598static void ScheduleFrame(JNIEnv* env, jobject jcaller, jlong shell_holder) {
599 ANDROID_SHELL_HOLDER->GetPlatformView()->ScheduleFrame();
600}
601
603 jobject jcaller,
604 jlong shell_holder,
605 jint responseId,
606 jobject message,
607 jint position) {
608 uint8_t* response_data =
609 static_cast<uint8_t*>(env->GetDirectBufferAddress(message));
610 FML_DCHECK(response_data != nullptr);
611 auto mapping = std::make_unique<fml::MallocMapping>(
612 fml::MallocMapping::Copy(response_data, response_data + position));
613 ANDROID_SHELL_HOLDER->GetPlatformMessageHandler()
614 ->InvokePlatformMessageResponseCallback(responseId, std::move(mapping));
615}
616
618 jobject jcaller,
619 jlong shell_holder,
620 jint responseId) {
621 ANDROID_SHELL_HOLDER->GetPlatformMessageHandler()
622 ->InvokePlatformMessageEmptyResponseCallback(responseId);
623}
624
625static void NotifyLowMemoryWarning(JNIEnv* env,
626 jobject obj,
627 jlong shell_holder) {
628 ANDROID_SHELL_HOLDER->NotifyLowMemoryWarning();
629}
630
631static jboolean FlutterTextUtilsIsEmoji(JNIEnv* env,
632 jobject obj,
633 jint codePoint) {
634 return u_hasBinaryProperty(codePoint, UProperty::UCHAR_EMOJI);
635}
636
637static jboolean FlutterTextUtilsIsEmojiModifier(JNIEnv* env,
638 jobject obj,
639 jint codePoint) {
640 return u_hasBinaryProperty(codePoint, UProperty::UCHAR_EMOJI_MODIFIER);
641}
642
643static jboolean FlutterTextUtilsIsEmojiModifierBase(JNIEnv* env,
644 jobject obj,
645 jint codePoint) {
646 return u_hasBinaryProperty(codePoint, UProperty::UCHAR_EMOJI_MODIFIER_BASE);
647}
648
649static jboolean FlutterTextUtilsIsVariationSelector(JNIEnv* env,
650 jobject obj,
651 jint codePoint) {
652 return u_hasBinaryProperty(codePoint, UProperty::UCHAR_VARIATION_SELECTOR);
653}
654
655static jboolean FlutterTextUtilsIsRegionalIndicator(JNIEnv* env,
656 jobject obj,
657 jint codePoint) {
658 return u_hasBinaryProperty(codePoint, UProperty::UCHAR_REGIONAL_INDICATOR);
659}
660
661static void LoadLoadingUnitFailure(intptr_t loading_unit_id,
662 const std::string& message,
663 bool transient) {
664 // TODO(garyq): Implement
665}
666
667static void DeferredComponentInstallFailure(JNIEnv* env,
668 jobject obj,
669 jint jLoadingUnitId,
670 jstring jError,
671 jboolean jTransient) {
672 LoadLoadingUnitFailure(static_cast<intptr_t>(jLoadingUnitId),
673 fml::jni::JavaStringToString(env, jError),
674 static_cast<bool>(jTransient));
675}
676
677static void LoadDartDeferredLibrary(JNIEnv* env,
678 jobject obj,
679 jlong shell_holder,
680 jint jLoadingUnitId,
681 jobjectArray jSearchPaths) {
682 // Convert java->c++
683 intptr_t loading_unit_id = static_cast<intptr_t>(jLoadingUnitId);
684 std::vector<std::string> search_paths =
685 fml::jni::StringArrayToVector(env, jSearchPaths);
686
687 // Use dlopen here to directly check if handle is nullptr before creating a
688 // NativeLibrary.
689 void* handle = nullptr;
690 while (handle == nullptr && !search_paths.empty()) {
691 std::string path = search_paths.back();
692 handle = ::dlopen(path.c_str(), RTLD_NOW);
693 search_paths.pop_back();
694 }
695 if (handle == nullptr) {
696 LoadLoadingUnitFailure(loading_unit_id,
697 "No lib .so found for provided search paths.", true);
698 return;
699 }
702
703 // Resolve symbols.
704 std::unique_ptr<const fml::SymbolMapping> data_mapping =
705 std::make_unique<const fml::SymbolMapping>(
707 std::unique_ptr<const fml::SymbolMapping> instructions_mapping =
708 std::make_unique<const fml::SymbolMapping>(
710
711 ANDROID_SHELL_HOLDER->GetPlatformView()->LoadDartDeferredLibrary(
712 loading_unit_id, std::move(data_mapping),
713 std::move(instructions_mapping));
714}
715
716static void UpdateJavaAssetManager(JNIEnv* env,
717 jobject obj,
718 jlong shell_holder,
719 jobject jAssetManager,
720 jstring jAssetBundlePath) {
721 auto asset_resolver = std::make_unique<flutter::APKAssetProvider>(
722 env, // jni environment
723 jAssetManager, // asset manager
724 fml::jni::JavaStringToString(env, jAssetBundlePath)); // apk asset dir
725
726 ANDROID_SHELL_HOLDER->GetPlatformView()->UpdateAssetResolverByType(
727 std::move(asset_resolver),
729}
730
731bool RegisterApi(JNIEnv* env) {
732 static const JNINativeMethod flutter_jni_methods[] = {
733 // Start of methods from FlutterJNI
734 {
735 .name = "nativeAttach",
736 .signature = "(Lio/flutter/embedding/engine/FlutterJNI;)J",
737 .fnPtr = reinterpret_cast<void*>(&AttachJNI),
738 },
739 {
740 .name = "nativeDestroy",
741 .signature = "(J)V",
742 .fnPtr = reinterpret_cast<void*>(&DestroyJNI),
743 },
744 {
745 .name = "nativeSpawn",
746 .signature = "(JLjava/lang/String;Ljava/lang/String;Ljava/lang/"
747 "String;Ljava/util/List;J)Lio/flutter/"
748 "embedding/engine/FlutterJNI;",
749 .fnPtr = reinterpret_cast<void*>(&SpawnJNI),
750 },
751 {
752 .name = "nativeRunBundleAndSnapshotFromLibrary",
753 .signature = "(JLjava/lang/String;Ljava/lang/String;"
754 "Ljava/lang/String;Landroid/content/res/"
755 "AssetManager;Ljava/util/List;J)V",
756 .fnPtr = reinterpret_cast<void*>(&RunBundleAndSnapshotFromLibrary),
757 },
758 {
759 .name = "nativeDispatchEmptyPlatformMessage",
760 .signature = "(JLjava/lang/String;I)V",
761 .fnPtr = reinterpret_cast<void*>(&DispatchEmptyPlatformMessage),
762 },
763 {
764 .name = "nativeCleanupMessageData",
765 .signature = "(J)V",
766 .fnPtr = reinterpret_cast<void*>(&CleanupMessageData),
767 },
768 {
769 .name = "nativeDispatchPlatformMessage",
770 .signature = "(JLjava/lang/String;Ljava/nio/ByteBuffer;II)V",
771 .fnPtr = reinterpret_cast<void*>(&DispatchPlatformMessage),
772 },
773 {
774 .name = "nativeInvokePlatformMessageResponseCallback",
775 .signature = "(JILjava/nio/ByteBuffer;I)V",
776 .fnPtr =
777 reinterpret_cast<void*>(&InvokePlatformMessageResponseCallback),
778 },
779 {
780 .name = "nativeInvokePlatformMessageEmptyResponseCallback",
781 .signature = "(JI)V",
782 .fnPtr = reinterpret_cast<void*>(
784 },
785 {
786 .name = "nativeNotifyLowMemoryWarning",
787 .signature = "(J)V",
788 .fnPtr = reinterpret_cast<void*>(&NotifyLowMemoryWarning),
789 },
790
791 // Start of methods from FlutterView
792 {
793 .name = "nativeGetBitmap",
794 .signature = "(J)Landroid/graphics/Bitmap;",
795 .fnPtr = reinterpret_cast<void*>(&GetBitmap),
796 },
797 {
798 .name = "nativeSurfaceCreated",
799 .signature = "(JLandroid/view/Surface;)V",
800 .fnPtr = reinterpret_cast<void*>(&SurfaceCreated),
801 },
802 {
803 .name = "nativeSurfaceWindowChanged",
804 .signature = "(JLandroid/view/Surface;)V",
805 .fnPtr = reinterpret_cast<void*>(&SurfaceWindowChanged),
806 },
807 {
808 .name = "nativeSurfaceChanged",
809 .signature = "(JII)V",
810 .fnPtr = reinterpret_cast<void*>(&SurfaceChanged),
811 },
812 {
813 .name = "nativeSurfaceDestroyed",
814 .signature = "(J)V",
815 .fnPtr = reinterpret_cast<void*>(&SurfaceDestroyed),
816 },
817 {
818 .name = "nativeSetViewportMetrics",
819 .signature = "(JFIIIIIIIIIIIIIII[I[I[IIIIIIIII)V",
820 .fnPtr = reinterpret_cast<void*>(&SetViewportMetrics),
821 },
822 {
823 .name = "nativeDispatchPointerDataPacket",
824 .signature = "(JLjava/nio/ByteBuffer;I)V",
825 .fnPtr = reinterpret_cast<void*>(&DispatchPointerDataPacket),
826 },
827 {
828 .name = "nativeDispatchSemanticsAction",
829 .signature = "(JIILjava/nio/ByteBuffer;I)V",
830 .fnPtr = reinterpret_cast<void*>(&DispatchSemanticsAction),
831 },
832 {
833 .name = "nativeSetSemanticsEnabled",
834 .signature = "(JZ)V",
835 .fnPtr = reinterpret_cast<void*>(&SetSemanticsEnabled),
836 },
837 {
838 .name = "nativeSetAccessibilityFeatures",
839 .signature = "(JI)V",
840 .fnPtr = reinterpret_cast<void*>(&SetAccessibilityFeatures),
841 },
842 {
843 .name = "nativeGetIsSoftwareRenderingEnabled",
844 .signature = "()Z",
845 .fnPtr = reinterpret_cast<void*>(&GetIsSoftwareRendering),
846 },
847 {
848 .name = "nativeRegisterTexture",
849 .signature = "(JJLjava/lang/ref/"
850 "WeakReference;)V",
851 .fnPtr = reinterpret_cast<void*>(&RegisterTexture),
852 },
853 {
854 .name = "nativeRegisterImageTexture",
855 .signature = "(JJLjava/lang/ref/"
856 "WeakReference;Z)V",
857 .fnPtr = reinterpret_cast<void*>(&RegisterImageTexture),
858 },
859 {
860 .name = "nativeMarkTextureFrameAvailable",
861 .signature = "(JJ)V",
862 .fnPtr = reinterpret_cast<void*>(&MarkTextureFrameAvailable),
863 },
864 {
865 .name = "nativeScheduleFrame",
866 .signature = "(J)V",
867 .fnPtr = reinterpret_cast<void*>(&ScheduleFrame),
868 },
869 {
870 .name = "nativeUnregisterTexture",
871 .signature = "(JJ)V",
872 .fnPtr = reinterpret_cast<void*>(&UnregisterTexture),
873 },
874 // Methods for Dart callback functionality.
875 {
876 .name = "nativeLookupCallbackInformation",
877 .signature = "(J)Lio/flutter/view/FlutterCallbackInformation;",
878 .fnPtr = reinterpret_cast<void*>(&LookupCallbackInformation),
879 },
880
881 // Start of methods for FlutterTextUtils
882 {
883 .name = "nativeFlutterTextUtilsIsEmoji",
884 .signature = "(I)Z",
885 .fnPtr = reinterpret_cast<void*>(&FlutterTextUtilsIsEmoji),
886 },
887 {
888 .name = "nativeFlutterTextUtilsIsEmojiModifier",
889 .signature = "(I)Z",
890 .fnPtr = reinterpret_cast<void*>(&FlutterTextUtilsIsEmojiModifier),
891 },
892 {
893 .name = "nativeFlutterTextUtilsIsEmojiModifierBase",
894 .signature = "(I)Z",
895 .fnPtr =
896 reinterpret_cast<void*>(&FlutterTextUtilsIsEmojiModifierBase),
897 },
898 {
899 .name = "nativeFlutterTextUtilsIsVariationSelector",
900 .signature = "(I)Z",
901 .fnPtr =
902 reinterpret_cast<void*>(&FlutterTextUtilsIsVariationSelector),
903 },
904 {
905 .name = "nativeFlutterTextUtilsIsRegionalIndicator",
906 .signature = "(I)Z",
907 .fnPtr =
908 reinterpret_cast<void*>(&FlutterTextUtilsIsRegionalIndicator),
909 },
910 {
911 .name = "nativeLoadDartDeferredLibrary",
912 .signature = "(JI[Ljava/lang/String;)V",
913 .fnPtr = reinterpret_cast<void*>(&LoadDartDeferredLibrary),
914 },
915 {
916 .name = "nativeUpdateJavaAssetManager",
917 .signature =
918 "(JLandroid/content/res/AssetManager;Ljava/lang/String;)V",
919 .fnPtr = reinterpret_cast<void*>(&UpdateJavaAssetManager),
920 },
921 {
922 .name = "nativeDeferredComponentInstallFailure",
923 .signature = "(ILjava/lang/String;Z)V",
924 .fnPtr = reinterpret_cast<void*>(&DeferredComponentInstallFailure),
925 },
926 {
927 .name = "nativeUpdateDisplayMetrics",
928 .signature = "(J)V",
929 .fnPtr = reinterpret_cast<void*>(&UpdateDisplayMetrics),
930 },
931 {
932 .name = "nativeIsSurfaceControlEnabled",
933 .signature = "(J)Z",
934 .fnPtr = reinterpret_cast<void*>(&IsSurfaceControlEnabled),
935 }};
936
937 if (env->RegisterNatives(g_flutter_jni_class->obj(), flutter_jni_methods,
938 std::size(flutter_jni_methods)) != 0) {
939 FML_LOG(ERROR) << "Failed to RegisterNatives with FlutterJNI";
940 return false;
941 }
942
943 g_jni_shell_holder_field = env->GetFieldID(
944 g_flutter_jni_class->obj(), "nativeShellHolderId", "Ljava/lang/Long;");
945
946 if (g_jni_shell_holder_field == nullptr) {
947 FML_LOG(ERROR) << "Could not locate FlutterJNI's nativeShellHolderId field";
948 return false;
949 }
950
952 env->GetMethodID(g_flutter_jni_class->obj(), "<init>", "()V");
953
954 if (g_jni_constructor == nullptr) {
955 FML_LOG(ERROR) << "Could not locate FlutterJNI's constructor";
956 return false;
957 }
958
959 g_long_constructor = env->GetStaticMethodID(g_java_long_class->obj(),
960 "valueOf", "(J)Ljava/lang/Long;");
961 if (g_long_constructor == nullptr) {
962 FML_LOG(ERROR) << "Could not locate Long's constructor";
963 return false;
964 }
965
967
968 fml::jni::ScopedJavaLocalRef<jclass> overlay_surface_class(
969 env, env->FindClass("io/flutter/embedding/engine/FlutterOverlaySurface"));
970 if (overlay_surface_class.is_null()) {
971 FML_LOG(ERROR) << "Could not locate FlutterOverlaySurface class";
972 return false;
973 }
975 env->GetMethodID(overlay_surface_class.obj(), "getId", "()I");
976 if (g_overlay_surface_id_method == nullptr) {
977 FML_LOG(ERROR) << "Could not locate FlutterOverlaySurface#getId() method";
978 return false;
979 }
980 g_overlay_surface_surface_method = env->GetMethodID(
981 overlay_surface_class.obj(), "getSurface", "()Landroid/view/Surface;");
982 if (g_overlay_surface_surface_method == nullptr) {
983 FML_LOG(ERROR)
984 << "Could not locate FlutterOverlaySurface#getSurface() method";
985 return false;
986 }
987
989 env, env->FindClass("android/graphics/Bitmap"));
990 if (g_bitmap_class->is_null()) {
991 FML_LOG(ERROR) << "Could not locate Bitmap Class";
992 return false;
993 }
994
995 g_bitmap_create_bitmap_method = env->GetStaticMethodID(
996 g_bitmap_class->obj(), "createBitmap",
997 "(IILandroid/graphics/Bitmap$Config;)Landroid/graphics/Bitmap;");
998 if (g_bitmap_create_bitmap_method == nullptr) {
999 FML_LOG(ERROR) << "Could not locate Bitmap.createBitmap method";
1000 return false;
1001 }
1002
1003 g_bitmap_copy_pixels_from_buffer_method = env->GetMethodID(
1004 g_bitmap_class->obj(), "copyPixelsFromBuffer", "(Ljava/nio/Buffer;)V");
1006 FML_LOG(ERROR) << "Could not locate Bitmap.copyPixelsFromBuffer method";
1007 return false;
1008 }
1009
1011 env, env->FindClass("android/graphics/Bitmap$Config"));
1012 if (g_bitmap_config_class->is_null()) {
1013 FML_LOG(ERROR) << "Could not locate Bitmap.Config Class";
1014 return false;
1015 }
1016
1017 g_bitmap_config_value_of = env->GetStaticMethodID(
1018 g_bitmap_config_class->obj(), "valueOf",
1019 "(Ljava/lang/String;)Landroid/graphics/Bitmap$Config;");
1020 if (g_bitmap_config_value_of == nullptr) {
1021 FML_LOG(ERROR) << "Could not locate Bitmap.Config.valueOf method";
1022 return false;
1023 }
1024
1025 return true;
1026}
1027
1029 if (env == nullptr) {
1030 FML_LOG(ERROR) << "No JNIEnv provided";
1031 return false;
1032 }
1033
1035 env, env->FindClass("io/flutter/view/FlutterCallbackInformation"));
1036 if (g_flutter_callback_info_class->is_null()) {
1037 FML_LOG(ERROR) << "Could not locate FlutterCallbackInformation class";
1038 return false;
1039 }
1040
1041 g_flutter_callback_info_constructor = env->GetMethodID(
1042 g_flutter_callback_info_class->obj(), "<init>",
1043 "(Ljava/lang/String;Ljava/lang/String;Ljava/lang/String;)V");
1044 if (g_flutter_callback_info_constructor == nullptr) {
1045 FML_LOG(ERROR) << "Could not locate FlutterCallbackInformation constructor";
1046 return false;
1047 }
1048
1050 env, env->FindClass("io/flutter/embedding/engine/FlutterJNI"));
1051 if (g_flutter_jni_class->is_null()) {
1052 FML_LOG(ERROR) << "Failed to find FlutterJNI Class.";
1053 return false;
1054 }
1055
1057 env,
1058 env->FindClass(
1059 "io/flutter/embedding/engine/mutatorsstack/FlutterMutatorsStack"));
1060 if (g_mutators_stack_class == nullptr) {
1061 FML_LOG(ERROR) << "Could not locate FlutterMutatorsStack";
1062 return false;
1063 }
1064
1066 env->GetMethodID(g_mutators_stack_class->obj(), "<init>", "()V");
1067 if (g_mutators_stack_init_method == nullptr) {
1068 FML_LOG(ERROR) << "Could not locate FlutterMutatorsStack.init method";
1069 return false;
1070 }
1071
1073 env->GetMethodID(g_mutators_stack_class->obj(), "pushTransform", "([F)V");
1075 FML_LOG(ERROR)
1076 << "Could not locate FlutterMutatorsStack.pushTransform method";
1077 return false;
1078 }
1079
1080 g_mutators_stack_push_cliprect_method = env->GetMethodID(
1081 g_mutators_stack_class->obj(), "pushClipRect", "(IIII)V");
1083 FML_LOG(ERROR)
1084 << "Could not locate FlutterMutatorsStack.pushClipRect method";
1085 return false;
1086 }
1087
1088 g_mutators_stack_push_cliprrect_method = env->GetMethodID(
1089 g_mutators_stack_class->obj(), "pushClipRRect", "(IIII[F)V");
1091 FML_LOG(ERROR)
1092 << "Could not locate FlutterMutatorsStack.pushClipRRect method";
1093 return false;
1094 }
1095
1097 env->GetMethodID(g_mutators_stack_class->obj(), "pushOpacity", "(F)V");
1098 if (g_mutators_stack_push_opacity_method == nullptr) {
1099 FML_LOG(ERROR)
1100 << "Could not locate FlutterMutatorsStack.pushOpacity method";
1101 return false;
1102 }
1103
1105 env->GetMethodID(g_mutators_stack_class->obj(), "pushClipPath",
1106 "(Landroid/graphics/Path;)V");
1108 FML_LOG(ERROR)
1109 << "Could not locate FlutterMutatorsStack.pushClipPath method";
1110 return false;
1111 }
1112
1114 env, env->FindClass("java/lang/ref/WeakReference"));
1115 if (g_java_weak_reference_class->is_null()) {
1116 FML_LOG(ERROR) << "Could not locate WeakReference class";
1117 return false;
1118 }
1119
1120 g_java_weak_reference_get_method = env->GetMethodID(
1121 g_java_weak_reference_class->obj(), "get", "()Ljava/lang/Object;");
1122 if (g_java_weak_reference_get_method == nullptr) {
1123 FML_LOG(ERROR) << "Could not locate WeakReference.get method";
1124 return false;
1125 }
1126
1128 env, env->FindClass(
1129 "io/flutter/embedding/engine/renderer/SurfaceTextureWrapper"));
1130 if (g_texture_wrapper_class->is_null()) {
1131 FML_LOG(ERROR) << "Could not locate SurfaceTextureWrapper class";
1132 return false;
1133 }
1134
1135 g_attach_to_gl_context_method = env->GetMethodID(
1136 g_texture_wrapper_class->obj(), "attachToGLContext", "(I)V");
1137
1138 if (g_attach_to_gl_context_method == nullptr) {
1139 FML_LOG(ERROR) << "Could not locate attachToGlContext method";
1140 return false;
1141 }
1142
1144 env->GetMethodID(g_texture_wrapper_class->obj(), "shouldUpdate", "()Z");
1145
1147 FML_LOG(ERROR)
1148 << "Could not locate SurfaceTextureWrapper.shouldUpdate method";
1149 return false;
1150 }
1151
1153 env->GetMethodID(g_texture_wrapper_class->obj(), "updateTexImage", "()V");
1154
1155 if (g_update_tex_image_method == nullptr) {
1156 FML_LOG(ERROR) << "Could not locate updateTexImage method";
1157 return false;
1158 }
1159
1160 g_get_transform_matrix_method = env->GetMethodID(
1161 g_texture_wrapper_class->obj(), "getTransformMatrix", "([F)V");
1162
1163 if (g_get_transform_matrix_method == nullptr) {
1164 FML_LOG(ERROR) << "Could not locate getTransformMatrix method";
1165 return false;
1166 }
1167
1168 g_detach_from_gl_context_method = env->GetMethodID(
1169 g_texture_wrapper_class->obj(), "detachFromGLContext", "()V");
1170
1171 if (g_detach_from_gl_context_method == nullptr) {
1172 FML_LOG(ERROR) << "Could not locate detachFromGlContext method";
1173 return false;
1174 }
1177 env, env->FindClass("io/flutter/view/TextureRegistry$ImageConsumer"));
1179 FML_LOG(ERROR) << "Could not locate TextureRegistry.ImageConsumer class";
1180 return false;
1181 }
1182
1184 env->GetMethodID(g_image_consumer_texture_registry_interface->obj(),
1185 "acquireLatestImage", "()Landroid/media/Image;");
1186 if (g_acquire_latest_image_method == nullptr) {
1187 FML_LOG(ERROR) << "Could not locate acquireLatestImage on "
1188 "TextureRegistry.ImageConsumer class";
1189 return false;
1190 }
1191
1193 env, env->FindClass("android/media/Image"));
1194 if (g_image_class->is_null()) {
1195 FML_LOG(ERROR) << "Could not locate Image class";
1196 return false;
1197 }
1198
1199 // Ensure we don't have any pending exceptions.
1201
1203 env->GetMethodID(g_image_class->obj(), "getHardwareBuffer",
1204 "()Landroid/hardware/HardwareBuffer;");
1205
1206 if (g_image_get_hardware_buffer_method == nullptr) {
1207 // Continue on as this method may not exist at API <= 29.
1208 fml::jni::ClearException(env, true);
1209 }
1210
1211 g_image_close_method = env->GetMethodID(g_image_class->obj(), "close", "()V");
1212
1213 if (g_image_close_method == nullptr) {
1214 FML_LOG(ERROR) << "Could not locate close on Image class";
1215 return false;
1216 }
1217
1218 // Ensure we don't have any pending exceptions.
1221 env, env->FindClass("android/hardware/HardwareBuffer"));
1222
1223 if (!g_hardware_buffer_class->is_null()) {
1225 env->GetMethodID(g_hardware_buffer_class->obj(), "close", "()V");
1226 if (g_hardware_buffer_close_method == nullptr) {
1227 // Continue on as this class may not exist at API <= 26.
1228 fml::jni::ClearException(env, true);
1229 }
1230 } else {
1231 // Continue on as this class may not exist at API <= 26.
1232 fml::jni::ClearException(env, true);
1233 }
1234
1236 g_flutter_jni_class->obj(), "computePlatformResolvedLocale",
1237 "([Ljava/lang/String;)[Ljava/lang/String;");
1238
1240 FML_LOG(ERROR) << "Could not locate computePlatformResolvedLocale method";
1241 return false;
1242 }
1243
1244 g_request_dart_deferred_library_method = env->GetMethodID(
1245 g_flutter_jni_class->obj(), "requestDartDeferredLibrary", "(I)V");
1246
1248 FML_LOG(ERROR) << "Could not locate requestDartDeferredLibrary method";
1249 return false;
1250 }
1251
1253 env, env->FindClass("java/lang/Long"));
1254 if (g_java_long_class->is_null()) {
1255 FML_LOG(ERROR) << "Could not locate java.lang.Long class";
1256 return false;
1257 }
1258
1259 // Android path class and methods.
1261 env, env->FindClass("android/graphics/Path"));
1262 if (path_class->is_null()) {
1263 FML_LOG(ERROR) << "Could not locate android.graphics.Path class";
1264 return false;
1265 }
1266
1267 path_constructor = env->GetMethodID(path_class->obj(), "<init>", "()V");
1268 if (path_constructor == nullptr) {
1269 FML_LOG(ERROR) << "Could not locate android.graphics.Path constructor";
1270 return false;
1271 }
1272
1273 path_set_fill_type_method = env->GetMethodID(
1274 path_class->obj(), "setFillType", "(Landroid/graphics/Path$FillType;)V");
1275 if (path_set_fill_type_method == nullptr) {
1276 FML_LOG(ERROR)
1277 << "Could not locate android.graphics.Path.setFillType method";
1278 return false;
1279 }
1280
1281 path_move_to_method = env->GetMethodID(path_class->obj(), "moveTo", "(FF)V");
1282 if (path_move_to_method == nullptr) {
1283 FML_LOG(ERROR) << "Could not locate android.graphics.Path.moveTo method";
1284 return false;
1285 }
1286 path_line_to_method = env->GetMethodID(path_class->obj(), "lineTo", "(FF)V");
1287 if (path_line_to_method == nullptr) {
1288 FML_LOG(ERROR) << "Could not locate android.graphics.Path.lineTo method";
1289 return false;
1290 }
1292 env->GetMethodID(path_class->obj(), "quadTo", "(FFFF)V");
1293 if (path_quad_to_method == nullptr) {
1294 FML_LOG(ERROR) << "Could not locate android.graphics.Path.quadTo method";
1295 return false;
1296 }
1298 env->GetMethodID(path_class->obj(), "cubicTo", "(FFFFFF)V");
1299 if (path_cubic_to_method == nullptr) {
1300 FML_LOG(ERROR) << "Could not locate android.graphics.Path.cubicTo method";
1301 return false;
1302 }
1303 // Ensure we don't have any pending exceptions.
1305
1307 env->GetMethodID(path_class->obj(), "conicTo", "(FFFFF)V");
1308 if (path_conic_to_method == nullptr) {
1309 // Continue on as this method may not exist at API <= 34.
1310 fml::jni::ClearException(env, true);
1311 }
1312 path_close_method = env->GetMethodID(path_class->obj(), "close", "()V");
1313 if (path_close_method == nullptr) {
1314 FML_LOG(ERROR) << "Could not locate android.graphics.Path.close method";
1315 return false;
1316 }
1317
1319 env, env->FindClass("android/graphics/Path$FillType"));
1320 if (g_path_fill_type_class->is_null()) {
1321 FML_LOG(ERROR) << "Could not locate android.graphics.Path$FillType class";
1322 return false;
1323 }
1324
1326 env->GetStaticFieldID(g_path_fill_type_class->obj(), "WINDING",
1327 "Landroid/graphics/Path$FillType;");
1328 if (g_path_fill_type_winding_field == nullptr) {
1329 FML_LOG(ERROR) << "Could not locate Path.FillType.WINDING field";
1330 return false;
1331 }
1332
1334 env->GetStaticFieldID(g_path_fill_type_class->obj(), "EVEN_ODD",
1335 "Landroid/graphics/Path$FillType;");
1336 if (g_path_fill_type_even_odd_field == nullptr) {
1337 FML_LOG(ERROR) << "Could not locate Path.FillType.EVEN_ODD field";
1338 return false;
1339 }
1340
1341 return RegisterApi(env);
1342}
1343
1345 const fml::jni::JavaObjectWeakGlobalRef& java_object)
1346 : java_object_(java_object) {}
1347
1349
1351 std::unique_ptr<flutter::PlatformMessage> message,
1352 int responseId) {
1353 // Called from any thread.
1354 JNIEnv* env = fml::jni::AttachCurrentThread();
1355
1356 auto java_object = java_object_.get(env);
1357 if (java_object.is_null()) {
1358 return;
1359 }
1360
1362 fml::jni::StringToJavaString(env, message->channel());
1363
1364 if (message->hasData()) {
1366 env, env->NewDirectByteBuffer(
1367 const_cast<uint8_t*>(message->data().GetMapping()),
1368 message->data().GetSize()));
1369 // Message data is deleted in CleanupMessageData.
1370 fml::MallocMapping mapping = message->releaseData();
1371 env->CallVoidMethod(java_object.obj(), g_handle_platform_message_method,
1372 java_channel.obj(), message_array.obj(), responseId,
1373 reinterpret_cast<jlong>(mapping.Release()));
1374 } else {
1375 env->CallVoidMethod(java_object.obj(), g_handle_platform_message_method,
1376 java_channel.obj(), nullptr, responseId, nullptr);
1377 }
1378
1380}
1381
1383 std::string locale) {
1384 JNIEnv* env = fml::jni::AttachCurrentThread();
1385
1386 auto java_object = java_object_.get(env);
1387 if (java_object.is_null()) {
1388 return;
1389 }
1390
1392 fml::jni::StringToJavaString(env, locale);
1393
1394 env->CallVoidMethod(java_object.obj(), g_set_application_locale_method,
1395 jlocale.obj());
1396
1398}
1399
1401 bool enabled) {
1402 JNIEnv* env = fml::jni::AttachCurrentThread();
1403
1404 auto java_object = java_object_.get(env);
1405 if (java_object.is_null()) {
1406 return;
1407 }
1408
1409 env->CallVoidMethod(java_object.obj(), g_set_semantics_tree_enabled_method,
1410 enabled);
1411
1413}
1414
1416 int responseId,
1417 std::unique_ptr<fml::Mapping> data) {
1418 // We are on the platform thread. Attempt to get the strong reference to
1419 // the Java object.
1420 JNIEnv* env = fml::jni::AttachCurrentThread();
1421
1422 auto java_object = java_object_.get(env);
1423 if (java_object.is_null()) {
1424 // The Java object was collected before this message response got to
1425 // it. Drop the response on the floor.
1426 return;
1427 }
1428 if (data == nullptr) { // Empty response.
1429 env->CallVoidMethod(java_object.obj(),
1430 g_handle_platform_message_response_method, responseId,
1431 nullptr);
1432 } else {
1433 // Convert the vector to a Java byte array.
1435 env, env->NewDirectByteBuffer(const_cast<uint8_t*>(data->GetMapping()),
1436 data->GetSize()));
1437
1438 env->CallVoidMethod(java_object.obj(),
1439 g_handle_platform_message_response_method, responseId,
1440 data_array.obj());
1441 }
1442
1444}
1445
1447 double font_size,
1448 int configuration_id) const {
1449 JNIEnv* env = fml::jni::AttachCurrentThread();
1450
1451 auto java_object = java_object_.get(env);
1452 if (java_object.is_null()) {
1453 return -3;
1454 }
1455
1456 const jfloat scaledSize = env->CallFloatMethod(
1457 java_object.obj(), g_get_scaled_font_size_method,
1458 static_cast<jfloat>(font_size), static_cast<jint>(configuration_id));
1460 return static_cast<double>(scaledSize);
1461}
1462
1464 std::vector<uint8_t> buffer,
1465 std::vector<std::string> strings,
1466 std::vector<std::vector<uint8_t>> string_attribute_args) {
1467 JNIEnv* env = fml::jni::AttachCurrentThread();
1468
1469 auto java_object = java_object_.get(env);
1470 if (java_object.is_null()) {
1471 return;
1472 }
1473
1475 env, env->NewDirectByteBuffer(buffer.data(), buffer.size()));
1477 fml::jni::VectorToStringArray(env, strings);
1478 fml::jni::ScopedJavaLocalRef<jobjectArray> jstring_attribute_args =
1479 fml::jni::VectorToBufferArray(env, string_attribute_args);
1480
1481 env->CallVoidMethod(java_object.obj(), g_update_semantics_method,
1482 direct_buffer.obj(), jstrings.obj(),
1483 jstring_attribute_args.obj());
1484
1486}
1487
1489 std::vector<uint8_t> actions_buffer,
1490 std::vector<std::string> strings) {
1491 JNIEnv* env = fml::jni::AttachCurrentThread();
1492
1493 auto java_object = java_object_.get(env);
1494 if (java_object.is_null()) {
1495 return;
1496 }
1497
1498 fml::jni::ScopedJavaLocalRef<jobject> direct_actions_buffer(
1499 env,
1500 env->NewDirectByteBuffer(actions_buffer.data(), actions_buffer.size()));
1501
1503 fml::jni::VectorToStringArray(env, strings);
1504
1505 env->CallVoidMethod(java_object.obj(),
1506 g_update_custom_accessibility_actions_method,
1507 direct_actions_buffer.obj(), jstrings.obj());
1508
1510}
1511
1513 JNIEnv* env = fml::jni::AttachCurrentThread();
1514
1515 auto java_object = java_object_.get(env);
1516 if (java_object.is_null()) {
1517 return;
1518 }
1519
1520 env->CallVoidMethod(java_object.obj(), g_on_first_frame_method);
1521
1523}
1524
1526 JNIEnv* env = fml::jni::AttachCurrentThread();
1527
1528 auto java_object = java_object_.get(env);
1529 if (java_object.is_null()) {
1530 return;
1531 }
1532
1533 env->CallVoidMethod(java_object.obj(), g_on_engine_restart_method);
1534
1536}
1537
1539 JavaLocalRef surface_texture,
1540 int textureId) {
1541 JNIEnv* env = fml::jni::AttachCurrentThread();
1542
1543 if (surface_texture.is_null()) {
1544 return;
1545 }
1546
1547 fml::jni::ScopedJavaLocalRef<jobject> surface_texture_local_ref(
1548 env, env->CallObjectMethod(surface_texture.obj(),
1550
1551 if (surface_texture_local_ref.is_null()) {
1552 return;
1553 }
1554
1555 env->CallVoidMethod(surface_texture_local_ref.obj(),
1557
1559}
1560
1562 JavaLocalRef surface_texture) {
1563 JNIEnv* env = fml::jni::AttachCurrentThread();
1564
1565 if (surface_texture.is_null()) {
1566 return false;
1567 }
1568
1569 fml::jni::ScopedJavaLocalRef<jobject> surface_texture_local_ref(
1570 env, env->CallObjectMethod(surface_texture.obj(),
1572 if (surface_texture_local_ref.is_null()) {
1573 return false;
1574 }
1575
1576 jboolean shouldUpdate = env->CallBooleanMethod(
1577 surface_texture_local_ref.obj(), g_surface_texture_wrapper_should_update);
1578
1580
1581 return shouldUpdate;
1582}
1583
1585 JavaLocalRef surface_texture) {
1586 JNIEnv* env = fml::jni::AttachCurrentThread();
1587
1588 if (surface_texture.is_null()) {
1589 return;
1590 }
1591
1592 fml::jni::ScopedJavaLocalRef<jobject> surface_texture_local_ref(
1593 env, env->CallObjectMethod(surface_texture.obj(),
1595 if (surface_texture_local_ref.is_null()) {
1596 return;
1597 }
1598
1599 env->CallVoidMethod(surface_texture_local_ref.obj(),
1601
1603}
1604
1606 JavaLocalRef surface_texture) {
1607 JNIEnv* env = fml::jni::AttachCurrentThread();
1608
1609 if (surface_texture.is_null()) {
1610 return {};
1611 }
1612
1613 fml::jni::ScopedJavaLocalRef<jobject> surface_texture_local_ref(
1614 env, env->CallObjectMethod(surface_texture.obj(),
1616 if (surface_texture_local_ref.is_null()) {
1617 return {};
1618 }
1619
1621 env, env->NewFloatArray(16));
1622
1623 env->CallVoidMethod(surface_texture_local_ref.obj(),
1624 g_get_transform_matrix_method, transformMatrix.obj());
1626
1627 float* m = env->GetFloatArrayElements(transformMatrix.obj(), nullptr);
1628
1629 static_assert(sizeof(SkScalar) == sizeof(float));
1630 const auto transform = SkM44::ColMajor(m);
1631
1632 env->ReleaseFloatArrayElements(transformMatrix.obj(), m, JNI_ABORT);
1633
1634 return transform;
1635}
1636
1638 JavaLocalRef surface_texture) {
1639 JNIEnv* env = fml::jni::AttachCurrentThread();
1640
1641 if (surface_texture.is_null()) {
1642 return;
1643 }
1644
1645 fml::jni::ScopedJavaLocalRef<jobject> surface_texture_local_ref(
1646 env, env->CallObjectMethod(surface_texture.obj(),
1648 if (surface_texture_local_ref.is_null()) {
1649 return;
1650 }
1651
1652 env->CallVoidMethod(surface_texture_local_ref.obj(),
1654
1656}
1657
1660 JavaLocalRef image_producer_texture_entry) {
1661 JNIEnv* env = fml::jni::AttachCurrentThread();
1662
1663 if (image_producer_texture_entry.is_null()) {
1664 // Return null.
1665 return JavaLocalRef();
1666 }
1667
1668 // Convert the weak reference to ImageTextureEntry into a strong local
1669 // reference.
1670 fml::jni::ScopedJavaLocalRef<jobject> image_producer_texture_entry_local_ref(
1671 env, env->CallObjectMethod(image_producer_texture_entry.obj(),
1673
1674 if (image_producer_texture_entry_local_ref.is_null()) {
1675 // Return null.
1676 return JavaLocalRef();
1677 }
1678
1680 env, env->CallObjectMethod(image_producer_texture_entry_local_ref.obj(),
1682 if (fml::jni::CheckException(env)) {
1683 return r;
1684 }
1685 // Return null.
1686 return JavaLocalRef();
1687}
1688
1692 JNIEnv* env = fml::jni::AttachCurrentThread();
1693 if (image.is_null()) {
1694 // Return null.
1695 return JavaLocalRef();
1696 }
1698 env,
1699 env->CallObjectMethod(image.obj(), g_image_get_hardware_buffer_method));
1700 if (fml::jni::ClearException(env, false)) {
1701 return JavaLocalRef();
1702 }
1703 return r;
1704}
1705
1707 JNIEnv* env = fml::jni::AttachCurrentThread();
1708 if (image.is_null()) {
1709 return;
1710 }
1711 env->CallVoidMethod(image.obj(), g_image_close_method);
1713}
1714
1716 JavaLocalRef hardware_buffer) {
1718 JNIEnv* env = fml::jni::AttachCurrentThread();
1719 if (hardware_buffer.is_null()) {
1720 return;
1721 }
1722 env->CallVoidMethod(hardware_buffer.obj(), g_hardware_buffer_close_method);
1724}
1725
1727 int view_id,
1728 int x,
1729 int y,
1730 int width,
1731 int height,
1732 int viewWidth,
1733 int viewHeight,
1734 MutatorsStack mutators_stack) {
1735 JNIEnv* env = fml::jni::AttachCurrentThread();
1736 auto java_object = java_object_.get(env);
1737 if (java_object.is_null()) {
1738 return;
1739 }
1740
1741 jobject mutatorsStack = env->NewObject(g_mutators_stack_class->obj(),
1743
1744 std::vector<std::shared_ptr<Mutator>>::const_iterator iter =
1745 mutators_stack.Begin();
1746 while (iter != mutators_stack.End()) {
1747 switch ((*iter)->GetType()) {
1749 const DlMatrix& matrix = (*iter)->GetMatrix();
1750 DlScalar matrix_array[9]{
1751 matrix.m[0], matrix.m[4], matrix.m[12], //
1752 matrix.m[1], matrix.m[5], matrix.m[13], //
1753 matrix.m[3], matrix.m[7], matrix.m[15],
1754 };
1756 env, env->NewFloatArray(9));
1757
1758 env->SetFloatArrayRegion(transformMatrix.obj(), 0, 9, matrix_array);
1759 env->CallVoidMethod(mutatorsStack,
1761 transformMatrix.obj());
1762 break;
1763 }
1765 const DlRect& rect = (*iter)->GetRect();
1766 env->CallVoidMethod(mutatorsStack,
1768 static_cast<int>(rect.GetLeft()), //
1769 static_cast<int>(rect.GetTop()), //
1770 static_cast<int>(rect.GetRight()), //
1771 static_cast<int>(rect.GetBottom()));
1772 break;
1773 }
1775 const DlRoundRect& rrect = (*iter)->GetRRect();
1776 const DlRect& rect = rrect.GetBounds();
1777 const DlRoundingRadii radii = rrect.GetRadii();
1778 SkScalar radiis[8] = {
1779 radii.top_left.width, radii.top_left.height,
1780 radii.top_right.width, radii.top_right.height,
1782 radii.bottom_left.width, radii.bottom_left.height,
1783 };
1785 env, env->NewFloatArray(8));
1786 env->SetFloatArrayRegion(radiisArray.obj(), 0, 8, radiis);
1787 env->CallVoidMethod(mutatorsStack,
1789 static_cast<int>(rect.GetLeft()), //
1790 static_cast<int>(rect.GetTop()), //
1791 static_cast<int>(rect.GetRight()), //
1792 static_cast<int>(rect.GetBottom()), //
1793 radiisArray.obj());
1794 break;
1795 }
1796 case MutatorType::kClipRSE: {
1797 const DlRoundRect& rrect = (*iter)->GetRSEApproximation();
1798 const DlRect& rect = rrect.GetBounds();
1799 const DlRoundingRadii radii = rrect.GetRadii();
1800 SkScalar radiis[8] = {
1801 radii.top_left.width, radii.top_left.height,
1802 radii.top_right.width, radii.top_right.height,
1804 radii.bottom_left.width, radii.bottom_left.height,
1805 };
1807 env, env->NewFloatArray(8));
1808 env->SetFloatArrayRegion(radiisArray.obj(), 0, 8, radiis);
1809 env->CallVoidMethod(mutatorsStack,
1811 static_cast<int>(rect.GetLeft()), //
1812 static_cast<int>(rect.GetTop()), //
1813 static_cast<int>(rect.GetRight()), //
1814 static_cast<int>(rect.GetBottom()), //
1815 radiisArray.obj());
1816 break;
1817 }
1818 // TODO(cyanglaz): Implement other mutators.
1819 // https://github.com/flutter/flutter/issues/58426
1827 break;
1828 }
1829 ++iter;
1830 }
1831
1832 env->CallVoidMethod(java_object.obj(), g_on_display_platform_view_method,
1833 view_id, x, y, width, height, viewWidth, viewHeight,
1834 mutatorsStack);
1835
1837}
1838
1840 int surface_id,
1841 int x,
1842 int y,
1843 int width,
1844 int height) {
1845 JNIEnv* env = fml::jni::AttachCurrentThread();
1846
1847 auto java_object = java_object_.get(env);
1848 if (java_object.is_null()) {
1849 return;
1850 }
1851
1852 env->CallVoidMethod(java_object.obj(), g_on_display_overlay_surface_method,
1853 surface_id, x, y, width, height);
1854
1856}
1857
1859 JNIEnv* env = fml::jni::AttachCurrentThread();
1860
1861 auto java_object = java_object_.get(env);
1862 if (java_object.is_null()) {
1863 return;
1864 }
1865
1866 env->CallVoidMethod(java_object.obj(), g_on_begin_frame_method);
1867
1869}
1870
1872 JNIEnv* env = fml::jni::AttachCurrentThread();
1873
1874 auto java_object = java_object_.get(env);
1875 if (java_object.is_null()) {
1876 return;
1877 }
1878
1879 env->CallVoidMethod(java_object.obj(), g_on_end_frame_method);
1880
1882}
1883
1884std::unique_ptr<PlatformViewAndroidJNI::OverlayMetadata>
1886 JNIEnv* env = fml::jni::AttachCurrentThread();
1887
1888 auto java_object = java_object_.get(env);
1889 if (java_object.is_null()) {
1890 return nullptr;
1891 }
1892
1894 env, env->CallObjectMethod(java_object.obj(),
1895 g_create_overlay_surface_method));
1897
1898 if (overlay.is_null()) {
1899 return std::make_unique<PlatformViewAndroidJNI::OverlayMetadata>(0,
1900 nullptr);
1901 }
1902
1903 jint overlay_id =
1904 env->CallIntMethod(overlay.obj(), g_overlay_surface_id_method);
1905
1906 jobject overlay_surface =
1907 env->CallObjectMethod(overlay.obj(), g_overlay_surface_surface_method);
1908
1909 auto overlay_window = fml::MakeRefCounted<AndroidNativeWindow>(
1910 ANativeWindow_fromSurface(env, overlay_surface));
1911
1912 return std::make_unique<PlatformViewAndroidJNI::OverlayMetadata>(
1913 overlay_id, std::move(overlay_window));
1914}
1915
1917 JNIEnv* env = fml::jni::AttachCurrentThread();
1918
1919 auto java_object = java_object_.get(env);
1920 if (java_object.is_null()) {
1921 return;
1922 }
1923
1924 env->CallVoidMethod(java_object.obj(), g_destroy_overlay_surfaces_method);
1925
1927}
1928
1929std::unique_ptr<std::vector<std::string>>
1931 std::vector<std::string> supported_locales_data) {
1932 JNIEnv* env = fml::jni::AttachCurrentThread();
1933
1934 std::unique_ptr<std::vector<std::string>> out =
1935 std::make_unique<std::vector<std::string>>();
1936
1937 auto java_object = java_object_.get(env);
1938 if (java_object.is_null()) {
1939 return out;
1940 }
1942 fml::jni::VectorToStringArray(env, supported_locales_data);
1943 jobjectArray result = static_cast<jobjectArray>(env->CallObjectMethod(
1945 j_locales_data.obj()));
1946
1948
1949 int length = env->GetArrayLength(result);
1950 for (int i = 0; i < length; i++) {
1951 out->emplace_back(fml::jni::JavaStringToString(
1952 env, static_cast<jstring>(env->GetObjectArrayElement(result, i))));
1953 }
1954 return out;
1955}
1956
1958 JNIEnv* env = fml::jni::AttachCurrentThread();
1959
1960 auto java_object = java_object_.get(env);
1961 if (java_object.is_null()) {
1963 }
1964
1966 env, env->GetObjectClass(java_object.obj()));
1967 if (clazz.is_null()) {
1969 }
1970
1971 jfieldID fid = env->GetStaticFieldID(clazz.obj(), "refreshRateFPS", "F");
1972 return static_cast<double>(env->GetStaticFloatField(clazz.obj(), fid));
1973}
1974
1976 JNIEnv* env = fml::jni::AttachCurrentThread();
1977
1978 auto java_object = java_object_.get(env);
1979 if (java_object.is_null()) {
1980 return -1;
1981 }
1982
1984 env, env->GetObjectClass(java_object.obj()));
1985 if (clazz.is_null()) {
1986 return -1;
1987 }
1988
1989 jfieldID fid = env->GetStaticFieldID(clazz.obj(), "displayWidth", "F");
1990 return static_cast<double>(env->GetStaticFloatField(clazz.obj(), fid));
1991}
1992
1994 JNIEnv* env = fml::jni::AttachCurrentThread();
1995
1996 auto java_object = java_object_.get(env);
1997 if (java_object.is_null()) {
1998 return -1;
1999 }
2000
2002 env, env->GetObjectClass(java_object.obj()));
2003 if (clazz.is_null()) {
2004 return -1;
2005 }
2006
2007 jfieldID fid = env->GetStaticFieldID(clazz.obj(), "displayHeight", "F");
2008 return static_cast<double>(env->GetStaticFloatField(clazz.obj(), fid));
2009}
2010
2012 JNIEnv* env = fml::jni::AttachCurrentThread();
2013
2014 auto java_object = java_object_.get(env);
2015 if (java_object.is_null()) {
2016 return -1;
2017 }
2018
2020 env, env->GetObjectClass(java_object.obj()));
2021 if (clazz.is_null()) {
2022 return -1;
2023 }
2024
2025 jfieldID fid = env->GetStaticFieldID(clazz.obj(), "displayDensity", "F");
2026 return static_cast<double>(env->GetStaticFloatField(clazz.obj(), fid));
2027}
2028
2030 int loading_unit_id) {
2031 JNIEnv* env = fml::jni::AttachCurrentThread();
2032
2033 auto java_object = java_object_.get(env);
2034 if (java_object.is_null()) {
2035 return true;
2036 }
2037
2038 env->CallVoidMethod(java_object.obj(), g_request_dart_deferred_library_method,
2039 loading_unit_id);
2040
2042 return true;
2043}
2044
2045// New Platform View Support.
2046
2048 JNIEnv* env = fml::jni::AttachCurrentThread();
2049
2050 auto java_object = java_object_.get(env);
2051 if (java_object.is_null()) {
2052 return nullptr;
2053 }
2054
2056 env,
2057 env->CallObjectMethod(java_object.obj(), g_create_transaction_method));
2058 if (transaction.is_null()) {
2059 return nullptr;
2060 }
2062
2063 return impeller::android::GetProcTable().ASurfaceTransaction_fromJava(
2064 env, transaction.obj());
2065}
2066
2068 JNIEnv* env = fml::jni::AttachCurrentThread();
2069
2070 auto java_object = java_object_.get(env);
2071 if (java_object.is_null()) {
2072 return;
2073 }
2074
2075 env->CallVoidMethod(java_object.obj(), g_swap_transaction_method);
2076
2078}
2079
2081 JNIEnv* env = fml::jni::AttachCurrentThread();
2082
2083 auto java_object = java_object_.get(env);
2084 if (java_object.is_null()) {
2085 return;
2086 }
2087
2088 env->CallVoidMethod(java_object.obj(), g_apply_transaction_method);
2089
2091}
2092
2093std::unique_ptr<PlatformViewAndroidJNI::OverlayMetadata>
2095 JNIEnv* env = fml::jni::AttachCurrentThread();
2096
2097 auto java_object = java_object_.get(env);
2098 if (java_object.is_null()) {
2099 return nullptr;
2100 }
2101
2103 env, env->CallObjectMethod(java_object.obj(),
2104 g_create_overlay_surface2_method));
2106
2107 if (overlay.is_null()) {
2108 return std::make_unique<PlatformViewAndroidJNI::OverlayMetadata>(0,
2109 nullptr);
2110 }
2111
2112 jint overlay_id =
2113 env->CallIntMethod(overlay.obj(), g_overlay_surface_id_method);
2114
2115 jobject overlay_surface =
2116 env->CallObjectMethod(overlay.obj(), g_overlay_surface_surface_method);
2117
2118 auto overlay_window = fml::MakeRefCounted<AndroidNativeWindow>(
2119 ANativeWindow_fromSurface(env, overlay_surface));
2120
2121 return std::make_unique<PlatformViewAndroidJNI::OverlayMetadata>(
2122 overlay_id, std::move(overlay_window));
2123}
2124
2126 JNIEnv* env = fml::jni::AttachCurrentThread();
2127
2128 auto java_object = java_object_.get(env);
2129 if (java_object.is_null()) {
2130 return;
2131 }
2132
2133 env->CallVoidMethod(java_object.obj(), g_destroy_overlay_surface2_method);
2134
2136}
2137
2138namespace {
2139class AndroidPathReceiver final : public DlPathReceiver {
2140 public:
2141 explicit AndroidPathReceiver(JNIEnv* env)
2142 : env_(env),
2143 android_path_(env->NewObject(path_class->obj(), path_constructor)) {}
2144
2145 void SetFillType(DlPathFillType type) {
2146 jfieldID fill_type_field_id;
2147 switch (type) {
2148 case DlPathFillType::kOdd:
2149 fill_type_field_id = g_path_fill_type_even_odd_field;
2150 break;
2151 case DlPathFillType::kNonZero:
2152 fill_type_field_id = g_path_fill_type_winding_field;
2153 break;
2154 default:
2155 // DlPathFillType does not have corresponding kInverseEvenOdd or
2156 // kInverseWinding fill types.
2157 return;
2158 }
2159
2160 // Get the static enum field value (Path.FillType.WINDING or
2161 // Path.FillType.EVEN_ODD)
2164 env_, env_->GetStaticObjectField(g_path_fill_type_class->obj(),
2165 fill_type_field_id));
2167 FML_CHECK(!fill_type_enum.is_null());
2168
2169 // Call Path.setFillType(Path.FillType)
2170 env_->CallVoidMethod(android_path_, path_set_fill_type_method,
2171 fill_type_enum.obj());
2173 }
2174
2175 void MoveTo(const DlPoint& p2, bool will_be_closed) override {
2176 env_->CallVoidMethod(android_path_, path_move_to_method, p2.x, p2.y);
2177 }
2178 void LineTo(const DlPoint& p2) override {
2179 env_->CallVoidMethod(android_path_, path_line_to_method, p2.x, p2.y);
2180 }
2181 void QuadTo(const DlPoint& cp, const DlPoint& p2) override {
2182 env_->CallVoidMethod(android_path_, path_quad_to_method, //
2183 cp.x, cp.y, p2.x, p2.y);
2184 }
2185 bool ConicTo(const DlPoint& cp, const DlPoint& p2, DlScalar weight) override {
2186 if (!path_conic_to_method) {
2187 return false;
2188 }
2189 env_->CallVoidMethod(android_path_, path_conic_to_method, //
2190 cp.x, cp.y, p2.x, p2.y, weight);
2191 return true;
2192 };
2193 void CubicTo(const DlPoint& cp1,
2194 const DlPoint& cp2,
2195 const DlPoint& p2) override {
2196 env_->CallVoidMethod(android_path_, path_cubic_to_method, //
2197 cp1.x, cp1.y, cp2.x, cp2.y, p2.x, p2.y);
2198 }
2199 void Close() override {
2200 env_->CallVoidMethod(android_path_, path_close_method);
2201 }
2202
2203 jobject TakePath() const { return android_path_; }
2204
2205 private:
2206 JNIEnv* env_;
2207 jobject android_path_;
2208};
2209} // namespace
2210
2212 int32_t view_id,
2213 int32_t x,
2214 int32_t y,
2215 int32_t width,
2216 int32_t height,
2217 int32_t viewWidth,
2218 int32_t viewHeight,
2219 MutatorsStack mutators_stack) {
2220 JNIEnv* env = fml::jni::AttachCurrentThread();
2221 auto java_object = java_object_.get(env);
2222 if (java_object.is_null()) {
2223 return;
2224 }
2225
2226 jobject mutatorsStack = env->NewObject(g_mutators_stack_class->obj(),
2228
2229 std::vector<std::shared_ptr<Mutator>>::const_iterator iter =
2230 mutators_stack.Begin();
2231 while (iter != mutators_stack.End()) {
2232 switch ((*iter)->GetType()) {
2234 const DlMatrix& matrix = (*iter)->GetMatrix();
2235 DlScalar matrix_array[9]{
2236 matrix.m[0], matrix.m[4], matrix.m[12], //
2237 matrix.m[1], matrix.m[5], matrix.m[13], //
2238 matrix.m[3], matrix.m[7], matrix.m[15],
2239 };
2241 env, env->NewFloatArray(9));
2242
2243 env->SetFloatArrayRegion(transformMatrix.obj(), 0, 9, matrix_array);
2244 env->CallVoidMethod(mutatorsStack,
2246 transformMatrix.obj());
2247 break;
2248 }
2250 const DlRect& rect = (*iter)->GetRect();
2251 env->CallVoidMethod(mutatorsStack,
2253 static_cast<int>(rect.GetLeft()), //
2254 static_cast<int>(rect.GetTop()), //
2255 static_cast<int>(rect.GetRight()), //
2256 static_cast<int>(rect.GetBottom()));
2257 break;
2258 }
2260 const DlRoundRect& rrect = (*iter)->GetRRect();
2261 const DlRect& rect = rrect.GetBounds();
2262 const DlRoundingRadii& radii = rrect.GetRadii();
2263 SkScalar radiis[8] = {
2264 radii.top_left.width, radii.top_left.height,
2265 radii.top_right.width, radii.top_right.height,
2267 radii.bottom_left.width, radii.bottom_left.height,
2268 };
2270 env, env->NewFloatArray(8));
2271 env->SetFloatArrayRegion(radiisArray.obj(), 0, 8, radiis);
2272 env->CallVoidMethod(mutatorsStack,
2274 static_cast<int>(rect.GetLeft()), //
2275 static_cast<int>(rect.GetTop()), //
2276 static_cast<int>(rect.GetRight()), //
2277 static_cast<int>(rect.GetBottom()), //
2278 radiisArray.obj());
2279 break;
2280 }
2281 case MutatorType::kClipRSE: {
2282 const DlRoundRect& rrect = (*iter)->GetRSEApproximation();
2283 const DlRect& rect = rrect.GetBounds();
2284 const DlRoundingRadii& radii = rrect.GetRadii();
2285 SkScalar radiis[8] = {
2286 radii.top_left.width, radii.top_left.height,
2287 radii.top_right.width, radii.top_right.height,
2289 radii.bottom_left.width, radii.bottom_left.height,
2290 };
2292 env, env->NewFloatArray(8));
2293 env->SetFloatArrayRegion(radiisArray.obj(), 0, 8, radiis);
2294 env->CallVoidMethod(mutatorsStack,
2296 static_cast<int>(rect.GetLeft()), //
2297 static_cast<int>(rect.GetTop()), //
2298 static_cast<int>(rect.GetRight()), //
2299 static_cast<int>(rect.GetBottom()), //
2300 radiisArray.obj());
2301 break;
2302 }
2303 case MutatorType::kOpacity: {
2304 float opacity = (*iter)->GetAlphaFloat();
2305 env->CallVoidMethod(mutatorsStack, g_mutators_stack_push_opacity_method,
2306 opacity);
2307 break;
2308 }
2310 auto& dlPath = (*iter)->GetPath();
2311 // The layer mutator mechanism should have already caught and
2312 // redirected these simplified path cases, which is important because
2313 // the conics they generate (in the case of oval and rrect) will
2314 // not match the results of an impeller path conversion very closely.
2315 FML_DCHECK(!dlPath.IsRect());
2316 FML_DCHECK(!dlPath.IsOval());
2317 FML_DCHECK(!dlPath.IsRoundRect());
2318
2319 // Define and populate an Android Path with data from the DlPath
2320 AndroidPathReceiver receiver(env);
2321 receiver.SetFillType(dlPath.GetFillType());
2322
2323 // TODO(flar): https://github.com/flutter/flutter/issues/164808
2324 // Need to convert the fill type to the Android enum and
2325 // call setFillType on the path...
2326 dlPath.Dispatch(receiver);
2327
2328 env->CallVoidMethod(mutatorsStack,
2330 receiver.TakePath());
2331 break;
2332 }
2333 // TODO(cyanglaz): Implement other mutators.
2334 // https://github.com/flutter/flutter/issues/58426
2340 break;
2341 }
2342 ++iter;
2343 }
2344
2345 env->CallVoidMethod(java_object.obj(), g_on_display_platform_view2_method,
2346 view_id, x, y, width, height, viewWidth, viewHeight,
2347 mutatorsStack);
2348
2350}
2351
2353 JNIEnv* env = fml::jni::AttachCurrentThread();
2354 auto java_object = java_object_.get(env);
2355 if (java_object.is_null()) {
2356 return;
2357 }
2358
2359 env->CallVoidMethod(java_object.obj(), g_hide_platform_view2_method, view_id);
2360}
2361
2363 JNIEnv* env = fml::jni::AttachCurrentThread();
2364
2365 auto java_object = java_object_.get(env);
2366 if (java_object.is_null()) {
2367 return;
2368 }
2369
2370 env->CallVoidMethod(java_object.obj(), g_on_end_frame2_method);
2371
2373}
2374
2376 JNIEnv* env = fml::jni::AttachCurrentThread();
2377
2378 auto java_object = java_object_.get(env);
2379 if (java_object.is_null()) {
2380 return;
2381 }
2382
2383 env->CallVoidMethod(java_object.obj(), g_show_overlay_surface2_method);
2385}
2386
2388 JNIEnv* env = fml::jni::AttachCurrentThread();
2389
2390 auto java_object = java_object_.get(env);
2391 if (java_object.is_null()) {
2392 return;
2393 }
2394
2395 env->CallVoidMethod(java_object.obj(), g_hide_overlay_surface2_method);
2397}
2398
2400 int32_t height) const {
2401 JNIEnv* env = fml::jni::AttachCurrentThread();
2402
2403 auto java_object = java_object_.get(env);
2404 if (java_object.is_null()) {
2405 return;
2406 }
2407
2408 env->CallVoidMethod(java_object.obj(), g_maybe_resize_surface_view, width,
2409 height);
2411}
2412
2413} // 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