1212#include < sstream>
1313
1414#include " flutter/common/settings.h"
15+ #include " flutter/lib/ui/plugins/callback_cache.h"
1516#include " flutter/lib/ui/ui_dart_state.h"
1617#include " lib/fxl/build_config.h"
1718#include " lib/fxl/logging.h"
@@ -36,6 +37,7 @@ extern void syslog(int, const char*, ...);
3637}
3738#endif
3839
40+ using tonic::DartConverter;
3941using tonic::LogIfError;
4042using tonic::ToDart;
4143
@@ -48,23 +50,25 @@ namespace blink {
4850#define BUILTIN_NATIVE_LIST (V ) \
4951 V (Logger_PrintString, 1 ) \
5052 V (SaveCompilationTrace, 0 ) \
51- V (ScheduleMicrotask, 1 )
53+ V (ScheduleMicrotask, 1 ) \
54+ V (GetCallbackHandle, 1 ) \
55+ V (GetCallbackFromHandle, 1 )
5256
5357BUILTIN_NATIVE_LIST (DECLARE_FUNCTION);
5458
5559void DartRuntimeHooks::RegisterNatives (tonic::DartLibraryNatives* natives) {
5660 natives->Register ({BUILTIN_NATIVE_LIST (REGISTER_FUNCTION)});
5761}
5862
59- static Dart_Handle GetClosure (Dart_Handle builtin_library, const char * name) {
63+ static Dart_Handle GetFunction (Dart_Handle builtin_library, const char * name) {
6064 Dart_Handle getter_name = ToDart (name);
6165 Dart_Handle closure = Dart_Invoke (builtin_library, getter_name, 0 , nullptr );
6266 DART_CHECK_VALID (closure);
6367 return closure;
6468}
6569
6670static void InitDartInternal (Dart_Handle builtin_library, bool is_ui_isolate) {
67- Dart_Handle print = GetClosure (builtin_library, " _getPrintClosure" );
71+ Dart_Handle print = GetFunction (builtin_library, " _getPrintClosure" );
6872
6973 Dart_Handle internal_library = Dart_LookupLibrary (ToDart (" dart:_internal" ));
7074
@@ -101,7 +105,7 @@ static void InitDartAsync(Dart_Handle builtin_library, bool is_ui_isolate) {
101105 Dart_Handle schedule_microtask;
102106 if (is_ui_isolate) {
103107 schedule_microtask =
104- GetClosure (builtin_library, " _getScheduleMicrotaskClosure" );
108+ GetFunction (builtin_library, " _getScheduleMicrotaskClosure" );
105109 } else {
106110 Dart_Handle isolate_lib = Dart_LookupLibrary (ToDart (" dart:isolate" ));
107111 Dart_Handle method_name =
@@ -125,7 +129,8 @@ static void InitDartIO(Dart_Handle builtin_library,
125129 DART_CHECK_VALID (Dart_SetField (platform_type, ToDart (" _nativeScript" ),
126130 ToDart (script_uri)));
127131 }
128- Dart_Handle locale_closure = GetClosure (builtin_library, " _getLocaleClosure" );
132+ Dart_Handle locale_closure =
133+ GetFunction (builtin_library, " _getLocaleClosure" );
129134 DART_CHECK_VALID (
130135 Dart_SetField (platform_type, ToDart (" _localeClosure" ), locale_closure));
131136}
@@ -223,4 +228,103 @@ void ScheduleMicrotask(Dart_NativeArguments args) {
223228 UIDartState::Current ()->ScheduleMicrotask (closure);
224229}
225230
231+ static std::string GetFunctionLibraryUrl (Dart_Handle closure) {
232+ if (Dart_IsClosure (closure)) {
233+ closure = Dart_ClosureFunction (closure);
234+ DART_CHECK_VALID (closure);
235+ }
236+
237+ if (!Dart_IsFunction (closure)) {
238+ return " " ;
239+ }
240+
241+ Dart_Handle url = Dart_Null ();
242+ Dart_Handle owner = Dart_FunctionOwner (closure);
243+ if (Dart_IsInstance (owner)) {
244+ owner = Dart_ClassLibrary (owner);
245+ }
246+ if (Dart_IsLibrary (owner)) {
247+ url = Dart_LibraryUrl (owner);
248+ DART_CHECK_VALID (url);
249+ }
250+ return DartConverter<std::string>::FromDart (url);
251+ }
252+
253+ static std::string GetFunctionClassName (Dart_Handle closure) {
254+ Dart_Handle result;
255+
256+ if (Dart_IsClosure (closure)) {
257+ closure = Dart_ClosureFunction (closure);
258+ DART_CHECK_VALID (closure);
259+ }
260+
261+ if (!Dart_IsFunction (closure)) {
262+ return " " ;
263+ }
264+
265+ bool is_static = false ;
266+ result = Dart_FunctionIsStatic (closure, &is_static);
267+ DART_CHECK_VALID (result);
268+ if (!is_static) {
269+ return " " ;
270+ }
271+
272+ result = Dart_FunctionOwner (closure);
273+ DART_CHECK_VALID (result);
274+
275+ if (Dart_IsLibrary (result) || !Dart_IsInstance (result)) {
276+ return " " ;
277+ }
278+ return DartConverter<std::string>::FromDart (Dart_ClassName (result));
279+ }
280+
281+ static std::string GetFunctionName (Dart_Handle func) {
282+ DART_CHECK_VALID (func);
283+
284+ if (Dart_IsClosure (func)) {
285+ func = Dart_ClosureFunction (func);
286+ DART_CHECK_VALID (func);
287+ }
288+
289+ if (!Dart_IsFunction (func)) {
290+ return " " ;
291+ }
292+
293+ bool is_static = false ;
294+ Dart_Handle result = Dart_FunctionIsStatic (func, &is_static);
295+ DART_CHECK_VALID (result);
296+ if (!is_static) {
297+ return " " ;
298+ }
299+
300+ result = Dart_FunctionName (func);
301+ if (Dart_IsError (result)) {
302+ Dart_PropagateError (result);
303+ return " " ;
304+ }
305+
306+ return DartConverter<std::string>::FromDart (result);
307+ }
308+
309+ void GetCallbackHandle (Dart_NativeArguments args) {
310+ Dart_Handle func = Dart_GetNativeArgument (args, 0 );
311+ std::string name = GetFunctionName (func);
312+ std::string class_name = GetFunctionClassName (func);
313+ std::string library_path = GetFunctionLibraryUrl (func);
314+
315+ if (name.empty ()) {
316+ Dart_SetReturnValue (args, Dart_Null ());
317+ return ;
318+ }
319+ Dart_SetReturnValue (
320+ args, DartConverter<int64_t >::ToDart (DartCallbackCache::GetCallbackHandle (
321+ name, class_name, library_path)));
322+ }
323+
324+ void GetCallbackFromHandle (Dart_NativeArguments args) {
325+ Dart_Handle h = Dart_GetNativeArgument (args, 0 );
326+ int64_t handle = DartConverter<int64_t >::FromDart (h);
327+ Dart_SetReturnValue (args, DartCallbackCache::GetCallback (handle));
328+ }
329+
226330} // namespace blink
0 commit comments