diff --git a/flutter/android/app/src/main/kotlin/com/carriez/flutter_hbb/MainActivity.kt b/flutter/android/app/src/main/kotlin/com/carriez/flutter_hbb/MainActivity.kt index 3cc105bfa..fd340f7ed 100644 --- a/flutter/android/app/src/main/kotlin/com/carriez/flutter_hbb/MainActivity.kt +++ b/flutter/android/app/src/main/kotlin/com/carriez/flutter_hbb/MainActivity.kt @@ -192,7 +192,6 @@ class MainActivity : FlutterActivity() { override fun onResume() { super.onResume() val inputPer = InputService.isOpen - Log.d(logTag, "onResume inputPer:$inputPer") activity.runOnUiThread { flutterMethodChannel.invokeMethod( "on_state_changed", diff --git a/flutter/android/app/src/main/kotlin/com/carriez/flutter_hbb/common.kt b/flutter/android/app/src/main/kotlin/com/carriez/flutter_hbb/common.kt index 3cb3ae581..4bf244a06 100644 --- a/flutter/android/app/src/main/kotlin/com/carriez/flutter_hbb/common.kt +++ b/flutter/android/app/src/main/kotlin/com/carriez/flutter_hbb/common.kt @@ -57,6 +57,18 @@ fun requestPermission(context: Context, type: String) { } return } + "application_details_settings" -> { + try { + context.startActivity(Intent().apply { + addFlags(Intent.FLAG_ACTIVITY_NEW_TASK) + action = "android.settings.APPLICATION_DETAILS_SETTINGS" + data = Uri.parse("package:" + context.packageName) + }) + } catch (e:Exception) { + e.printStackTrace() + } + return + } "audio" -> { Permission.RECORD_AUDIO } diff --git a/flutter/lib/common.dart b/flutter/lib/common.dart index 1b36c548b..a7c5dfea0 100644 --- a/flutter/lib/common.dart +++ b/flutter/lib/common.dart @@ -260,7 +260,12 @@ class PermissionManager { static Timer? _timer; static var _current = ""; - static final permissions = ["audio", "file", "ignore_battery_optimizations"]; + static final permissions = [ + "audio", + "file", + "ignore_battery_optimizations", + "application_details_settings" + ]; static bool isWaitingFile() { if (_completer != null) { diff --git a/flutter/lib/pages/settings_page.dart b/flutter/lib/pages/settings_page.dart index 7506d849f..30eb88b7b 100644 --- a/flutter/lib/pages/settings_page.dart +++ b/flutter/lib/pages/settings_page.dart @@ -26,23 +26,42 @@ class SettingsPage extends StatefulWidget implements PageShape { _SettingsState createState() => _SettingsState(); } -class _SettingsState extends State { +class _SettingsState extends State with WidgetsBindingObserver { static const url = 'https://rustdesk.com/'; - var _showIgnoreBattery = false; + final _hasIgnoreBattery = androidVersion >= 26; + var _ignoreBatteryOpt = false; @override void initState() { super.initState(); - if (androidVersion >= 26) { - () async { - final res = - await PermissionManager.check("ignore_battery_optimizations"); - if (_showIgnoreBattery != !res) { - setState(() { - _showIgnoreBattery = !res; - }); - } - }(); + WidgetsBinding.instance.addObserver(this); + if (_hasIgnoreBattery) { + updateIgnoreBatteryStatus(); + } + } + + @override + void dispose() { + WidgetsBinding.instance.removeObserver(this); + super.dispose(); + } + + @override + void didChangeAppLifecycleState(AppLifecycleState state) { + if (state == AppLifecycleState.resumed) { + updateIgnoreBatteryStatus(); + } + } + + Future updateIgnoreBatteryStatus() async { + final res = await PermissionManager.check("ignore_battery_optimizations"); + if (_ignoreBatteryOpt != res) { + setState(() { + _ignoreBatteryOpt = res; + }); + return true; + } else { + return false; } } @@ -53,7 +72,6 @@ class _SettingsState extends State { final enableAbr = FFI.getByName("option", "enable-abr") != 'N'; final enhancementsTiles = [ SettingsTile.switchTile( - leading: Icon(Icons.more_horiz), title: Text(translate('Adaptive Bitrate') + '(beta)'), initialValue: enableAbr, onToggle: (v) { @@ -68,32 +86,37 @@ class _SettingsState extends State { }, ) ]; - if (_showIgnoreBattery) { + if (_hasIgnoreBattery) { enhancementsTiles.insert( 0, - SettingsTile.navigation( + SettingsTile.switchTile( + initialValue: _ignoreBatteryOpt, title: Text(translate('Keep RustDesk background service')), description: Text('* ${translate('Ignore Battery Optimizations')}'), - leading: Icon(Icons.battery_saver), - onPressed: (context) { - PermissionManager.request("ignore_battery_optimizations"); - var count = 0; - Timer.periodic(Duration(seconds: 1), (timer) async { - if (count > 5) { - count = 0; - timer.cancel(); + onToggle: (v) async { + if (v) { + PermissionManager.request("ignore_battery_optimizations"); + } else { + final res = await DialogManager.show( + (setState, close) => CustomAlertDialog( + title: Text(translate("Open System Setting")), + content: Text(translate( + "android_open_battery_optimizations_tip")), + actions: [ + TextButton( + onPressed: () => close(), + child: Text(translate("Cancel"))), + ElevatedButton( + onPressed: () => close(true), + child: + Text(translate("Open System Setting"))), + ], + )); + if (res == true) { + PermissionManager.request("application_details_settings"); } - if (await PermissionManager.check( - "ignore_battery_optimizations")) { - count = 0; - timer.cancel(); - setState(() { - _showIgnoreBattery = false; - }); - } - count++; - }); + } })); } diff --git a/src/lang/cn.rs b/src/lang/cn.rs index ba85d7f39..58a3a6cd7 100644 --- a/src/lang/cn.rs +++ b/src/lang/cn.rs @@ -286,5 +286,6 @@ pub static ref T: std::collections::HashMap<&'static str, &'static str> = ("Language", "语言"), ("Keep RustDesk background service", "保持RustDesk后台服务"), ("Ignore Battery Optimizations", "忽略电池优化"), + ("android_open_battery_optimizations_tip", "如需关闭此功能,请在接下来的RustDesk应用设置页面中,找到并进入 [电源] 页面,取消勾选 [不受限制]"), ].iter().cloned().collect(); } diff --git a/src/lang/cs.rs b/src/lang/cs.rs index e12bc6075..c5c432d46 100644 --- a/src/lang/cs.rs +++ b/src/lang/cs.rs @@ -286,5 +286,6 @@ pub static ref T: std::collections::HashMap<&'static str, &'static str> = ("Language", ""), ("Keep RustDesk background service", ""), ("Ignore Battery Optimizations", ""), + ("android_open_battery_optimizations_tip", ""), ].iter().cloned().collect(); } diff --git a/src/lang/da.rs b/src/lang/da.rs index f8c676376..d13cd8550 100644 --- a/src/lang/da.rs +++ b/src/lang/da.rs @@ -286,5 +286,6 @@ pub static ref T: std::collections::HashMap<&'static str, &'static str> = ("Language", ""), ("Keep RustDesk background service", ""), ("Ignore Battery Optimizations", ""), + ("android_open_battery_optimizations_tip", ""), ].iter().cloned().collect(); } diff --git a/src/lang/de.rs b/src/lang/de.rs index 8685e764d..b7f471992 100644 --- a/src/lang/de.rs +++ b/src/lang/de.rs @@ -286,5 +286,6 @@ pub static ref T: std::collections::HashMap<&'static str, &'static str> = ("Language", "Sprache"), ("Keep RustDesk background service", ""), ("Ignore Battery Optimizations", ""), + ("android_open_battery_optimizations_tip", ""), ].iter().cloned().collect(); } diff --git a/src/lang/en.rs b/src/lang/en.rs index a4d11d415..1818a619a 100644 --- a/src/lang/en.rs +++ b/src/lang/en.rs @@ -27,5 +27,6 @@ pub static ref T: std::collections::HashMap<&'static str, &'static str> = ("doc_mac_permission", "https://rustdesk.com/docs/en/manual/mac/#enable-permissions"), ("doc_fix_wayland", "https://rustdesk.com/docs/en/manual/linux/#x11-required"), ("server_not_support", "Not yet supported by the server"), + ("android_open_battery_optimizations_tip", "If you want to disable this feature, please go to the next RustDesk application settings page, find and enter [Battery] ,Uncheck [Unrestricted]"), ].iter().cloned().collect(); } diff --git a/src/lang/eo.rs b/src/lang/eo.rs index 5952f51a1..4719a3be3 100644 --- a/src/lang/eo.rs +++ b/src/lang/eo.rs @@ -286,5 +286,6 @@ pub static ref T: std::collections::HashMap<&'static str, &'static str> = ("Language", ""), ("Keep RustDesk background service", ""), ("Ignore Battery Optimizations", ""), + ("android_open_battery_optimizations_tip", ""), ].iter().cloned().collect(); } diff --git a/src/lang/es.rs b/src/lang/es.rs index 9e12ed430..adf214b97 100644 --- a/src/lang/es.rs +++ b/src/lang/es.rs @@ -286,5 +286,6 @@ pub static ref T: std::collections::HashMap<&'static str, &'static str> = ("Language", ""), ("Keep RustDesk background service", ""), ("Ignore Battery Optimizations", ""), + ("android_open_battery_optimizations_tip", ""), ].iter().cloned().collect(); } diff --git a/src/lang/fr.rs b/src/lang/fr.rs index 5e223b262..e92069993 100644 --- a/src/lang/fr.rs +++ b/src/lang/fr.rs @@ -286,5 +286,6 @@ pub static ref T: std::collections::HashMap<&'static str, &'static str> = ("Language", "Langue"), ("Keep RustDesk background service", ""), ("Ignore Battery Optimizations", ""), + ("android_open_battery_optimizations_tip", ""), ].iter().cloned().collect(); } diff --git a/src/lang/hu.rs b/src/lang/hu.rs index ab890766e..b0d1bfda0 100644 --- a/src/lang/hu.rs +++ b/src/lang/hu.rs @@ -286,5 +286,6 @@ pub static ref T: std::collections::HashMap<&'static str, &'static str> = ("Language", "Nyelv"), ("Keep RustDesk background service", ""), ("Ignore Battery Optimizations", ""), + ("android_open_battery_optimizations_tip", ""), ].iter().cloned().collect(); } diff --git a/src/lang/id.rs b/src/lang/id.rs index e926ee4cf..4cdaf8b95 100644 --- a/src/lang/id.rs +++ b/src/lang/id.rs @@ -286,5 +286,6 @@ pub static ref T: std::collections::HashMap<&'static str, &'static str> = ("Language", ""), ("Keep RustDesk background service", ""), ("Ignore Battery Optimizations", ""), + ("android_open_battery_optimizations_tip", ""), ].iter().cloned().collect(); } diff --git a/src/lang/it.rs b/src/lang/it.rs index 016363d4e..3a0c2dc2a 100644 --- a/src/lang/it.rs +++ b/src/lang/it.rs @@ -286,5 +286,6 @@ pub static ref T: std::collections::HashMap<&'static str, &'static str> = ("Language", "Linguaggio"), ("Keep RustDesk background service", ""), ("Ignore Battery Optimizations", ""), + ("android_open_battery_optimizations_tip", ""), ].iter().cloned().collect(); } diff --git a/src/lang/ptbr.rs b/src/lang/ptbr.rs index e36672e5c..e3cadd204 100644 --- a/src/lang/ptbr.rs +++ b/src/lang/ptbr.rs @@ -286,5 +286,6 @@ pub static ref T: std::collections::HashMap<&'static str, &'static str> = ("Language", ""), ("Keep RustDesk background service", ""), ("Ignore Battery Optimizations", ""), + ("android_open_battery_optimizations_tip", ""), ].iter().cloned().collect(); } diff --git a/src/lang/ru.rs b/src/lang/ru.rs index d8f138223..7735e3db3 100644 --- a/src/lang/ru.rs +++ b/src/lang/ru.rs @@ -286,5 +286,6 @@ pub static ref T: std::collections::HashMap<&'static str, &'static str> = ("Language", "Язык"), ("Keep RustDesk background service", ""), ("Ignore Battery Optimizations", ""), + ("android_open_battery_optimizations_tip", ""), ].iter().cloned().collect(); } diff --git a/src/lang/sk.rs b/src/lang/sk.rs index 4f2a4a29f..ea8d22aa8 100644 --- a/src/lang/sk.rs +++ b/src/lang/sk.rs @@ -286,5 +286,6 @@ pub static ref T: std::collections::HashMap<&'static str, &'static str> = ("Language", ""), ("Keep RustDesk background service", ""), ("Ignore Battery Optimizations", ""), + ("android_open_battery_optimizations_tip", ""), ].iter().cloned().collect(); } diff --git a/src/lang/template.rs b/src/lang/template.rs index 8feac4d3b..9ea7146e1 100644 --- a/src/lang/template.rs +++ b/src/lang/template.rs @@ -286,5 +286,6 @@ pub static ref T: std::collections::HashMap<&'static str, &'static str> = ("Language", ""), ("Keep RustDesk background service", ""), ("Ignore Battery Optimizations", ""), + ("android_open_battery_optimizations_tip", ""), ].iter().cloned().collect(); } diff --git a/src/lang/tr.rs b/src/lang/tr.rs index 5bab8d8c9..1d30425dc 100644 --- a/src/lang/tr.rs +++ b/src/lang/tr.rs @@ -286,5 +286,6 @@ pub static ref T: std::collections::HashMap<&'static str, &'static str> = ("Language", ""), ("Keep RustDesk background service", ""), ("Ignore Battery Optimizations", ""), + ("android_open_battery_optimizations_tip", ""), ].iter().cloned().collect(); } diff --git a/src/lang/tw.rs b/src/lang/tw.rs index 8bc1392bb..30c8f5a76 100644 --- a/src/lang/tw.rs +++ b/src/lang/tw.rs @@ -286,5 +286,6 @@ pub static ref T: std::collections::HashMap<&'static str, &'static str> = ("Language", "語言"), ("Keep RustDesk background service", "保持RustDesk後台服務"), ("Ignore Battery Optimizations", "忽略電池優化"), + ("android_open_battery_optimizations_tip", "如需關閉此功能,請在接下來的RustDesk應用設置頁面中,找到並進入 [電源] 頁面,取消勾選 [不受限制]"), ].iter().cloned().collect(); } diff --git a/src/mobile.rs b/src/mobile.rs index 942510b17..d3adaaa79 100644 --- a/src/mobile.rs +++ b/src/mobile.rs @@ -599,7 +599,7 @@ impl Connection { async fn handle_msg_from_peer(&mut self, data: &[u8], peer: &mut Stream) -> bool { if let Ok(msg_in) = Message::parse_from_bytes(&data) { match msg_in.union { - Some(message::Union::video_frame(vf)) => { + Some(message::Union::VideoFrame(vf)) => { if !self.first_frame { self.first_frame = true; } @@ -610,21 +610,21 @@ impl Connection { s.add(ZeroCopyBuffer(self.video_handler.rgb.clone())); } } - Some(message::Union::hash(hash)) => { + Some(message::Union::Hash(hash)) => { self.session.handle_hash(hash, peer).await; } - Some(message::Union::login_response(lr)) => match lr.union { - Some(login_response::Union::error(err)) => { + Some(message::Union::LoginResponse(lr)) => match lr.union { + Some(login_response::Union::Error(err)) => { if !self.session.handle_login_error(&err) { return false; } } - Some(login_response::Union::peer_info(pi)) => { + Some(login_response::Union::PeerInfo(pi)) => { self.session.handle_peer_info(pi); } _ => {} }, - Some(message::Union::clipboard(cb)) => { + Some(message::Union::Clipboard(cb)) => { if !self.session.lc.read().unwrap().disable_clipboard { let content = if cb.compress { decompress(&cb.content) @@ -637,7 +637,7 @@ impl Connection { } } } - Some(message::Union::cursor_data(cd)) => { + Some(message::Union::CursorData(cd)) => { let colors = hbb_common::compress::decompress(&cd.colors); self.session.push_event( "cursor_data", @@ -654,18 +654,18 @@ impl Connection { ], ); } - Some(message::Union::cursor_id(id)) => { + Some(message::Union::CursorId(id)) => { self.session .push_event("cursor_id", vec![("id", &id.to_string())]); } - Some(message::Union::cursor_position(cp)) => { + Some(message::Union::CursorPosition(cp)) => { self.session.push_event( "cursor_position", vec![("x", &cp.x.to_string()), ("y", &cp.y.to_string())], ); } - Some(message::Union::file_response(fr)) => match fr.union { - Some(file_response::Union::dir(fd)) => { + Some(message::Union::FileResponse(fr)) => match fr.union { + Some(file_response::Union::Dir(fd)) => { let mut entries = fd.entries.to_vec(); if self.session.peer_platform() == "Windows" { fs::transform_windows_path(&mut entries); @@ -679,7 +679,7 @@ impl Connection { job.set_files(entries); } } - Some(file_response::Union::block(block)) => { + Some(file_response::Union::Block(block)) => { if let Some(job) = fs::get_job(block.id, &mut self.write_jobs) { if let Err(_err) = job.write(block, None).await { // to-do: add "skip" for writing job @@ -687,17 +687,17 @@ impl Connection { self.update_jobs_status(); } } - Some(file_response::Union::done(d)) => { + Some(file_response::Union::Done(d)) => { if let Some(job) = fs::get_job(d.id, &mut self.write_jobs) { job.modify_time(); fs::remove_job(d.id, &mut self.write_jobs); } self.handle_job_status(d.id, d.file_num, None); } - Some(file_response::Union::error(e)) => { + Some(file_response::Union::Error(e)) => { self.handle_job_status(e.id, e.file_num, Some(e.error)); } - Some(file_response::Union::digest(digest)) => { + Some(file_response::Union::Digest(digest)) => { if digest.is_upload { if let Some(job) = fs::get_job(digest.id, &mut self.read_jobs) { if let Some(file) = job.files().get(digest.file_num as usize) { @@ -708,9 +708,9 @@ impl Connection { id: digest.id, file_num: digest.file_num, union: Some(if overwrite { - file_transfer_send_confirm_request::Union::offset_blk(0) + file_transfer_send_confirm_request::Union::OffsetBlk(0) } else { - file_transfer_send_confirm_request::Union::skip( + file_transfer_send_confirm_request::Union::Skip( true, ) }), @@ -740,7 +740,7 @@ impl Connection { let msg= new_send_confirm(FileTransferSendConfirmRequest { id: digest.id, file_num: digest.file_num, - union: Some(file_transfer_send_confirm_request::Union::skip(true)), + union: Some(file_transfer_send_confirm_request::Union::Skip(true)), ..Default::default() }); self.session.send_msg(msg); @@ -752,9 +752,9 @@ impl Connection { id: digest.id, file_num: digest.file_num, union: Some(if overwrite { - file_transfer_send_confirm_request::Union::offset_blk(0) + file_transfer_send_confirm_request::Union::OffsetBlk(0) } else { - file_transfer_send_confirm_request::Union::skip(true) + file_transfer_send_confirm_request::Union::Skip(true) }), ..Default::default() }, @@ -774,7 +774,7 @@ impl Connection { FileTransferSendConfirmRequest { id: digest.id, file_num: digest.file_num, - union: Some(file_transfer_send_confirm_request::Union::offset_blk(0)), + union: Some(file_transfer_send_confirm_request::Union::OffsetBlk(0)), ..Default::default() }, ); @@ -791,15 +791,15 @@ impl Connection { } _ => {} }, - Some(message::Union::misc(misc)) => match misc.union { - Some(misc::Union::audio_format(f)) => { + Some(message::Union::Misc(misc)) => match misc.union { + Some(misc::Union::AudioFormat(f)) => { self.audio_handler.handle_format(f); // } - Some(misc::Union::chat_message(c)) => { + Some(misc::Union::ChatMessage(c)) => { self.session .push_event("chat_client_mode", vec![("text", &c.text)]); } - Some(misc::Union::permission_info(p)) => { + Some(misc::Union::PermissionInfo(p)) => { log::info!("Change permission {:?} -> {}", p.permission, p.enabled); use permission_info::Permission; self.session.push_event( @@ -815,7 +815,7 @@ impl Connection { )], ); } - Some(misc::Union::switch_display(s)) => { + Some(misc::Union::SwitchDisplay(s)) => { self.video_handler.reset(); self.session.push_event( "switch_display", @@ -828,22 +828,22 @@ impl Connection { ], ); } - Some(misc::Union::close_reason(c)) => { + Some(misc::Union::CloseReason(c)) => { self.session.msgbox("error", "Connection Error", &c); return false; } _ => {} }, - Some(message::Union::test_delay(t)) => { + Some(message::Union::TestDelay(t)) => { self.session.handle_test_delay(t, peer).await; } - Some(message::Union::audio_frame(frame)) => { + Some(message::Union::AudioFrame(frame)) => { if !self.session.lc.read().unwrap().disable_audio { self.audio_handler.handle_frame(frame); } } - Some(message::Union::file_action(action)) => match action.union { - Some(file_action::Union::send_confirm(c)) => { + Some(message::Union::FileAction(action)) => match action.union { + Some(file_action::Union::SendConfirm(c)) => { if let Some(job) = fs::get_job(c.id, &mut self.read_jobs) { job.confirm(&c); } @@ -1029,9 +1029,9 @@ impl Connection { id, file_num, union: if need_override { - Some(file_transfer_send_confirm_request::Union::offset_blk(0)) + Some(file_transfer_send_confirm_request::Union::OffsetBlk(0)) } else { - Some(file_transfer_send_confirm_request::Union::skip(true)) + Some(file_transfer_send_confirm_request::Union::Skip(true)) }, ..Default::default() }); @@ -1047,9 +1047,9 @@ impl Connection { id, file_num, union: if need_override { - Some(file_transfer_send_confirm_request::Union::offset_blk(0)) + Some(file_transfer_send_confirm_request::Union::OffsetBlk(0)) } else { - Some(file_transfer_send_confirm_request::Union::skip(true)) + Some(file_transfer_send_confirm_request::Union::Skip(true)) }, ..Default::default() }); @@ -1451,7 +1451,7 @@ pub mod connection_manager { let mut req = FileTransferSendConfirmRequest { id, file_num, - union: Some(file_transfer_send_confirm_request::Union::offset_blk(0)), + union: Some(file_transfer_send_confirm_request::Union::OffsetBlk(0)), ..Default::default() }; let digest = FileTransferDigest {