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