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