| 
									
										
										
										
											2022-05-17 19:59:37 +08:00
										 |  |  | import 'dart:convert'; | 
					
						
							| 
									
										
										
										
											2022-01-26 12:48:16 +08:00
										 |  |  | import 'dart:io'; | 
					
						
							|  |  |  | import 'dart:typed_data'; | 
					
						
							|  |  |  | import 'dart:ffi'; | 
					
						
							|  |  |  | import 'package:ffi/ffi.dart'; | 
					
						
							|  |  |  | import 'package:path_provider/path_provider.dart'; | 
					
						
							|  |  |  | import 'package:device_info/device_info.dart'; | 
					
						
							| 
									
										
										
										
											2022-01-26 19:00:23 +08:00
										 |  |  | import 'package:package_info/package_info.dart'; | 
					
						
							| 
									
										
										
										
											2022-02-10 02:07:53 +08:00
										 |  |  | import 'package:external_path/external_path.dart'; | 
					
						
							|  |  |  | import 'package:flutter/services.dart'; | 
					
						
							| 
									
										
										
										
											2022-05-17 19:59:37 +08:00
										 |  |  | import '../generated_bridge.dart'; | 
					
						
							| 
									
										
										
										
											2022-02-28 18:29:25 +08:00
										 |  |  | import '../common.dart'; | 
					
						
							| 
									
										
										
										
											2022-01-26 12:48:16 +08:00
										 |  |  | 
 | 
					
						
							|  |  |  | class RgbaFrame extends Struct { | 
					
						
							|  |  |  |   @Uint32() | 
					
						
							| 
									
										
										
										
											2022-02-17 15:22:14 +08:00
										 |  |  |   external int len; | 
					
						
							|  |  |  |   external Pointer<Uint8> data; | 
					
						
							| 
									
										
										
										
											2022-01-26 12:48:16 +08:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | typedef F2 = Pointer<Utf8> Function(Pointer<Utf8>, Pointer<Utf8>); | 
					
						
							|  |  |  | typedef F3 = void Function(Pointer<Utf8>, Pointer<Utf8>); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | class PlatformFFI { | 
					
						
							|  |  |  |   static String _dir = ''; | 
					
						
							| 
									
										
										
										
											2022-02-10 02:07:53 +08:00
										 |  |  |   static String _homeDir = ''; | 
					
						
							| 
									
										
										
										
											2022-02-17 15:22:14 +08:00
										 |  |  |   static F2? _getByName; | 
					
						
							|  |  |  |   static F3? _setByName; | 
					
						
							| 
									
										
										
										
											2022-05-17 19:59:37 +08:00
										 |  |  |   static void Function(Map<String, dynamic>)? _eventCallback; | 
					
						
							| 
									
										
										
										
											2022-05-19 23:45:44 +08:00
										 |  |  |   static void Function(Uint8List)? _rgbaCallback; | 
					
						
							| 
									
										
										
										
											2022-01-26 12:48:16 +08:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2022-01-26 19:00:23 +08:00
										 |  |  |   static Future<String> getVersion() async { | 
					
						
							|  |  |  |     PackageInfo packageInfo = await PackageInfo.fromPlatform(); | 
					
						
							|  |  |  |     return packageInfo.version; | 
					
						
							|  |  |  |   } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2022-01-26 12:48:16 +08:00
										 |  |  |   static String getByName(String name, [String arg = '']) { | 
					
						
							|  |  |  |     if (_getByName == null) return ''; | 
					
						
							|  |  |  |     var a = name.toNativeUtf8(); | 
					
						
							|  |  |  |     var b = arg.toNativeUtf8(); | 
					
						
							| 
									
										
										
										
											2022-02-17 15:22:14 +08:00
										 |  |  |     var p = _getByName!(a, b); | 
					
						
							| 
									
										
										
										
											2022-04-18 17:01:45 +08:00
										 |  |  |     assert(p != nullptr); | 
					
						
							| 
									
										
										
										
											2022-01-26 12:48:16 +08:00
										 |  |  |     var res = p.toDartString(); | 
					
						
							|  |  |  |     calloc.free(p); | 
					
						
							|  |  |  |     calloc.free(a); | 
					
						
							|  |  |  |     calloc.free(b); | 
					
						
							|  |  |  |     return res; | 
					
						
							|  |  |  |   } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |   static void setByName(String name, [String value = '']) { | 
					
						
							|  |  |  |     if (_setByName == null) return; | 
					
						
							|  |  |  |     var a = name.toNativeUtf8(); | 
					
						
							|  |  |  |     var b = value.toNativeUtf8(); | 
					
						
							| 
									
										
										
										
											2022-02-17 15:22:14 +08:00
										 |  |  |     _setByName!(a, b); | 
					
						
							| 
									
										
										
										
											2022-01-26 12:48:16 +08:00
										 |  |  |     calloc.free(a); | 
					
						
							|  |  |  |     calloc.free(b); | 
					
						
							|  |  |  |   } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |   static Future<Null> init() async { | 
					
						
							|  |  |  |     isIOS = Platform.isIOS; | 
					
						
							|  |  |  |     isAndroid = Platform.isAndroid; | 
					
						
							|  |  |  |     final dylib = Platform.isAndroid | 
					
						
							|  |  |  |         ? DynamicLibrary.open('librustdesk.so') | 
					
						
							|  |  |  |         : DynamicLibrary.process(); | 
					
						
							|  |  |  |     print('initializing FFI'); | 
					
						
							|  |  |  |     try { | 
					
						
							|  |  |  |       _getByName = dylib.lookupFunction<F2, F2>('get_by_name'); | 
					
						
							|  |  |  |       _setByName = | 
					
						
							|  |  |  |           dylib.lookupFunction<Void Function(Pointer<Utf8>, Pointer<Utf8>), F3>( | 
					
						
							|  |  |  |               'set_by_name'); | 
					
						
							|  |  |  |       _dir = (await getApplicationDocumentsDirectory()).path; | 
					
						
							| 
									
										
										
										
											2022-05-17 19:59:37 +08:00
										 |  |  |       _startListenEvent(RustdeskImpl(dylib)); | 
					
						
							| 
									
										
										
										
											2022-04-18 17:01:45 +08:00
										 |  |  |       try { | 
					
						
							|  |  |  |         _homeDir = (await ExternalPath.getExternalStorageDirectories())[0]; | 
					
						
							|  |  |  |       } catch (e) { | 
					
						
							|  |  |  |         print(e); | 
					
						
							|  |  |  |       } | 
					
						
							| 
									
										
										
										
											2022-01-26 12:48:16 +08:00
										 |  |  |       String id = 'NA'; | 
					
						
							|  |  |  |       String name = 'Flutter'; | 
					
						
							|  |  |  |       DeviceInfoPlugin deviceInfo = DeviceInfoPlugin(); | 
					
						
							|  |  |  |       if (Platform.isAndroid) { | 
					
						
							|  |  |  |         AndroidDeviceInfo androidInfo = await deviceInfo.androidInfo; | 
					
						
							|  |  |  |         name = '${androidInfo.brand}-${androidInfo.model}'; | 
					
						
							|  |  |  |         id = androidInfo.id.hashCode.toString(); | 
					
						
							| 
									
										
										
										
											2022-03-24 17:58:33 +08:00
										 |  |  |         androidVersion = androidInfo.version.sdkInt; | 
					
						
							| 
									
										
										
										
											2022-01-26 12:48:16 +08:00
										 |  |  |       } else { | 
					
						
							|  |  |  |         IosDeviceInfo iosInfo = await deviceInfo.iosInfo; | 
					
						
							|  |  |  |         name = iosInfo.utsname.machine; | 
					
						
							|  |  |  |         id = iosInfo.identifierForVendor.hashCode.toString(); | 
					
						
							|  |  |  |       } | 
					
						
							| 
									
										
										
										
											2022-02-10 02:07:53 +08:00
										 |  |  |       print("info1-id:$id,info2-name:$name,dir:$_dir,homeDir:$_homeDir"); | 
					
						
							| 
									
										
										
										
											2022-01-26 12:48:16 +08:00
										 |  |  |       setByName('info1', id); | 
					
						
							|  |  |  |       setByName('info2', name); | 
					
						
							| 
									
										
										
										
											2022-02-10 02:07:53 +08:00
										 |  |  |       setByName('home_dir', _homeDir); | 
					
						
							| 
									
										
										
										
											2022-01-26 12:48:16 +08:00
										 |  |  |       setByName('init', _dir); | 
					
						
							|  |  |  |     } catch (e) { | 
					
						
							|  |  |  |       print(e); | 
					
						
							|  |  |  |     } | 
					
						
							| 
									
										
										
										
											2022-02-28 21:26:44 +08:00
										 |  |  |     version = await getVersion(); | 
					
						
							| 
									
										
										
										
											2022-01-26 12:48:16 +08:00
										 |  |  |   } | 
					
						
							| 
									
										
										
										
											2022-02-03 00:53:59 +08:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2022-05-19 23:45:44 +08:00
										 |  |  |   static void _startListenEvent(RustdeskImpl rustdeskImpl) { | 
					
						
							|  |  |  |     () async { | 
					
						
							|  |  |  |       await for (final message in rustdeskImpl.startEventStream()) { | 
					
						
							|  |  |  |         if (_eventCallback != null) { | 
					
						
							|  |  |  |           try { | 
					
						
							|  |  |  |             Map<String, dynamic> event = json.decode(message); | 
					
						
							|  |  |  |             _eventCallback!(event); | 
					
						
							|  |  |  |           } catch (e) { | 
					
						
							|  |  |  |             print('json.decode fail(): $e'); | 
					
						
							|  |  |  |           } | 
					
						
							| 
									
										
										
										
											2022-05-17 19:59:37 +08:00
										 |  |  |         } | 
					
						
							|  |  |  |       } | 
					
						
							| 
									
										
										
										
											2022-05-19 23:45:44 +08:00
										 |  |  |     }(); | 
					
						
							|  |  |  |     () async { | 
					
						
							|  |  |  |       await for (final rgba in rustdeskImpl.startRgbaStream()) { | 
					
						
							|  |  |  |         if (_rgbaCallback != null) { | 
					
						
							|  |  |  |           _rgbaCallback!(rgba); | 
					
						
							|  |  |  |         } else { | 
					
						
							|  |  |  |           rgba.clear(); | 
					
						
							|  |  |  |         } | 
					
						
							|  |  |  |       } | 
					
						
							|  |  |  |     }(); | 
					
						
							| 
									
										
										
										
											2022-05-17 19:59:37 +08:00
										 |  |  |   } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |   static void setEventCallback(void Function(Map<String, dynamic>) fun) async { | 
					
						
							|  |  |  |     _eventCallback = fun; | 
					
						
							|  |  |  |   } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2022-05-19 23:45:44 +08:00
										 |  |  |   static void setRgbaCallback(void Function(Uint8List) fun) async { | 
					
						
							|  |  |  |     _rgbaCallback = fun; | 
					
						
							|  |  |  |   } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2022-04-25 18:25:25 +08:00
										 |  |  |   static void startDesktopWebListener() {} | 
					
						
							| 
									
										
										
										
											2022-02-17 15:22:14 +08:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2022-02-03 00:53:59 +08:00
										 |  |  |   static void stopDesktopWebListener() {} | 
					
						
							| 
									
										
										
										
											2022-02-10 02:07:53 +08:00
										 |  |  | 
 | 
					
						
							|  |  |  |   static void setMethodCallHandler(FMethod callback) { | 
					
						
							|  |  |  |     toAndroidChannel.setMethodCallHandler((call) async { | 
					
						
							|  |  |  |       callback(call.method, call.arguments); | 
					
						
							|  |  |  |       return null; | 
					
						
							|  |  |  |     }); | 
					
						
							|  |  |  |   } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2022-04-18 17:01:45 +08:00
										 |  |  |   static invokeMethod(String method, [dynamic arguments]) async { | 
					
						
							| 
									
										
										
										
											2022-04-18 11:46:36 +08:00
										 |  |  |     if (!isAndroid) return Future<bool>(() => false); | 
					
						
							| 
									
										
										
										
											2022-04-18 17:01:45 +08:00
										 |  |  |     return await toAndroidChannel.invokeMethod(method, arguments); | 
					
						
							| 
									
										
										
										
											2022-02-10 02:07:53 +08:00
										 |  |  |   } | 
					
						
							| 
									
										
										
										
											2022-01-26 12:48:16 +08:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | final localeName = Platform.localeName; | 
					
						
							| 
									
										
										
										
											2022-02-10 02:07:53 +08:00
										 |  |  | final toAndroidChannel = MethodChannel("mChannel"); |