mirror of
https://github.com/rustdesk/rustdesk.git
synced 2024-11-25 05:09:04 +08:00
refactor all [setByName] [getByName] to async bridge function
This commit is contained in:
parent
c5d0628291
commit
e420178750
@ -825,10 +825,34 @@ class WebMenu extends StatefulWidget {
|
||||
}
|
||||
|
||||
class _WebMenuState extends State<WebMenu> {
|
||||
String? username;
|
||||
String url = "";
|
||||
|
||||
@override
|
||||
void initState() {
|
||||
super.initState();
|
||||
() async {
|
||||
final usernameRes = await getUsername();
|
||||
final urlRes = await getUrl();
|
||||
var update = false;
|
||||
if (usernameRes != username) {
|
||||
username = usernameRes;
|
||||
update = true;
|
||||
}
|
||||
if (urlRes != url) {
|
||||
url = urlRes;
|
||||
update = true;
|
||||
}
|
||||
|
||||
if (update) {
|
||||
setState(() {});
|
||||
}
|
||||
}();
|
||||
}
|
||||
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
Provider.of<FfiModel>(context);
|
||||
final username = getUsername();
|
||||
return PopupMenuButton<String>(
|
||||
icon: Icon(Icons.more_vert),
|
||||
itemBuilder: (context) {
|
||||
@ -846,7 +870,7 @@ class _WebMenuState extends State<WebMenu> {
|
||||
value: "server",
|
||||
)
|
||||
] +
|
||||
(getUrl().contains('admin.rustdesk.com')
|
||||
(url.contains('admin.rustdesk.com')
|
||||
? <PopupMenuItem<String>>[]
|
||||
: [
|
||||
PopupMenuItem(
|
||||
|
@ -275,9 +275,7 @@ class _DesktopHomePageState extends State<DesktopHomePage> with TrayListener {
|
||||
),
|
||||
IconButton(
|
||||
icon: Icon(Icons.refresh),
|
||||
onPressed: () {
|
||||
gFFI.setByName("temporary_password");
|
||||
},
|
||||
onPressed: () => bind.mainUpdateTemporaryPassword(),
|
||||
),
|
||||
FutureBuilder<Widget>(
|
||||
future: buildPasswordPopupMenu(context),
|
||||
@ -360,7 +358,7 @@ class _DesktopHomePageState extends State<DesktopHomePage> with TrayListener {
|
||||
if (gFFI.serverModel.temporaryPasswordLength !=
|
||||
e) {
|
||||
gFFI.serverModel.temporaryPasswordLength = e;
|
||||
gFFI.setByName("temporary_password");
|
||||
bind.mainUpdateTemporaryPassword();
|
||||
}
|
||||
},
|
||||
))
|
||||
@ -1336,8 +1334,8 @@ Future<bool> loginDialog() async {
|
||||
return completer.future;
|
||||
}
|
||||
|
||||
void setPasswordDialog() {
|
||||
final pw = gFFI.getByName("permanent_password");
|
||||
void setPasswordDialog() async {
|
||||
final pw = await bind.mainGetPermanentPassword();
|
||||
final p0 = TextEditingController(text: pw);
|
||||
final p1 = TextEditingController(text: pw);
|
||||
var errMsg0 = "";
|
||||
@ -1427,7 +1425,7 @@ void setPasswordDialog() {
|
||||
});
|
||||
return;
|
||||
}
|
||||
gFFI.setByName("permanent_password", pass);
|
||||
bind.mainSetPermanentPassword(password: pass);
|
||||
close();
|
||||
},
|
||||
child: Text(translate("OK"))),
|
||||
|
@ -348,8 +348,9 @@ class _RemotePageState extends State<RemotePage>
|
||||
if (dy > 0)
|
||||
dy = -1;
|
||||
else if (dy < 0) dy = 1;
|
||||
_ffi.setByName('send_mouse',
|
||||
'{"id": "${widget.id}", "type": "wheel", "x": "$dx", "y": "$dy"}');
|
||||
bind.sessionSendMouse(
|
||||
id: widget.id,
|
||||
msg: '{"type": "wheel", "x": "$dx", "y": "$dy"}');
|
||||
}
|
||||
},
|
||||
child: MouseRegion(
|
||||
|
@ -187,7 +187,7 @@ class _PeerCardState extends State<_PeerCard>
|
||||
elevation: 8,
|
||||
);
|
||||
if (value == 'remove') {
|
||||
setState(() => gFFI.setByName('remove', '$id'));
|
||||
setState(() => bind.mainRemovePeer(id: id));
|
||||
() async {
|
||||
removePreference(id);
|
||||
}();
|
||||
|
@ -54,8 +54,9 @@ class _ConnectionPageState extends State<ConnectionPage> {
|
||||
}();
|
||||
}
|
||||
if (isAndroid) {
|
||||
Timer(Duration(seconds: 5), () {
|
||||
_updateUrl = gFFI.getByName('software_update_url');
|
||||
Timer(Duration(seconds: 5), () async {
|
||||
_updateUrl = await bind.mainGetSoftwareUpdateUrl();
|
||||
;
|
||||
if (_updateUrl.isNotEmpty) setState(() {});
|
||||
});
|
||||
}
|
||||
@ -299,7 +300,7 @@ class _ConnectionPageState extends State<ConnectionPage> {
|
||||
elevation: 8,
|
||||
);
|
||||
if (value == 'remove') {
|
||||
setState(() => gFFI.setByName('remove', '$id'));
|
||||
setState(() => bind.mainRemovePeer(id: id));
|
||||
() async {
|
||||
removePreference(id);
|
||||
}();
|
||||
@ -315,10 +316,34 @@ class WebMenu extends StatefulWidget {
|
||||
}
|
||||
|
||||
class _WebMenuState extends State<WebMenu> {
|
||||
String? username;
|
||||
String url = "";
|
||||
|
||||
@override
|
||||
void initState() {
|
||||
super.initState();
|
||||
() async {
|
||||
final usernameRes = await getUsername();
|
||||
final urlRes = await getUrl();
|
||||
var update = false;
|
||||
if (usernameRes != username) {
|
||||
username = usernameRes;
|
||||
update = true;
|
||||
}
|
||||
if (urlRes != url) {
|
||||
url = urlRes;
|
||||
update = true;
|
||||
}
|
||||
|
||||
if (update) {
|
||||
setState(() {});
|
||||
}
|
||||
}();
|
||||
}
|
||||
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
Provider.of<FfiModel>(context);
|
||||
final username = getUsername();
|
||||
return PopupMenuButton<String>(
|
||||
icon: Icon(Icons.more_vert),
|
||||
itemBuilder: (context) {
|
||||
@ -336,7 +361,7 @@ class _WebMenuState extends State<WebMenu> {
|
||||
value: "server",
|
||||
)
|
||||
] +
|
||||
(getUrl().contains('admin.rustdesk.com')
|
||||
(url.contains('admin.rustdesk.com')
|
||||
? <PopupMenuItem<String>>[]
|
||||
: [
|
||||
PopupMenuItem(
|
||||
|
@ -330,8 +330,9 @@ class _RemotePageState extends State<RemotePage> {
|
||||
if (dy > 0)
|
||||
dy = -1;
|
||||
else if (dy < 0) dy = 1;
|
||||
gFFI.setByName(
|
||||
'send_mouse', '{"type": "wheel", "x": "$dx", "y": "$dy"}');
|
||||
bind.sessionSendMouse(
|
||||
id: widget.id,
|
||||
msg: '{"type": "wheel", "x": "$dx", "y": "$dy"}');
|
||||
}
|
||||
},
|
||||
child: MouseRegion(
|
||||
@ -1124,7 +1125,7 @@ void showRestartRemoteDevice(PeerInfo pi, String id) async {
|
||||
onPressed: () => close(true), child: Text(translate("OK"))),
|
||||
],
|
||||
));
|
||||
if (res == true) gFFI.setByName('restart_remote_device');
|
||||
if (res == true) bind.sessionRestartRemoteDevice(id: id);
|
||||
}
|
||||
|
||||
void showSetOSPassword(String id, bool login) async {
|
||||
|
@ -1,13 +1,10 @@
|
||||
import 'dart:convert';
|
||||
|
||||
import 'package:flutter/material.dart';
|
||||
import 'package:flutter_hbb/mobile/widgets/dialog.dart';
|
||||
import 'package:flutter_hbb/models/model.dart';
|
||||
import 'package:flutter_smart_dialog/flutter_smart_dialog.dart';
|
||||
import 'package:provider/provider.dart';
|
||||
|
||||
import '../../common.dart';
|
||||
import '../../models/model.dart';
|
||||
import '../../models/platform_model.dart';
|
||||
import '../../models/server_model.dart';
|
||||
import 'home_page.dart';
|
||||
|
||||
@ -99,10 +96,7 @@ class ServerPage extends StatelessWidget implements PageShape {
|
||||
} else if (value == kUsePermanentPassword ||
|
||||
value == kUseTemporaryPassword ||
|
||||
value == kUseBothPasswords) {
|
||||
Map<String, String> msg = Map()
|
||||
..["name"] = "verification-method"
|
||||
..["value"] = value;
|
||||
gFFI.setByName('option', jsonEncode(msg));
|
||||
bind.mainSetOption(key: "verification-method", value: value);
|
||||
gFFI.serverModel.updatePasswordModel();
|
||||
}
|
||||
})
|
||||
@ -183,9 +177,8 @@ class ServerInfo extends StatelessWidget {
|
||||
? null
|
||||
: IconButton(
|
||||
icon: const Icon(Icons.refresh),
|
||||
onPressed: () {
|
||||
gFFI.setByName("temporary_password");
|
||||
})),
|
||||
onPressed: () =>
|
||||
bind.mainUpdateTemporaryPassword())),
|
||||
onSaved: (String? value) {},
|
||||
),
|
||||
],
|
||||
@ -406,8 +399,7 @@ class ConnectionManager extends StatelessWidget {
|
||||
MaterialStateProperty.all(Colors.red)),
|
||||
icon: Icon(Icons.close),
|
||||
onPressed: () {
|
||||
gFFI.setByName(
|
||||
"close_conn", entry.key.toString());
|
||||
bind.serverCloseConnection(connId: entry.key);
|
||||
gFFI.invokeMethod(
|
||||
"cancel_notification", entry.key);
|
||||
},
|
||||
|
@ -31,15 +31,38 @@ class SettingsPage extends StatefulWidget implements PageShape {
|
||||
const url = 'https://rustdesk.com/';
|
||||
final _hasIgnoreBattery = androidVersion >= 26;
|
||||
var _ignoreBatteryOpt = false;
|
||||
var _enableAbr = false;
|
||||
|
||||
class _SettingsState extends State<SettingsPage> with WidgetsBindingObserver {
|
||||
String? username;
|
||||
|
||||
@override
|
||||
void initState() {
|
||||
super.initState();
|
||||
WidgetsBinding.instance.addObserver(this);
|
||||
if (_hasIgnoreBattery) {
|
||||
updateIgnoreBatteryStatus();
|
||||
}
|
||||
|
||||
() async {
|
||||
var update = false;
|
||||
if (_hasIgnoreBattery) {
|
||||
update = await updateIgnoreBatteryStatus();
|
||||
}
|
||||
|
||||
final usernameRes = await getUsername();
|
||||
if (usernameRes != username) {
|
||||
update = true;
|
||||
username = usernameRes;
|
||||
}
|
||||
|
||||
final enableAbrRes = await bind.mainGetOption(key: "enable-abr") != "N";
|
||||
if (enableAbrRes != _enableAbr) {
|
||||
update = true;
|
||||
_enableAbr = enableAbrRes;
|
||||
}
|
||||
|
||||
if (update) {
|
||||
setState(() {});
|
||||
}
|
||||
}();
|
||||
}
|
||||
|
||||
@override
|
||||
@ -51,16 +74,18 @@ class _SettingsState extends State<SettingsPage> with WidgetsBindingObserver {
|
||||
@override
|
||||
void didChangeAppLifecycleState(AppLifecycleState state) {
|
||||
if (state == AppLifecycleState.resumed) {
|
||||
updateIgnoreBatteryStatus();
|
||||
() async {
|
||||
if (await updateIgnoreBatteryStatus()) {
|
||||
setState(() {});
|
||||
}
|
||||
}();
|
||||
}
|
||||
}
|
||||
|
||||
Future<bool> updateIgnoreBatteryStatus() async {
|
||||
final res = await PermissionManager.check("ignore_battery_optimizations");
|
||||
if (_ignoreBatteryOpt != res) {
|
||||
setState(() {
|
||||
_ignoreBatteryOpt = res;
|
||||
});
|
||||
_ignoreBatteryOpt = res;
|
||||
return true;
|
||||
} else {
|
||||
return false;
|
||||
@ -70,21 +95,15 @@ class _SettingsState extends State<SettingsPage> with WidgetsBindingObserver {
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
Provider.of<FfiModel>(context);
|
||||
final username = getUsername();
|
||||
final enableAbr = gFFI.getByName("option", "enable-abr") != 'N';
|
||||
final enhancementsTiles = [
|
||||
SettingsTile.switchTile(
|
||||
title: Text(translate('Adaptive Bitrate') + '(beta)'),
|
||||
initialValue: enableAbr,
|
||||
title: Text(translate('Adaptive Bitrate') + ' (beta)'),
|
||||
initialValue: _enableAbr,
|
||||
onToggle: (v) {
|
||||
final msg = Map()
|
||||
..["name"] = "enable-abr"
|
||||
..["value"] = "";
|
||||
if (!v) {
|
||||
msg["value"] = "N";
|
||||
}
|
||||
gFFI.setByName("option", json.encode(msg));
|
||||
setState(() {});
|
||||
bind.mainSetOption(key: "enable-abr", value: v ? "" : "N");
|
||||
setState(() {
|
||||
_enableAbr = !_enableAbr;
|
||||
});
|
||||
},
|
||||
)
|
||||
];
|
||||
@ -196,7 +215,7 @@ void showServerSettings() async {
|
||||
|
||||
void showLanguageSettings() async {
|
||||
try {
|
||||
final langs = json.decode(gFFI.getByName('langs')) as List<dynamic>;
|
||||
final langs = json.decode(await bind.mainGetLangs()) as List<dynamic>;
|
||||
var lang = await bind.mainGetLocalOption(key: "lang");
|
||||
DialogManager.show((setState, close) {
|
||||
final setLang = (v) {
|
||||
@ -297,20 +316,19 @@ String parseResp(String body) {
|
||||
}
|
||||
final token = data['access_token'];
|
||||
if (token != null) {
|
||||
gFFI.setByName('option', '{"name": "access_token", "value": "$token"}');
|
||||
bind.mainSetOption(key: "access_token", value: token);
|
||||
}
|
||||
final info = data['user'];
|
||||
if (info != null) {
|
||||
final value = json.encode(info);
|
||||
gFFI.setByName(
|
||||
'option', json.encode({"name": "user_info", "value": value}));
|
||||
bind.mainSetOption(key: "user_info", value: value);
|
||||
gFFI.ffiModel.updateUser();
|
||||
}
|
||||
return '';
|
||||
}
|
||||
|
||||
void refreshCurrentUser() async {
|
||||
final token = gFFI.getByName("option", "access_token");
|
||||
final token = await bind.mainGetOption(key: "access_token");
|
||||
if (token == '') return;
|
||||
final url = getUrl();
|
||||
final body = {'id': bind.mainGetMyId(), 'uuid': bind.mainGetUuid()};
|
||||
@ -333,7 +351,7 @@ void refreshCurrentUser() async {
|
||||
}
|
||||
|
||||
void logout() async {
|
||||
final token = gFFI.getByName("option", "access_token");
|
||||
final token = await bind.mainGetOption(key: "access_token");
|
||||
if (token == '') return;
|
||||
final url = getUrl();
|
||||
final body = {'id': bind.mainGetMyId(), 'uuid': bind.mainGetUuid()};
|
||||
@ -350,16 +368,16 @@ void logout() async {
|
||||
resetToken();
|
||||
}
|
||||
|
||||
void resetToken() {
|
||||
gFFI.setByName('option', '{"name": "access_token", "value": ""}');
|
||||
gFFI.setByName('option', '{"name": "user_info", "value": ""}');
|
||||
void resetToken() async {
|
||||
await bind.mainSetOption(key: "access_token", value: "");
|
||||
await bind.mainSetOption(key: "user_info", value: "");
|
||||
gFFI.ffiModel.updateUser();
|
||||
}
|
||||
|
||||
String getUrl() {
|
||||
var url = gFFI.getByName('option', 'api-server');
|
||||
Future<String> getUrl() async {
|
||||
var url = await bind.mainGetOption(key: "api-server");
|
||||
if (url == '') {
|
||||
url = gFFI.getByName('option', 'custom-rendezvous-server');
|
||||
url = await bind.mainGetOption(key: "custom-rendezvous-server");
|
||||
if (url != '') {
|
||||
if (url.contains(':')) {
|
||||
final tmp = url.split(':');
|
||||
@ -448,11 +466,11 @@ void showLogin() {
|
||||
});
|
||||
}
|
||||
|
||||
String? getUsername() {
|
||||
final token = gFFI.getByName("option", "access_token");
|
||||
Future<String?> getUsername() async {
|
||||
final token = await bind.mainGetOption(key: "access_token");
|
||||
String? username;
|
||||
if (token != "") {
|
||||
final info = gFFI.getByName("option", "user_info");
|
||||
final info = await bind.mainGetOption(key: "user_info");
|
||||
if (info != "") {
|
||||
try {
|
||||
Map<String, dynamic> tmp = json.decode(info);
|
||||
|
@ -1,11 +1,9 @@
|
||||
import 'dart:async';
|
||||
import 'dart:convert';
|
||||
|
||||
import 'package:flutter/material.dart';
|
||||
import 'package:flutter_smart_dialog/flutter_smart_dialog.dart';
|
||||
|
||||
import '../../common.dart';
|
||||
import '../../models/model.dart';
|
||||
import '../../models/platform_model.dart';
|
||||
|
||||
void clientClose() {
|
||||
msgBox('', 'Close', 'Are you sure to close the connection?');
|
||||
@ -22,8 +20,8 @@ void showError({Duration duration = SEC1}) {
|
||||
showToast(translate("Error"), duration: SEC1);
|
||||
}
|
||||
|
||||
void setPermanentPasswordDialog() {
|
||||
final pw = gFFI.getByName("permanent_password");
|
||||
void setPermanentPasswordDialog() async {
|
||||
final pw = await bind.mainGetPermanentPassword();
|
||||
final p0 = TextEditingController(text: pw);
|
||||
final p1 = TextEditingController(text: pw);
|
||||
var validateLength = false;
|
||||
@ -103,9 +101,9 @@ void setPermanentPasswordDialog() {
|
||||
});
|
||||
}
|
||||
|
||||
void setTemporaryPasswordLengthDialog() {
|
||||
void setTemporaryPasswordLengthDialog() async {
|
||||
List<String> lengths = ['6', '8', '10'];
|
||||
String length = gFFI.getByName('option', 'temporary-password-length');
|
||||
String length = await bind.mainGetOption(key: "temporary-password-length");
|
||||
var index = lengths.indexOf(length);
|
||||
if (index < 0) index = 0;
|
||||
length = lengths[index];
|
||||
@ -116,11 +114,8 @@ void setTemporaryPasswordLengthDialog() {
|
||||
setState(() {
|
||||
length = newValue;
|
||||
});
|
||||
Map<String, String> msg = Map()
|
||||
..["name"] = "temporary-password-length"
|
||||
..["value"] = newValue;
|
||||
gFFI.setByName("option", jsonEncode(msg));
|
||||
gFFI.setByName("temporary_password");
|
||||
bind.mainSetOption(key: "temporary-password-length", value: newValue);
|
||||
bind.mainUpdateTemporaryPassword();
|
||||
Future.delayed(Duration(milliseconds: 200), () {
|
||||
close();
|
||||
showSuccess();
|
||||
@ -138,9 +133,9 @@ void setTemporaryPasswordLengthDialog() {
|
||||
}, backDismiss: true, clickMaskDismiss: true);
|
||||
}
|
||||
|
||||
void enterPasswordDialog(String id) {
|
||||
void enterPasswordDialog(String id) async {
|
||||
final controller = TextEditingController();
|
||||
var remember = gFFI.getByName('remember', id) == 'true';
|
||||
var remember = await bind.getSessionRemember(id: id) ?? false;
|
||||
DialogManager.show((setState, close) {
|
||||
return CustomAlertDialog(
|
||||
title: Text(translate('Password Required')),
|
||||
|
@ -1,5 +1,3 @@
|
||||
import 'dart:convert';
|
||||
|
||||
import 'package:dash_chat_2/dash_chat_2.dart';
|
||||
import 'package:flutter/material.dart';
|
||||
import 'package:flutter_hbb/models/platform_model.dart';
|
||||
@ -106,12 +104,11 @@ class ChatModel with ChangeNotifier {
|
||||
if (message.text.isNotEmpty) {
|
||||
_messages[_currentID]?.insert(message);
|
||||
if (_currentID == clientModeID) {
|
||||
_ffi.target?.setByName("chat_client_mode", message.text);
|
||||
if (_ffi.target != null) {
|
||||
bind.sessionSendChat(id: _ffi.target!.id, text: message.text);
|
||||
}
|
||||
} else {
|
||||
final msg = Map()
|
||||
..["id"] = _currentID
|
||||
..["text"] = message.text;
|
||||
_ffi.target?.setByName("chat_server_mode", jsonEncode(msg));
|
||||
bind.serverSendChat(connId: _currentID, msg: message.text);
|
||||
}
|
||||
}
|
||||
notifyListeners();
|
||||
|
@ -290,7 +290,7 @@ class FileModel extends ChangeNotifier {
|
||||
}
|
||||
|
||||
onReady() async {
|
||||
_localOption.home = _ffi.target?.getByName("get_home_dir") ?? "";
|
||||
_localOption.home = await bind.mainGetHomeDir();
|
||||
_localOption.showHidden = (await bind.sessionGetPeerOption(
|
||||
id: _ffi.target?.id ?? "", name: "local_show_hidden"))
|
||||
.isNotEmpty;
|
||||
|
@ -889,8 +889,10 @@ class FFI {
|
||||
|
||||
/// Send scroll event with scroll distance [y].
|
||||
void scroll(int y) {
|
||||
setByName('send_mouse',
|
||||
json.encode(modify({'id': id, 'type': 'wheel', 'y': y.toString()})));
|
||||
bind.sessionSendMouse(
|
||||
id: id,
|
||||
msg: json
|
||||
.encode(modify({'id': id, 'type': 'wheel', 'y': y.toString()})));
|
||||
}
|
||||
|
||||
/// Reconnect to the remote peer.
|
||||
@ -916,8 +918,9 @@ class FFI {
|
||||
/// Send mouse press event.
|
||||
void sendMouse(String type, MouseButtons button) {
|
||||
if (!ffiModel.keyboard()) return;
|
||||
setByName('send_mouse',
|
||||
json.encode(modify({'id': id, 'type': type, 'buttons': button.value})));
|
||||
bind.sessionSendMouse(
|
||||
id: id,
|
||||
msg: json.encode(modify({'type': type, 'buttons': button.value})));
|
||||
}
|
||||
|
||||
/// Send key stroke event.
|
||||
@ -953,8 +956,8 @@ class FFI {
|
||||
if (!ffiModel.keyboard()) return;
|
||||
var x2 = x.toInt();
|
||||
var y2 = y.toInt();
|
||||
setByName(
|
||||
'send_mouse', json.encode(modify({'id': id, 'x': '$x2', 'y': '$y2'})));
|
||||
bind.sessionSendMouse(
|
||||
id: id, msg: json.encode(modify({'x': '$x2', 'y': '$y2'})));
|
||||
}
|
||||
|
||||
/// List the saved peers.
|
||||
@ -1032,14 +1035,14 @@ class FFI {
|
||||
|
||||
/// Send **get** command to the Rust core based on [name] and [arg].
|
||||
/// Return the result as a string.
|
||||
String getByName(String name, [String arg = '']) {
|
||||
return platformFFI.getByName(name, arg);
|
||||
}
|
||||
// String getByName(String name, [String arg = '']) {
|
||||
// return platformFFI.getByName(name, arg);
|
||||
// }
|
||||
|
||||
/// Send **set** command to the Rust core based on [name] and [value].
|
||||
void setByName(String name, [String value = '']) {
|
||||
platformFFI.setByName(name, value);
|
||||
}
|
||||
// void setByName(String name, [String value = '']) {
|
||||
// platformFFI.setByName(name, value);
|
||||
// }
|
||||
|
||||
handleMouse(Map<String, dynamic> evt, {double tabBarHeight = 0.0}) {
|
||||
var type = '';
|
||||
@ -1092,8 +1095,7 @@ class FFI {
|
||||
break;
|
||||
}
|
||||
evt['buttons'] = buttons;
|
||||
evt['id'] = id;
|
||||
setByName('send_mouse', json.encode(evt));
|
||||
bind.sessionSendMouse(id: id, msg: json.encode(evt));
|
||||
}
|
||||
|
||||
listenToMouse(bool yesOrNo) {
|
||||
|
@ -30,8 +30,6 @@ class PlatformFFI {
|
||||
String _dir = '';
|
||||
String _homeDir = '';
|
||||
F2? _translate;
|
||||
F2? _getByName;
|
||||
F3? _setByName;
|
||||
var _eventHandlers = Map<String, Map<String, HandleEvent>>();
|
||||
late RustdeskImpl _ffiBind;
|
||||
late String _appType;
|
||||
@ -89,31 +87,6 @@ class PlatformFFI {
|
||||
return res;
|
||||
}
|
||||
|
||||
/// Send **get** command to the Rust core based on [name] and [arg].
|
||||
/// Return the result as a string.
|
||||
String getByName(String name, [String arg = '']) {
|
||||
if (_getByName == null) return '';
|
||||
var a = name.toNativeUtf8();
|
||||
var b = arg.toNativeUtf8();
|
||||
var p = _getByName!(a, b);
|
||||
assert(p != nullptr);
|
||||
var res = p.toDartString();
|
||||
calloc.free(p);
|
||||
calloc.free(a);
|
||||
calloc.free(b);
|
||||
return res;
|
||||
}
|
||||
|
||||
/// Send **set** command to the Rust core based on [name] and [value].
|
||||
void setByName(String name, [String value = '']) {
|
||||
if (_setByName == null) return;
|
||||
var a = name.toNativeUtf8();
|
||||
var b = value.toNativeUtf8();
|
||||
_setByName!(a, b);
|
||||
calloc.free(a);
|
||||
calloc.free(b);
|
||||
}
|
||||
|
||||
/// Init the FFI class, loads the native Rust core library.
|
||||
Future<Null> init(String appType) async {
|
||||
_appType = appType;
|
||||
@ -133,10 +106,6 @@ class PlatformFFI {
|
||||
debugPrint('initializing FFI ${_appType}');
|
||||
try {
|
||||
_translate = dylib.lookupFunction<F2, F2>('translate');
|
||||
_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;
|
||||
_ffiBind = RustdeskImpl(dylib);
|
||||
_startListenEvent(_ffiBind); // global event
|
||||
@ -177,10 +146,10 @@ class PlatformFFI {
|
||||
}
|
||||
print(
|
||||
"_appType:$_appType,info1-id:$id,info2-name:$name,dir:$_dir,homeDir:$_homeDir");
|
||||
setByName('info1', id);
|
||||
setByName('info2', name);
|
||||
setByName('home_dir', _homeDir);
|
||||
setByName('init', _dir);
|
||||
await _ffiBind.mainDeviceId(id: id);
|
||||
await _ffiBind.mainDeviceName(name: name);
|
||||
await _ffiBind.mainSetHomeDir(home: _homeDir);
|
||||
await _ffiBind.mainInit(appDir: _dir);
|
||||
} catch (e) {
|
||||
print(e);
|
||||
}
|
||||
|
@ -99,42 +99,29 @@ class ServerModel with ChangeNotifier {
|
||||
// audio
|
||||
if (androidVersion < 30 || !await PermissionManager.check("audio")) {
|
||||
_audioOk = false;
|
||||
parent.target?.setByName(
|
||||
'option',
|
||||
jsonEncode(Map()
|
||||
..["name"] = "enable-audio"
|
||||
..["value"] = "N"));
|
||||
bind.mainSetOption(key: "enable-audio", value: "N");
|
||||
} else {
|
||||
final audioOption = parent.target?.getByName('option', 'enable-audio');
|
||||
_audioOk = audioOption?.isEmpty ?? false;
|
||||
final audioOption = await bind.mainGetOption(key: 'enable-audio');
|
||||
_audioOk = audioOption.isEmpty;
|
||||
}
|
||||
|
||||
// file
|
||||
if (!await PermissionManager.check("file")) {
|
||||
_fileOk = false;
|
||||
parent.target?.setByName(
|
||||
'option',
|
||||
jsonEncode(Map()
|
||||
..["name"] = "enable-file-transfer"
|
||||
..["value"] = "N"));
|
||||
bind.mainSetOption(key: "enable-file-transfer", value: "N");
|
||||
} else {
|
||||
final fileOption =
|
||||
parent.target?.getByName('option', 'enable-file-transfer');
|
||||
_fileOk = fileOption?.isEmpty ?? false;
|
||||
await bind.mainGetOption(key: 'enable-file-transfer');
|
||||
_fileOk = fileOption.isEmpty;
|
||||
}
|
||||
|
||||
// input (mouse control)
|
||||
Map<String, String> res = Map()
|
||||
..["name"] = "enable-keyboard"
|
||||
..["value"] = 'N';
|
||||
parent.target
|
||||
?.setByName('option', jsonEncode(res)); // input false by default
|
||||
// input (mouse control) false by default
|
||||
bind.mainSetOption(key: "enable-keyboard", value: "N");
|
||||
notifyListeners();
|
||||
}();
|
||||
|
||||
Timer.periodic(Duration(seconds: 1), (timer) {
|
||||
var status =
|
||||
int.tryParse(parent.target?.getByName('connect_statue') ?? "") ?? 0;
|
||||
Timer.periodic(Duration(seconds: 1), (timer) async {
|
||||
var status = await bind.mainGetOnlineStatue();
|
||||
if (status > 0) {
|
||||
status = 1;
|
||||
}
|
||||
@ -142,10 +129,8 @@ class ServerModel with ChangeNotifier {
|
||||
_connectStatus = status;
|
||||
notifyListeners();
|
||||
}
|
||||
final res = parent.target
|
||||
?.getByName('check_clients_length', _clients.length.toString()) ??
|
||||
"";
|
||||
if (res.isNotEmpty) {
|
||||
final res = await bind.mainCheckClientsLength(length: _clients.length);
|
||||
if (res != null) {
|
||||
debugPrint("clients not match!");
|
||||
updateClientState(res);
|
||||
}
|
||||
@ -156,7 +141,7 @@ class ServerModel with ChangeNotifier {
|
||||
|
||||
updatePasswordModel() async {
|
||||
var update = false;
|
||||
final temporaryPassword = gFFI.getByName("temporary_password");
|
||||
final temporaryPassword = await bind.mainGetTemporaryPassword();
|
||||
final verificationMethod =
|
||||
await bind.mainGetOption(key: "verification-method");
|
||||
final temporaryPasswordLength =
|
||||
@ -194,10 +179,7 @@ class ServerModel with ChangeNotifier {
|
||||
}
|
||||
|
||||
_audioOk = !_audioOk;
|
||||
Map<String, String> res = Map()
|
||||
..["name"] = "enable-audio"
|
||||
..["value"] = _audioOk ? '' : 'N';
|
||||
parent.target?.setByName('option', jsonEncode(res));
|
||||
bind.mainSetOption(key: "enable-audio", value: _audioOk ? '' : 'N');
|
||||
notifyListeners();
|
||||
}
|
||||
|
||||
@ -211,10 +193,7 @@ class ServerModel with ChangeNotifier {
|
||||
}
|
||||
|
||||
_fileOk = !_fileOk;
|
||||
Map<String, String> res = Map()
|
||||
..["name"] = "enable-file-transfer"
|
||||
..["value"] = _fileOk ? '' : 'N';
|
||||
parent.target?.setByName('option', jsonEncode(res));
|
||||
bind.mainSetOption(key: "enable-file-transfer", value: _fileOk ? '' : 'N');
|
||||
notifyListeners();
|
||||
}
|
||||
|
||||
@ -284,7 +263,7 @@ class ServerModel with ChangeNotifier {
|
||||
// TODO
|
||||
parent.target?.ffiModel.updateEventListener("");
|
||||
await parent.target?.invokeMethod("init_service");
|
||||
parent.target?.setByName("start_service");
|
||||
await bind.mainStartService();
|
||||
_fetchID();
|
||||
updateClientState();
|
||||
if (!Platform.isLinux) {
|
||||
@ -299,7 +278,7 @@ class ServerModel with ChangeNotifier {
|
||||
// TODO
|
||||
parent.target?.serverModel.closeAll();
|
||||
await parent.target?.invokeMethod("stop_service");
|
||||
parent.target?.setByName("stop_service");
|
||||
await bind.mainStopService();
|
||||
notifyListeners();
|
||||
if (!Platform.isLinux) {
|
||||
// current linux is not supported
|
||||
@ -312,9 +291,9 @@ class ServerModel with ChangeNotifier {
|
||||
}
|
||||
|
||||
Future<bool> setPermanentPassword(String newPW) async {
|
||||
parent.target?.setByName("permanent_password", newPW);
|
||||
await bind.mainSetPermanentPassword(password: newPW);
|
||||
await Future.delayed(Duration(milliseconds: 500));
|
||||
final pw = parent.target?.getByName("permanent_password");
|
||||
final pw = await bind.mainGetPermanentPassword();
|
||||
if (newPW == pw) {
|
||||
return true;
|
||||
} else {
|
||||
@ -355,10 +334,7 @@ class ServerModel with ChangeNotifier {
|
||||
break;
|
||||
case "input":
|
||||
if (_inputOk != value) {
|
||||
Map<String, String> res = Map()
|
||||
..["name"] = "enable-keyboard"
|
||||
..["value"] = value ? '' : 'N';
|
||||
parent.target?.setByName('option', jsonEncode(res));
|
||||
bind.mainSetOption(key: "enable-keyboard", value: value ? '' : 'N');
|
||||
}
|
||||
_inputOk = value;
|
||||
break;
|
||||
@ -368,8 +344,8 @@ class ServerModel with ChangeNotifier {
|
||||
notifyListeners();
|
||||
}
|
||||
|
||||
updateClientState([String? json]) {
|
||||
var res = json ?? parent.target?.getByName("clients_state") ?? "";
|
||||
updateClientState([String? json]) async {
|
||||
var res = await bind.mainGetClientsState();
|
||||
try {
|
||||
final List clientsJson = jsonDecode(res);
|
||||
for (var clientJson in clientsJson) {
|
||||
@ -451,12 +427,9 @@ class ServerModel with ChangeNotifier {
|
||||
});
|
||||
}
|
||||
|
||||
void sendLoginResponse(Client client, bool res) {
|
||||
final Map<String, dynamic> response = Map();
|
||||
response["id"] = client.id;
|
||||
response["res"] = res;
|
||||
void sendLoginResponse(Client client, bool res) async {
|
||||
if (res) {
|
||||
parent.target?.setByName("login_res", jsonEncode(response));
|
||||
bind.serverLoginRes(connId: client.id, res: res);
|
||||
if (!client.isFileTransfer) {
|
||||
parent.target?.invokeMethod("start_capture");
|
||||
}
|
||||
@ -464,7 +437,7 @@ class ServerModel with ChangeNotifier {
|
||||
_clients[client.id]?.authorized = true;
|
||||
notifyListeners();
|
||||
} else {
|
||||
parent.target?.setByName("login_res", jsonEncode(response));
|
||||
bind.serverLoginRes(connId: client.id, res: res);
|
||||
parent.target?.invokeMethod("cancel_notification", client.id);
|
||||
_clients.remove(client.id);
|
||||
}
|
||||
@ -496,7 +469,7 @@ class ServerModel with ChangeNotifier {
|
||||
|
||||
closeAll() {
|
||||
_clients.forEach((id, client) {
|
||||
parent.target?.setByName("close_conn", id.toString());
|
||||
bind.serverCloseConnection(connId: id);
|
||||
});
|
||||
_clients.clear();
|
||||
}
|
||||
|
@ -1280,7 +1280,7 @@ impl LoginConfigHandler {
|
||||
/// Create a [`Message`] for login.
|
||||
fn create_login_msg(&self, password: Vec<u8>) -> Message {
|
||||
#[cfg(any(target_os = "android", target_os = "ios"))]
|
||||
let my_id = Config::get_id_or(crate::common::FLUTTER_INFO1.lock().unwrap().clone());
|
||||
let my_id = Config::get_id_or(crate::common::DEVICE_ID.lock().unwrap().clone());
|
||||
#[cfg(not(any(target_os = "android", target_os = "ios")))]
|
||||
let my_id = Config::get_id();
|
||||
let mut lr = LoginRequest {
|
||||
|
@ -28,8 +28,8 @@ lazy_static::lazy_static! {
|
||||
}
|
||||
|
||||
lazy_static::lazy_static! {
|
||||
pub static ref FLUTTER_INFO1: Arc<Mutex<String>> = Default::default();
|
||||
pub static ref FLUTTER_INFO2: Arc<Mutex<String>> = Default::default();
|
||||
pub static ref DEVICE_ID: Arc<Mutex<String>> = Default::default();
|
||||
pub static ref DEVICE_NAME: Arc<Mutex<String>> = Default::default();
|
||||
}
|
||||
|
||||
#[inline]
|
||||
@ -441,7 +441,7 @@ pub fn username() -> String {
|
||||
#[cfg(not(any(target_os = "android", target_os = "ios")))]
|
||||
return whoami::username().trim_end_matches('\0').to_owned();
|
||||
#[cfg(any(target_os = "android", target_os = "ios"))]
|
||||
return FLUTTER_INFO2.lock().unwrap().clone();
|
||||
return DEVICE_NAME.lock().unwrap().clone();
|
||||
}
|
||||
|
||||
#[inline]
|
||||
|
@ -26,7 +26,8 @@ use crate::ui_interface::{
|
||||
get_connect_status, get_fav, get_id, get_lan_peers, get_license, get_local_option, get_option,
|
||||
get_options, get_peer, get_peer_option, get_socks, get_sound_inputs, get_uuid, get_version,
|
||||
has_rendezvous_service, post_request, set_local_option, set_option, set_options,
|
||||
set_peer_option, set_socks, store_fav, test_if_valid_server, using_public_server,
|
||||
set_peer_option, set_permanent_password, set_socks, store_fav, test_if_valid_server,
|
||||
update_temporary_password, using_public_server,
|
||||
};
|
||||
|
||||
fn initialize(app_dir: &str) {
|
||||
@ -235,38 +236,6 @@ pub fn session_send_chat(id: String, text: String) {
|
||||
}
|
||||
}
|
||||
|
||||
// if let Some(_type) = m.get("type") {
|
||||
// mask = match _type.as_str() {
|
||||
// "down" => 1,
|
||||
// "up" => 2,
|
||||
// "wheel" => 3,
|
||||
// _ => 0,
|
||||
// };
|
||||
// }
|
||||
// if let Some(buttons) = m.get("buttons") {
|
||||
// mask |= match buttons.as_str() {
|
||||
// "left" => 1,
|
||||
// "right" => 2,
|
||||
// "wheel" => 4,
|
||||
// _ => 0,
|
||||
// } << 3;
|
||||
// }
|
||||
// TODO
|
||||
pub fn session_send_mouse(
|
||||
id: String,
|
||||
mask: i32,
|
||||
x: i32,
|
||||
y: i32,
|
||||
alt: bool,
|
||||
ctrl: bool,
|
||||
shift: bool,
|
||||
command: bool,
|
||||
) {
|
||||
if let Some(session) = SESSIONS.read().unwrap().get(&id) {
|
||||
session.send_mouse(mask, x, y, alt, ctrl, shift, command);
|
||||
}
|
||||
}
|
||||
|
||||
pub fn session_peer_option(id: String, name: String, value: String) {
|
||||
if let Some(session) = SESSIONS.read().unwrap().get(&id) {
|
||||
session.set_option(name, value);
|
||||
@ -426,11 +395,7 @@ pub fn main_set_option(key: String, value: String) {
|
||||
set_option(key, value);
|
||||
#[cfg(target_os = "android")]
|
||||
crate::rendezvous_mediator::RendezvousMediator::restart();
|
||||
#[cfg(any(
|
||||
target_os = "android",
|
||||
target_os = "ios",
|
||||
feature = "cli"
|
||||
))]
|
||||
#[cfg(any(target_os = "android", target_os = "ios", feature = "cli"))]
|
||||
crate::common::test_rendezvous_server();
|
||||
} else {
|
||||
set_option(key, value);
|
||||
@ -640,6 +605,143 @@ pub fn main_get_last_remote_id() -> String {
|
||||
LocalConfig::get_remote_id()
|
||||
}
|
||||
|
||||
pub fn main_get_software_update_url() -> String {
|
||||
crate::common::SOFTWARE_UPDATE_URL.lock().unwrap().clone()
|
||||
}
|
||||
|
||||
pub fn main_get_home_dir() -> String {
|
||||
fs::get_home_as_string()
|
||||
}
|
||||
|
||||
pub fn main_get_langs() -> String {
|
||||
crate::lang::LANGS.to_string()
|
||||
}
|
||||
|
||||
pub fn main_get_temporary_password() -> String {
|
||||
ui_interface::temporary_password()
|
||||
}
|
||||
|
||||
pub fn main_get_permanent_password() -> String {
|
||||
ui_interface::permanent_password()
|
||||
}
|
||||
|
||||
pub fn main_get_online_statue() -> i64 {
|
||||
ONLINE.lock().unwrap().values().max().unwrap_or(&0).clone()
|
||||
}
|
||||
|
||||
pub fn main_get_clients_state() -> String {
|
||||
get_clients_state()
|
||||
}
|
||||
|
||||
pub fn main_check_clients_length(length: usize) -> Option<String> {
|
||||
if length != get_clients_length() {
|
||||
Some(get_clients_state())
|
||||
} else {
|
||||
None
|
||||
}
|
||||
}
|
||||
|
||||
pub fn main_init(app_dir: String) {
|
||||
initialize(&app_dir);
|
||||
}
|
||||
|
||||
pub fn main_device_id(id: String) {
|
||||
*crate::common::DEVICE_ID.lock().unwrap() = id;
|
||||
}
|
||||
|
||||
pub fn main_device_name(name: String) {
|
||||
*crate::common::DEVICE_NAME.lock().unwrap() = name;
|
||||
}
|
||||
|
||||
pub fn main_remove_peer(id: String) {
|
||||
PeerConfig::remove(&id);
|
||||
}
|
||||
|
||||
// TODO
|
||||
pub fn session_send_mouse(id: String, msg: String) {
|
||||
if let Ok(m) = serde_json::from_str::<HashMap<String, String>>(&msg) {
|
||||
let alt = m.get("alt").is_some();
|
||||
let ctrl = m.get("ctrl").is_some();
|
||||
let shift = m.get("shift").is_some();
|
||||
let command = m.get("command").is_some();
|
||||
let x = m
|
||||
.get("x")
|
||||
.map(|x| x.parse::<i32>().unwrap_or(0))
|
||||
.unwrap_or(0);
|
||||
let y = m
|
||||
.get("y")
|
||||
.map(|x| x.parse::<i32>().unwrap_or(0))
|
||||
.unwrap_or(0);
|
||||
let mut mask = 0;
|
||||
if let Some(_type) = m.get("type") {
|
||||
mask = match _type.as_str() {
|
||||
"down" => 1,
|
||||
"up" => 2,
|
||||
"wheel" => 3,
|
||||
_ => 0,
|
||||
};
|
||||
}
|
||||
if let Some(buttons) = m.get("buttons") {
|
||||
mask |= match buttons.as_str() {
|
||||
"left" => 1,
|
||||
"right" => 2,
|
||||
"wheel" => 4,
|
||||
_ => 0,
|
||||
} << 3;
|
||||
}
|
||||
if let Some(session) = SESSIONS.read().unwrap().get(&id) {
|
||||
session.send_mouse(mask, x, y, alt, ctrl, shift, command);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
pub fn session_restart_remote_device(id: String) {
|
||||
// TODO
|
||||
// Session::restart_remote_device();
|
||||
}
|
||||
|
||||
pub fn main_set_home_dir(home: String) {
|
||||
*config::APP_HOME_DIR.write().unwrap() = home;
|
||||
}
|
||||
|
||||
pub fn main_stop_service() {
|
||||
#[cfg(target_os = "android")]
|
||||
{
|
||||
Config::set_option("stop-service".into(), "Y".into());
|
||||
crate::rendezvous_mediator::RendezvousMediator::restart();
|
||||
}
|
||||
}
|
||||
|
||||
pub fn main_start_service() {
|
||||
#[cfg(target_os = "android")]
|
||||
{
|
||||
Config::set_option("stop-service".into(), "".into());
|
||||
crate::rendezvous_mediator::RendezvousMediator::restart();
|
||||
}
|
||||
#[cfg(not(target_os = "android"))]
|
||||
std::thread::spawn(move || start_server(true));
|
||||
}
|
||||
|
||||
pub fn main_update_temporary_password() {
|
||||
update_temporary_password();
|
||||
}
|
||||
|
||||
pub fn main_set_permanent_password(password: String) {
|
||||
set_permanent_password(password);
|
||||
}
|
||||
|
||||
pub fn server_send_chat(conn_id: i32, msg: String) {
|
||||
connection_manager::send_chat(conn_id, msg);
|
||||
}
|
||||
|
||||
pub fn server_login_res(conn_id: i32, res: bool) {
|
||||
connection_manager::on_login_res(conn_id, res);
|
||||
}
|
||||
|
||||
pub fn server_close_connection(conn_id: i32) {
|
||||
connection_manager::close_conn(conn_id);
|
||||
}
|
||||
|
||||
#[no_mangle]
|
||||
unsafe extern "C" fn translate(name: *const c_char, locale: *const c_char) -> *const c_char {
|
||||
let name = CStr::from_ptr(name);
|
||||
@ -652,241 +754,6 @@ unsafe extern "C" fn translate(name: *const c_char, locale: *const c_char) -> *c
|
||||
CString::from_vec_unchecked(res.into_bytes()).into_raw()
|
||||
}
|
||||
|
||||
/// FFI for **get** commands which are idempotent.
|
||||
/// Return result in c string.
|
||||
///
|
||||
/// # Arguments
|
||||
///
|
||||
/// * `name` - name of the command
|
||||
/// * `arg` - argument of the command
|
||||
#[no_mangle]
|
||||
unsafe extern "C" fn get_by_name(name: *const c_char, arg: *const c_char) -> *const c_char {
|
||||
let mut res = "".to_owned();
|
||||
let arg: &CStr = CStr::from_ptr(arg);
|
||||
let name: &CStr = CStr::from_ptr(name);
|
||||
if let Ok(name) = name.to_str() {
|
||||
match name {
|
||||
// "peers" => {
|
||||
// if !config::APP_DIR.read().unwrap().is_empty() {
|
||||
// let peers: Vec<(String, config::PeerInfoSerde)> = PeerConfig::peers()
|
||||
// .drain(..)
|
||||
// .map(|(id, _, p)| (id, p.info))
|
||||
// .collect();
|
||||
// res = serde_json::ser::to_string(&peers).unwrap_or("".to_owned());
|
||||
// }
|
||||
// }
|
||||
// "remote_id" => {
|
||||
// if !config::APP_DIR.read().unwrap().is_empty() {
|
||||
// res = LocalConfig::get_remote_id();
|
||||
// }
|
||||
// }
|
||||
// "test_if_valid_server" => {
|
||||
// if let Ok(arg) = arg.to_str() {
|
||||
// res = hbb_common::socket_client::test_if_valid_server(arg);
|
||||
// }
|
||||
// }
|
||||
// "option" => {
|
||||
// if let Ok(arg) = arg.to_str() {
|
||||
// res = ui_interface::get_option(arg.to_owned());
|
||||
// }
|
||||
// }
|
||||
"software_update_url" => {
|
||||
res = crate::common::SOFTWARE_UPDATE_URL.lock().unwrap().clone()
|
||||
}
|
||||
// File Action
|
||||
"get_home_dir" => {
|
||||
res = fs::get_home_as_string();
|
||||
}
|
||||
// Server Side
|
||||
"langs" => {
|
||||
res = crate::lang::LANGS.to_string();
|
||||
}
|
||||
"temporary_password" => {
|
||||
res = ui_interface::temporary_password();
|
||||
}
|
||||
"permanent_password" => {
|
||||
res = ui_interface::permanent_password();
|
||||
}
|
||||
"connect_statue" => {
|
||||
res = ONLINE
|
||||
.lock()
|
||||
.unwrap()
|
||||
.values()
|
||||
.max()
|
||||
.unwrap_or(&0)
|
||||
.clone()
|
||||
.to_string();
|
||||
}
|
||||
#[cfg(not(any(target_os = "ios")))]
|
||||
"clients_state" => {
|
||||
res = get_clients_state();
|
||||
}
|
||||
#[cfg(not(any(target_os = "ios")))]
|
||||
"check_clients_length" => {
|
||||
if let Ok(value) = arg.to_str() {
|
||||
if value.parse::<usize>().unwrap_or(usize::MAX) != get_clients_length() {
|
||||
res = get_clients_state()
|
||||
}
|
||||
}
|
||||
}
|
||||
_ => {
|
||||
log::error!("Unknown name of get_by_name: {}", name);
|
||||
}
|
||||
}
|
||||
}
|
||||
CString::from_vec_unchecked(res.into_bytes()).into_raw()
|
||||
}
|
||||
|
||||
/// FFI for **set** commands which are not idempotent.
|
||||
///
|
||||
/// # Arguments
|
||||
///
|
||||
/// * `name` - name of the command
|
||||
/// * `arg` - argument of the command
|
||||
#[no_mangle]
|
||||
unsafe extern "C" fn set_by_name(name: *const c_char, value: *const c_char) {
|
||||
let value: &CStr = CStr::from_ptr(value);
|
||||
if let Ok(value) = value.to_str() {
|
||||
let name: &CStr = CStr::from_ptr(name);
|
||||
if let Ok(name) = name.to_str() {
|
||||
match name {
|
||||
"init" => {
|
||||
initialize(value);
|
||||
}
|
||||
"info1" => {
|
||||
*crate::common::FLUTTER_INFO1.lock().unwrap() = value.to_owned();
|
||||
}
|
||||
"info2" => {
|
||||
*crate::common::FLUTTER_INFO2.lock().unwrap() = value.to_owned();
|
||||
}
|
||||
"remove" => {
|
||||
PeerConfig::remove(value);
|
||||
}
|
||||
|
||||
// TODO
|
||||
"send_mouse" => {
|
||||
if let Ok(m) = serde_json::from_str::<HashMap<String, String>>(value) {
|
||||
let id = m.get("id");
|
||||
if id.is_none() {
|
||||
return;
|
||||
}
|
||||
let id = id.unwrap();
|
||||
let alt = m.get("alt").is_some();
|
||||
let ctrl = m.get("ctrl").is_some();
|
||||
let shift = m.get("shift").is_some();
|
||||
let command = m.get("command").is_some();
|
||||
let x = m
|
||||
.get("x")
|
||||
.map(|x| x.parse::<i32>().unwrap_or(0))
|
||||
.unwrap_or(0);
|
||||
let y = m
|
||||
.get("y")
|
||||
.map(|x| x.parse::<i32>().unwrap_or(0))
|
||||
.unwrap_or(0);
|
||||
let mut mask = 0;
|
||||
if let Some(_type) = m.get("type") {
|
||||
mask = match _type.as_str() {
|
||||
"down" => 1,
|
||||
"up" => 2,
|
||||
"wheel" => 3,
|
||||
_ => 0,
|
||||
};
|
||||
}
|
||||
if let Some(buttons) = m.get("buttons") {
|
||||
mask |= match buttons.as_str() {
|
||||
"left" => 1,
|
||||
"right" => 2,
|
||||
"wheel" => 4,
|
||||
_ => 0,
|
||||
} << 3;
|
||||
}
|
||||
if let Some(session) = SESSIONS.read().unwrap().get(id) {
|
||||
session.send_mouse(mask, x, y, alt, ctrl, shift, command);
|
||||
}
|
||||
}
|
||||
}
|
||||
// "option" => {
|
||||
// if let Ok(m) = serde_json::from_str::<HashMap<String, String>>(value) {
|
||||
// if let Some(name) = m.get("name") {
|
||||
// if let Some(value) = m.get("value") {
|
||||
// ui_interface::set_option(name.to_owned(), value.to_owned());
|
||||
// if name == "custom-rendezvous-server" {
|
||||
// #[cfg(target_os = "android")]
|
||||
// crate::rendezvous_mediator::RendezvousMediator::restart();
|
||||
// #[cfg(any(
|
||||
// target_os = "android",
|
||||
// target_os = "ios",
|
||||
// feature = "cli"
|
||||
// ))]
|
||||
// crate::common::test_rendezvous_server();
|
||||
// }
|
||||
// }
|
||||
// }
|
||||
// }
|
||||
// }
|
||||
"restart_remote_device" => {
|
||||
// TODO
|
||||
// Session::restart_remote_device();
|
||||
}
|
||||
#[cfg(target_os = "android")]
|
||||
"chat_server_mode" => {
|
||||
if let Ok(m) = serde_json::from_str::<HashMap<String, Value>>(value) {
|
||||
if let (Some(Value::Number(id)), Some(Value::String(text))) =
|
||||
(m.get("id"), m.get("text"))
|
||||
{
|
||||
let id = id.as_i64().unwrap_or(0);
|
||||
connection_manager::send_chat(id as i32, text.to_owned());
|
||||
}
|
||||
}
|
||||
}
|
||||
"home_dir" => {
|
||||
*config::APP_HOME_DIR.write().unwrap() = value.to_owned();
|
||||
}
|
||||
#[cfg(target_os = "android")]
|
||||
"login_res" => {
|
||||
if let Ok(m) = serde_json::from_str::<HashMap<String, Value>>(value) {
|
||||
if let (Some(Value::Number(id)), Some(Value::Bool(res))) =
|
||||
(m.get("id"), m.get("res"))
|
||||
{
|
||||
let id = id.as_i64().unwrap_or(0);
|
||||
connection_manager::on_login_res(id as i32, *res);
|
||||
}
|
||||
}
|
||||
}
|
||||
#[cfg(target_os = "android")]
|
||||
"stop_service" => {
|
||||
Config::set_option("stop-service".into(), "Y".into());
|
||||
crate::rendezvous_mediator::RendezvousMediator::restart();
|
||||
}
|
||||
"start_service" => {
|
||||
#[cfg(target_os = "android")]
|
||||
{
|
||||
Config::set_option("stop-service".into(), "".into());
|
||||
crate::rendezvous_mediator::RendezvousMediator::restart();
|
||||
}
|
||||
#[cfg(not(target_os = "android"))]
|
||||
std::thread::spawn(move || start_server(true));
|
||||
}
|
||||
#[cfg(target_os = "android")]
|
||||
"close_conn" => {
|
||||
if let Ok(id) = value.parse::<i32>() {
|
||||
connection_manager::close_conn(id);
|
||||
};
|
||||
}
|
||||
"temporary_password" => {
|
||||
ui_interface::update_temporary_password();
|
||||
}
|
||||
"permanent_password" => {
|
||||
ui_interface::set_permanent_password(value.to_owned());
|
||||
}
|
||||
_ => {
|
||||
log::error!("Unknown name of set_by_name: {}", name);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
fn handle_query_onlines(onlines: Vec<String>, offlines: Vec<String>) {
|
||||
if let Some(s) = flutter::GLOBAL_EVENT_STREAM
|
||||
.read()
|
||||
|
@ -5,7 +5,7 @@ use crate::clipboard_file::*;
|
||||
use crate::common::update_clipboard;
|
||||
use crate::video_service;
|
||||
#[cfg(any(target_os = "android", target_os = "ios"))]
|
||||
use crate::{common::FLUTTER_INFO2, flutter::connection_manager::start_channel};
|
||||
use crate::{common::DEVICE_NAME, flutter::connection_manager::start_channel};
|
||||
use crate::{ipc, VERSION};
|
||||
use hbb_common::{
|
||||
config::Config,
|
||||
@ -643,7 +643,7 @@ impl Connection {
|
||||
}
|
||||
#[cfg(target_os = "android")]
|
||||
{
|
||||
pi.hostname = FLUTTER_INFO2.lock().unwrap().clone();
|
||||
pi.hostname = DEVICE_NAME.lock().unwrap().clone();
|
||||
pi.platform = "Android".into();
|
||||
}
|
||||
#[cfg(feature = "hwcodec")]
|
||||
|
Loading…
Reference in New Issue
Block a user