From 9911f4d2f5e2059016c03b26738989f21ccf958d Mon Sep 17 00:00:00 2001 From: csf Date: Thu, 29 Sep 2022 13:07:20 +0800 Subject: [PATCH] android direct ip access --- flutter/lib/common.dart | 15 +-- flutter/lib/common/widgets/dialog.dart | 51 ++++++++++ flutter/lib/mobile/pages/server_page.dart | 10 +- flutter/lib/mobile/pages/settings_page.dart | 103 ++++++++++++++++---- flutter/lib/models/server_model.dart | 4 +- src/common.rs | 1 + src/flutter_ffi.rs | 7 +- 7 files changed, 153 insertions(+), 38 deletions(-) diff --git a/flutter/lib/common.dart b/flutter/lib/common.dart index 97b1a3596..1ec401461 100644 --- a/flutter/lib/common.dart +++ b/flutter/lib/common.dart @@ -133,11 +133,12 @@ class MyTheme { backgroundColor: Color(0xFFFFFFFF), scaffoldBackgroundColor: Color(0xFFEEEEEE), textTheme: const TextTheme( - titleLarge: TextStyle(fontSize: 19, color: Colors.black87), - titleSmall: TextStyle(fontSize: 14, color: Colors.black87), - bodySmall: TextStyle(fontSize: 12, color: Colors.black87, height: 1.25), - bodyMedium: TextStyle(fontSize: 14, color: Colors.black87, height: 1.25), - ), + titleLarge: TextStyle(fontSize: 19, color: Colors.black87), + titleSmall: TextStyle(fontSize: 14, color: Colors.black87), + bodySmall: TextStyle(fontSize: 12, color: Colors.black87, height: 1.25), + bodyMedium: + TextStyle(fontSize: 14, color: Colors.black87, height: 1.25), + labelLarge: TextStyle(fontSize: 16.0, color: MyTheme.accent80)), hintColor: Color(0xFFAAAAAA), primarySwatch: Colors.blue, visualDensity: VisualDensity.adaptivePlatformDensity, @@ -166,7 +167,9 @@ class MyTheme { titleLarge: TextStyle(fontSize: 19), titleSmall: TextStyle(fontSize: 14), bodySmall: TextStyle(fontSize: 12, height: 1.25), - bodyMedium: TextStyle(fontSize: 14, height: 1.25)), + bodyMedium: TextStyle(fontSize: 14, height: 1.25), + labelLarge: TextStyle( + fontSize: 16.0, fontWeight: FontWeight.bold, color: accent80)), cardColor: Color(0xFF252525), primarySwatch: Colors.blue, visualDensity: VisualDensity.adaptivePlatformDensity, diff --git a/flutter/lib/common/widgets/dialog.dart b/flutter/lib/common/widgets/dialog.dart index cfb57a4cb..35a303c0b 100644 --- a/flutter/lib/common/widgets/dialog.dart +++ b/flutter/lib/common/widgets/dialog.dart @@ -155,3 +155,54 @@ void changeWhiteList({Function()? callback}) async { ); }); } + +Future changeDirectAccessPort( + String currentIP, String currentPort) async { + final controller = TextEditingController(text: currentPort); + await gFFI.dialogManager.show((setState, close) { + return CustomAlertDialog( + title: Text(translate("Change Local Port")), + content: Column( + crossAxisAlignment: CrossAxisAlignment.start, + children: [ + const SizedBox(height: 8.0), + Row( + children: [ + Expanded( + child: TextField( + maxLines: null, + keyboardType: TextInputType.number, + decoration: InputDecoration( + hintText: '21118', + isCollapsed: true, + prefix: Text('$currentIP : '), + suffix: IconButton( + padding: EdgeInsets.zero, + icon: const Icon(Icons.clear, size: 16), + onPressed: () => controller.clear())), + inputFormatters: [ + FilteringTextInputFormatter.allow(RegExp( + r'^([0-9]|[1-9]\d|[1-9]\d{2}|[1-9]\d{3}|[1-5]\d{4}|6[0-4]\d{3}|65[0-4]\d{2}|655[0-2]\d|6553[0-5])$')), + ], + controller: controller, + focusNode: FocusNode()..requestFocus()), + ), + ], + ), + ], + ), + actions: [ + TextButton(onPressed: close, child: Text(translate("Cancel"))), + TextButton( + onPressed: () async { + await bind.mainSetOption( + key: 'direct-access-port', value: controller.text); + close(); + }, + child: Text(translate("OK"))), + ], + onCancel: close, + ); + }); + return controller.text; +} diff --git a/flutter/lib/mobile/pages/server_page.dart b/flutter/lib/mobile/pages/server_page.dart index 52b378681..cc80e3e0c 100644 --- a/flutter/lib/mobile/pages/server_page.dart +++ b/flutter/lib/mobile/pages/server_page.dart @@ -333,14 +333,8 @@ class PermissionRow extends StatelessWidget { child: FittedBox( fit: BoxFit.scaleDown, alignment: Alignment.centerLeft, - child: Text(name, - style: TextStyle( - fontSize: 16.0, - fontWeight: - Theme.of(context).brightness == Brightness.dark - ? FontWeight.bold - : null, - color: MyTheme.accent80)))), + child: + Text(name, style: Theme.of(context).textTheme.labelLarge))), Expanded( flex: 2, child: FittedBox( diff --git a/flutter/lib/mobile/pages/settings_page.dart b/flutter/lib/mobile/pages/settings_page.dart index 2c16a7991..4f1640a03 100644 --- a/flutter/lib/mobile/pages/settings_page.dart +++ b/flutter/lib/mobile/pages/settings_page.dart @@ -36,6 +36,9 @@ var _ignoreBatteryOpt = false; var _enableAbr = false; var _denyLANDiscovery = false; var _onlyWhiteList = false; +var _enableDirectIPAccess = false; +var _localIP = ""; +var _directAccessPort = ""; class _SettingsState extends State with WidgetsBindingObserver { String? username; @@ -77,6 +80,26 @@ class _SettingsState extends State with WidgetsBindingObserver { _onlyWhiteList = onlyWhiteList; } + final enableDirectIPAccess = option2bool( + 'direct-server', await bind.mainGetOption(key: 'direct-server')); + if (enableDirectIPAccess != _enableDirectIPAccess) { + update = true; + _enableDirectIPAccess = enableDirectIPAccess; + } + + final localIP = await bind.mainGetOption(key: 'local-ip-addr'); + if (localIP != _localIP) { + update = true; + _localIP = localIP; + } + + final directAccessPort = + await bind.mainGetOption(key: 'direct-access-port'); + if (directAccessPort != _directAccessPort) { + update = true; + _directAccessPort = directAccessPort; + } + if (update) { setState(() {}); } @@ -113,20 +136,8 @@ class _SettingsState extends State with WidgetsBindingObserver { @override Widget build(BuildContext context) { Provider.of(context); - final enhancementsTiles = [ - SettingsTile.switchTile( - title: Text('${translate('Adaptive Bitrate')} (beta)'), - initialValue: _enableAbr, - onToggle: (v) async { - await bind.mainSetOption(key: "enable-abr", value: v ? "" : "N"); - final newValue = await bind.mainGetOption(key: "enable-abr") != "N"; - setState(() { - _enableAbr = newValue; - }); - }, - ) - ]; - final shareScreenTiles = [ + final List enhancementsTiles = []; + final List shareScreenTiles = [ SettingsTile.switchTile( title: Text(translate('Deny LAN Discovery')), initialValue: _denyLANDiscovery, @@ -143,7 +154,7 @@ class _SettingsState extends State with WidgetsBindingObserver { ), SettingsTile.switchTile( title: Row(children: [ - Text(translate('Use IP Whitelisting')), + Expanded(child: Text(translate('Use IP Whitelisting'))), Offstage( offstage: !_onlyWhiteList, child: const Icon(Icons.warning_amber_rounded, @@ -164,6 +175,58 @@ class _SettingsState extends State with WidgetsBindingObserver { changeWhiteList(callback: update); }, + ), + SettingsTile.switchTile( + title: Text('${translate('Adaptive Bitrate')} (beta)'), + initialValue: _enableAbr, + onToggle: (v) async { + await bind.mainSetOption(key: "enable-abr", value: v ? "" : "N"); + final newValue = await bind.mainGetOption(key: "enable-abr") != "N"; + setState(() { + _enableAbr = newValue; + }); + }, + ), + SettingsTile.switchTile( + title: Row( + mainAxisAlignment: MainAxisAlignment.spaceBetween, + crossAxisAlignment: CrossAxisAlignment.center, + children: [ + Expanded( + child: Column( + crossAxisAlignment: CrossAxisAlignment.start, + children: [ + Text(translate("Direct IP Access")), + Offstage( + offstage: !_enableDirectIPAccess, + child: Text( + '${translate("Local Address")}: $_localIP${_directAccessPort.isEmpty ? "" : ":$_directAccessPort"}', + style: Theme.of(context).textTheme.bodySmall, + )), + ])), + Offstage( + offstage: !_enableDirectIPAccess, + child: IconButton( + padding: EdgeInsets.zero, + icon: Icon( + Icons.edit, + size: 20, + ), + onPressed: () async { + final port = await changeDirectAccessPort( + _localIP, _directAccessPort); + setState(() { + _directAccessPort = port; + }); + })) + ]), + initialValue: _enableDirectIPAccess, + onToggle: (_) async { + _enableDirectIPAccess = !_enableDirectIPAccess; + String value = bool2option('direct-server', _enableDirectIPAccess); + await bind.mainSetOption(key: 'direct-server', value: value); + setState(() {}); + }, ) ]; if (_hasIgnoreBattery) { @@ -171,9 +234,13 @@ class _SettingsState extends State with WidgetsBindingObserver { 0, SettingsTile.switchTile( initialValue: _ignoreBatteryOpt, - title: Text(translate('Keep RustDesk background service')), - description: - Text('* ${translate('Ignore Battery Optimizations')}'), + title: Column( + crossAxisAlignment: CrossAxisAlignment.start, + children: [ + Text(translate('Keep RustDesk background service')), + Text('* ${translate('Ignore Battery Optimizations')}', + style: Theme.of(context).textTheme.bodySmall), + ]), onToggle: (v) async { if (v) { PermissionManager.request("ignore_battery_optimizations"); diff --git a/flutter/lib/models/server_model.dart b/flutter/lib/models/server_model.dart index 0e70e40ea..625a3e681 100644 --- a/flutter/lib/models/server_model.dart +++ b/flutter/lib/models/server_model.dart @@ -13,7 +13,7 @@ import '../desktop/widgets/tabbar_widget.dart'; import '../mobile/pages/server_page.dart'; import 'model.dart'; -const KLoginDialogTag = "LOGIN"; +const kLoginDialogTag = "LOGIN"; const kUseTemporaryPassword = "use-temporary-password"; const kUsePermanentPassword = "use-permanent-password"; @@ -578,7 +578,7 @@ class Client { } String getLoginDialogTag(int id) { - return KLoginDialogTag + id.toString(); + return kLoginDialogTag + id.toString(); } showInputWarnAlert(FFI ffi) { diff --git a/src/common.rs b/src/common.rs index 37057b809..dd792362a 100644 --- a/src/common.rs +++ b/src/common.rs @@ -317,6 +317,7 @@ async fn test_nat_type_() -> ResultType { break; } } + Config::set_option("local-ip-addr".to_owned(), addr.ip().to_string()); let ok = port1 > 0 && port2 > 0; if ok { let t = if port1 == port2 { diff --git a/src/flutter_ffi.rs b/src/flutter_ffi.rs index d4c198eea..c1be51498 100644 --- a/src/flutter_ffi.rs +++ b/src/flutter_ffi.rs @@ -32,16 +32,15 @@ fn initialize(app_dir: &str) { ); #[cfg(feature = "mediacodec")] scrap::mediacodec::check_mediacodec(); + crate::common::test_rendezvous_server(); + crate::common::test_nat_type(); + crate::common::check_software_update(); } #[cfg(target_os = "ios")] { use hbb_common::env_logger::*; init_from_env(Env::default().filter_or(DEFAULT_FILTER_ENV, "debug")); } - #[cfg(target_os = "android")] - { - crate::common::check_software_update(); - } } /// FFI for rustdesk core's main entry.