use new event channel for mobile and web

This commit is contained in:
csf
2022-05-17 19:59:37 +08:00
parent 85a2a7cd44
commit a7af7967f6
26 changed files with 1875 additions and 480 deletions

View File

@@ -120,11 +120,9 @@ class FfiModel with ChangeNotifier {
_permissions.clear();
}
void update(String peerId) {
var pos;
for (;;) {
var evt = FFI.popEvent();
if (evt == null) break;
void updateEventListener(String peerId) {
final void Function(Map<String, dynamic>) cb = (evt) {
var pos;
var name = evt['name'];
if (name == 'msgbox') {
handleMsgBox(evt, peerId);
@@ -165,31 +163,33 @@ class FfiModel with ChangeNotifier {
} else if (name == 'on_client_remove') {
FFI.serverModel.onClientRemove(evt);
}
}
if (pos != null) FFI.cursorModel.updateCursorPosition(pos);
if (!_decoding) {
var rgba = PlatformFFI.getRgba();
if (rgba != null) {
if (_waitForImage) {
_waitForImage = false;
SmartDialog.dismiss();
}
_decoding = true;
final pid = FFI.id;
ui.decodeImageFromPixels(rgba, _display.width, _display.height,
isWeb ? ui.PixelFormat.rgba8888 : ui.PixelFormat.bgra8888, (image) {
PlatformFFI.clearRgbaFrame();
_decoding = false;
if (FFI.id != pid) return;
try {
// my throw exception, because the listener maybe already dispose
FFI.imageModel.update(image);
} catch (e) {
print('update image: $e');
if (pos != null) FFI.cursorModel.updateCursorPosition(pos);
if (!_decoding) {
var rgba = PlatformFFI.getRgba();
if (rgba != null) {
if (_waitForImage) {
_waitForImage = false;
SmartDialog.dismiss();
}
});
_decoding = true;
final pid = FFI.id;
ui.decodeImageFromPixels(rgba, _display.width, _display.height,
isWeb ? ui.PixelFormat.rgba8888 : ui.PixelFormat.bgra8888,
(image) {
PlatformFFI.clearRgbaFrame();
_decoding = false;
if (FFI.id != pid) return;
try {
// my throw exception, because the listener maybe already dispose
FFI.imageModel.update(image);
} catch (e) {
print('update image: $e');
}
});
}
}
}
};
PlatformFFI.setEventCallback(cb);
}
void handleSwitchDisplay(Map<String, dynamic> evt) {
@@ -214,7 +214,6 @@ class FfiModel with ChangeNotifier {
enterPasswordDialog(id);
} else {
var hasRetry = evt['hasRetry'] == 'true';
print(evt);
showMsgBox(type, title, text, hasRetry);
}
}

View File

@@ -1,3 +1,4 @@
import 'dart:convert';
import 'dart:io';
import 'dart:typed_data';
import 'dart:ffi';
@@ -7,6 +8,7 @@ import 'package:device_info/device_info.dart';
import 'package:package_info/package_info.dart';
import 'package:external_path/external_path.dart';
import 'package:flutter/services.dart';
import '../generated_bridge.dart';
import '../common.dart';
class RgbaFrame extends Struct {
@@ -28,6 +30,7 @@ class PlatformFFI {
static F3? _setByName;
static F4? _freeRgba;
static F5? _getRgba;
static void Function(Map<String, dynamic>)? _eventCallback;
static void clearRgbaFrame() {
if (_lastRgbaFrame != null &&
@@ -86,6 +89,7 @@ class PlatformFFI {
.lookupFunction<Void Function(Pointer<RgbaFrame>), F4>('free_rgba');
_getRgba = dylib.lookupFunction<F5, F5>('get_rgba');
_dir = (await getApplicationDocumentsDirectory()).path;
_startListenEvent(RustdeskImpl(dylib));
try {
_homeDir = (await ExternalPath.getExternalStorageDirectories())[0];
} catch (e) {
@@ -115,6 +119,23 @@ class PlatformFFI {
version = await getVersion();
}
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');
}
}
}
}
static void setEventCallback(void Function(Map<String, dynamic>) fun) async {
_eventCallback = fun;
}
static void startDesktopWebListener() {}
static void stopDesktopWebListener() {}

View File

@@ -1,6 +1,5 @@
import 'dart:async';
import 'dart:convert';
import 'package:dash_chat/dash_chat.dart';
import 'package:flutter/material.dart';
import 'package:wakelock/wakelock.dart';
import '../common.dart';
@@ -11,7 +10,6 @@ const loginDialogTag = "LOGIN";
final _emptyIdShow = translate("Generating ...");
class ServerModel with ChangeNotifier {
Timer? _interval;
bool _isStart = false; // Android MainService status
bool _mediaOk = false;
bool _inputOk = false;
@@ -201,10 +199,7 @@ class ServerModel with ChangeNotifier {
_isStart = true;
notifyListeners();
FFI.setByName("ensure_init_event_queue");
_interval?.cancel();
_interval = Timer.periodic(Duration(milliseconds: 30), (timer) {
FFI.ffiModel.update("");
});
FFI.ffiModel.updateEventListener("");
await FFI.invokeMethod("init_service");
FFI.setByName("start_service");
getIDPasswd();
@@ -214,8 +209,6 @@ class ServerModel with ChangeNotifier {
Future<Null> stopService() async {
_isStart = false;
_interval?.cancel();
_interval = null;
FFI.serverModel.closeAll();
await FFI.invokeMethod("stop_service");
FFI.setByName("stop_service");

View File

@@ -1,5 +1,6 @@
import 'dart:convert';
import 'dart:typed_data';
import 'dart:js' as js;
import 'dart:js';
import '../common.dart';
import 'dart:html';
@@ -7,39 +8,46 @@ import 'dart:async';
final List<StreamSubscription<MouseEvent>> mouseListeners = [];
final List<StreamSubscription<KeyboardEvent>> keyListeners = [];
int lastMouseDownButtons = 0;
bool mouseIn = false;
class PlatformFFI {
static void clearRgbaFrame() {}
static Uint8List? getRgba() {
return js.context.callMethod('getRgba');
return context.callMethod('getRgba');
}
static String getByName(String name, [String arg = '']) {
return js.context.callMethod('getByName', [name, arg]);
return context.callMethod('getByName', [name, arg]);
}
static void setByName(String name, [String value = '']) {
js.context.callMethod('setByName', [name, value]);
context.callMethod('setByName', [name, value]);
}
static Future<Null> init() async {
isWeb = true;
isDesktop = !js.context.callMethod('isMobile');
js.context.callMethod('init');
isDesktop = !context.callMethod('isMobile');
context.callMethod('init');
version = getByName('version');
}
static void setEventCallback(void Function(Map<String, dynamic>) fun) async {
context["onGlobalEvent"] = (String message) {
try {
Map<String, dynamic> event = json.decode(message);
fun(event);
} catch (e) {
print('json.decode fail(): $e');
}
};
}
static void startDesktopWebListener() {
mouseIn = true;
mouseListeners.add(
window.document.onContextMenu.listen((evt) => evt.preventDefault()));
}
static void stopDesktopWebListener() {
mouseIn = true;
mouseListeners.forEach((l) {
l.cancel();
});