mirror of
https://github.com/rustdesk/rustdesk.git
synced 2024-11-24 04:12:20 +08:00
Merge pull request #6520 from 21pages/wakelock
wake lock for all connection type
This commit is contained in:
commit
b8f7259fbd
3
Cargo.lock
generated
3
Cargo.lock
generated
@ -124,8 +124,7 @@ checksum = "e999941b234f3131b00bc13c22d06e8c5ff726d1b6318ac7eb276997bbb4fef0"
|
||||
[[package]]
|
||||
name = "android-wakelock"
|
||||
version = "0.1.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "296e5b7c23adb32743194b1810604b772f2be10f0b0387365cb3ba09cd5c1851"
|
||||
source = "git+https://github.com/21pages/android-wakelock#d0292e5a367e627c4fa6f1ca6bdfad005dca7d90"
|
||||
dependencies = [
|
||||
"jni 0.21.1",
|
||||
"log",
|
||||
|
@ -81,6 +81,7 @@ cidr-utils = "0.5"
|
||||
libloading = "0.8"
|
||||
fon = "0.6"
|
||||
zip = "0.6"
|
||||
shutdown_hooks = "0.1"
|
||||
|
||||
[target.'cfg(not(any(target_os = "android", target_os = "linux")))'.dependencies]
|
||||
cpal = "0.15"
|
||||
@ -95,7 +96,6 @@ clipboard = { path = "libs/clipboard" }
|
||||
ctrlc = "3.2"
|
||||
arboard = "3.2"
|
||||
system_shutdown = "4.0"
|
||||
shutdown_hooks = "0.1"
|
||||
|
||||
[target.'cfg(target_os = "windows")'.dependencies]
|
||||
winapi = { version = "0.3", features = ["winuser", "wincrypt", "shellscalingapi", "pdh", "synchapi", "memoryapi"] }
|
||||
@ -147,7 +147,7 @@ once_cell = {version = "1.18", optional = true}
|
||||
[target.'cfg(target_os = "android")'.dependencies]
|
||||
android_logger = "0.13"
|
||||
jni = "0.21"
|
||||
android-wakelock = "0.1"
|
||||
android-wakelock = { git = "https://github.com/21pages/android-wakelock" }
|
||||
|
||||
[workspace]
|
||||
members = ["libs/scrap", "libs/hbb_common", "libs/enigo", "libs/clipboard", "libs/virtual_display", "libs/virtual_display/dylib", "libs/portable"]
|
||||
|
@ -76,10 +76,10 @@ class _PeerTabPageState extends State<PeerTabPage>
|
||||
final uiType = bind.getLocalFlutterOption(k: 'peer-card-ui-type');
|
||||
if (uiType != '') {
|
||||
peerCardUiType.value = int.parse(uiType) == 0
|
||||
? PeerUiType.grid
|
||||
: int.parse(uiType) == 1
|
||||
? PeerUiType.tile
|
||||
: PeerUiType.list;
|
||||
? PeerUiType.grid
|
||||
: int.parse(uiType) == 1
|
||||
? PeerUiType.tile
|
||||
: PeerUiType.list;
|
||||
}
|
||||
hideAbTagsPanel.value =
|
||||
bind.mainGetLocalOption(key: "hideAbTagsPanel").isNotEmpty;
|
||||
@ -624,8 +624,6 @@ class _PeerTabPageState extends State<PeerTabPage>
|
||||
searchWidth -
|
||||
(actions.length == 2 ? otherActionWidth : 0);
|
||||
final availablePositions = rightWidth ~/ otherActionWidth;
|
||||
debugPrint(
|
||||
"dynamic action count:${dynamicActions.length}, available positions: $availablePositions");
|
||||
|
||||
if (availablePositions < dynamicActions.length &&
|
||||
dynamicActions.length > 1) {
|
||||
@ -767,7 +765,11 @@ class PeerViewDropdown extends StatefulWidget {
|
||||
class _PeerViewDropdownState extends State<PeerViewDropdown> {
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
final List<PeerUiType> types = [PeerUiType.grid, PeerUiType.tile, PeerUiType.list];
|
||||
final List<PeerUiType> types = [
|
||||
PeerUiType.grid,
|
||||
PeerUiType.tile,
|
||||
PeerUiType.list
|
||||
];
|
||||
final style = TextStyle(
|
||||
color: Theme.of(context).textTheme.titleLarge?.color,
|
||||
fontSize: MenuConfig.fontSize,
|
||||
@ -777,20 +779,23 @@ class _PeerViewDropdownState extends State<PeerViewDropdown> {
|
||||
height: 36,
|
||||
enabled: false,
|
||||
child: Text(translate("Change view"), style: style)));
|
||||
for (var e in PeerUiType.values) {
|
||||
for (var e in PeerUiType.values) {
|
||||
items.add(PopupMenuItem(
|
||||
height: 36,
|
||||
child: Obx(() => Center(
|
||||
child: SizedBox(
|
||||
height: 36,
|
||||
child: getRadio<PeerUiType>(
|
||||
Text(translate(
|
||||
types.indexOf(e) == 0 ? 'Big tiles' : types.indexOf(e) == 1 ? 'Small tiles' : 'List'
|
||||
), style: style),
|
||||
e,
|
||||
Text(
|
||||
translate(types.indexOf(e) == 0
|
||||
? 'Big tiles'
|
||||
: types.indexOf(e) == 1
|
||||
? 'Small tiles'
|
||||
: 'List'),
|
||||
style: style),
|
||||
e,
|
||||
peerCardUiType.value,
|
||||
dense: true,
|
||||
(PeerUiType? v) async {
|
||||
dense: true, (PeerUiType? v) async {
|
||||
if (v != null) {
|
||||
peerCardUiType.value = v;
|
||||
setState(() {});
|
||||
@ -798,18 +803,18 @@ class _PeerViewDropdownState extends State<PeerViewDropdown> {
|
||||
k: "peer-card-ui-type",
|
||||
v: peerCardUiType.value.index.toString(),
|
||||
);
|
||||
}}
|
||||
),
|
||||
}
|
||||
}),
|
||||
),
|
||||
))));
|
||||
}
|
||||
|
||||
var menuPos = RelativeRect.fromLTRB(0, 0, 0, 0);
|
||||
return _hoverAction(
|
||||
context: context,
|
||||
child: Tooltip(
|
||||
message: translate('Change view'),
|
||||
child: Icon(
|
||||
context: context,
|
||||
child: Tooltip(
|
||||
message: translate('Change view'),
|
||||
child: Icon(
|
||||
peerCardUiType.value == PeerUiType.grid
|
||||
? Icons.grid_view_rounded
|
||||
: peerCardUiType.value == PeerUiType.tile
|
||||
@ -817,22 +822,20 @@ class _PeerViewDropdownState extends State<PeerViewDropdown> {
|
||||
: Icons.view_agenda_rounded,
|
||||
size: 18,
|
||||
)),
|
||||
onTapDown: (details) {
|
||||
final x = details.globalPosition.dx;
|
||||
final y = details.globalPosition.dy;
|
||||
menuPos = RelativeRect.fromLTRB(x, y, x, y);
|
||||
},
|
||||
onTap: () => showMenu(
|
||||
context: context,
|
||||
position: menuPos,
|
||||
items: items,
|
||||
elevation: 8,
|
||||
)
|
||||
);
|
||||
onTapDown: (details) {
|
||||
final x = details.globalPosition.dx;
|
||||
final y = details.globalPosition.dy;
|
||||
menuPos = RelativeRect.fromLTRB(x, y, x, y);
|
||||
},
|
||||
onTap: () => showMenu(
|
||||
context: context,
|
||||
position: menuPos,
|
||||
items: items,
|
||||
elevation: 8,
|
||||
));
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
class PeerSortDropdown extends StatefulWidget {
|
||||
const PeerSortDropdown({super.key});
|
||||
|
||||
|
@ -260,6 +260,7 @@ fn init_ndk_context() -> JniResult<()> {
|
||||
unsafe {
|
||||
ndk_context::release_android_context();
|
||||
}
|
||||
*lock = false;
|
||||
}
|
||||
if let (Some(jvm), Some(ctx)) = (
|
||||
JVM.read().unwrap().as_ref(),
|
||||
|
@ -310,7 +310,7 @@ impl RecorderApi for WebmRecorder {
|
||||
|
||||
impl Drop for WebmRecorder {
|
||||
fn drop(&mut self) {
|
||||
std::mem::replace(&mut self.webm, None).map_or(false, |webm| webm.finalize(None));
|
||||
let _ = std::mem::replace(&mut self.webm, None).map_or(false, |webm| webm.finalize(None));
|
||||
let mut state = RecordState::WriteTail;
|
||||
if !self.written || self.start.elapsed().as_secs() < MIN_SECS {
|
||||
std::fs::remove_file(&self.ctx.filename).ok();
|
||||
|
@ -82,35 +82,28 @@ pub const PA_SAMPLE_RATE: u32 = 48000;
|
||||
|
||||
#[cfg(target_os = "android")]
|
||||
#[derive(Default)]
|
||||
pub struct WakeLock {
|
||||
lock: Option<android_wakelock::WakeLock>,
|
||||
}
|
||||
pub struct WakeLock(Option<android_wakelock::WakeLock>);
|
||||
|
||||
#[cfg(target_os = "android")]
|
||||
impl WakeLock {
|
||||
pub fn new(tag: &str) -> Self {
|
||||
let tag = format!("{}:{tag}", crate::get_app_name());
|
||||
match android_wakelock::partial(tag) {
|
||||
Ok(lock) => Self { lock: Some(lock) },
|
||||
Ok(lock) => Self(Some(lock)),
|
||||
Err(e) => {
|
||||
hbb_common::log::error!("Failed to get wakelock: {e:?}");
|
||||
Self::default()
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
pub fn acquire(&self) -> Option<android_wakelock::Guard> {
|
||||
match self.lock.as_ref() {
|
||||
Some(lock) => match lock.acquire() {
|
||||
Ok(guard) => Some(guard),
|
||||
Err(e) => {
|
||||
hbb_common::log::error!("Failed to acquire wakelock guard: {e:?}");
|
||||
None
|
||||
}
|
||||
},
|
||||
None => None,
|
||||
}
|
||||
}
|
||||
pub fn get_wake_lock(_display: bool) -> WakeLock {
|
||||
hbb_common::log::info!("new wakelock, require display on: {_display}");
|
||||
#[cfg(target_os = "android")]
|
||||
return crate::platform::WakeLock::new("server");
|
||||
#[cfg(not(target_os = "android"))]
|
||||
return crate::platform::WakeLock::new(_display, true, true);
|
||||
}
|
||||
|
||||
pub(crate) struct InstallingService; // please use new
|
||||
|
@ -70,6 +70,7 @@ lazy_static::lazy_static! {
|
||||
static ref ALIVE_CONNS: Arc::<Mutex<Vec<i32>>> = Default::default();
|
||||
static ref AUTHED_CONNS: Arc::<Mutex<Vec<(i32, AuthConnType)>>> = Default::default();
|
||||
static ref SWITCH_SIDES_UUID: Arc::<Mutex<HashMap<String, (Instant, uuid::Uuid)>>> = Default::default();
|
||||
static ref WAKE_LOCK: Arc::<Mutex<Option<(crate::platform::WakeLock, bool)>>> = Default::default();
|
||||
}
|
||||
|
||||
#[cfg(any(target_os = "windows", target_os = "linux"))]
|
||||
@ -1248,8 +1249,6 @@ impl Connection {
|
||||
}
|
||||
|
||||
fn on_remote_authorized(&self) {
|
||||
use std::sync::Once;
|
||||
static _ONCE: Once = Once::new();
|
||||
self.update_codec_on_login();
|
||||
#[cfg(any(target_os = "windows", target_os = "linux"))]
|
||||
if !Config::get_option("allow-remove-wallpaper").is_empty() {
|
||||
@ -1259,9 +1258,6 @@ impl Connection {
|
||||
match crate::platform::WallPaperRemover::new() {
|
||||
Ok(remover) => {
|
||||
*wallpaper = Some(remover);
|
||||
_ONCE.call_once(|| {
|
||||
shutdown_hooks::add_shutdown_hook(shutdown_hook);
|
||||
});
|
||||
}
|
||||
Err(e) => {
|
||||
log::info!("create wallpaper remover failed: {:?}", e);
|
||||
@ -2372,7 +2368,8 @@ impl Connection {
|
||||
|
||||
if t.on {
|
||||
if !virtual_display_manager::is_virtual_display_supported() {
|
||||
self.send(make_msg("idd_not_support_under_win10_2004_tip".to_string())).await;
|
||||
self.send(make_msg("idd_not_support_under_win10_2004_tip".to_string()))
|
||||
.await;
|
||||
} else {
|
||||
if let Err(e) =
|
||||
virtual_display_manager::plug_in_index_modes(t.display as _, Vec::new())
|
||||
@ -3230,9 +3227,14 @@ impl LinuxHeadlessHandle {
|
||||
}
|
||||
}
|
||||
|
||||
#[cfg(any(target_os = "windows", target_os = "linux"))]
|
||||
extern "C" fn shutdown_hook() {
|
||||
*WALLPAPER_REMOVER.lock().unwrap() = None;
|
||||
extern "C" fn connection_shutdown_hook() {
|
||||
// https://stackoverflow.com/questions/35980148/why-does-an-atexit-handler-panic-when-it-accesses-stdout
|
||||
// Please make sure there is no print in the call stack
|
||||
*WAKE_LOCK.lock().unwrap() = None;
|
||||
#[cfg(any(target_os = "windows", target_os = "linux"))]
|
||||
{
|
||||
*WALLPAPER_REMOVER.lock().unwrap() = None;
|
||||
}
|
||||
}
|
||||
|
||||
mod raii {
|
||||
@ -3262,8 +3264,38 @@ mod raii {
|
||||
impl AuthedConnID {
|
||||
pub fn new(id: i32, conn_type: AuthConnType) -> Self {
|
||||
AUTHED_CONNS.lock().unwrap().push((id, conn_type));
|
||||
Self::check_wake_lock();
|
||||
use std::sync::Once;
|
||||
static _ONCE: Once = Once::new();
|
||||
_ONCE.call_once(|| {
|
||||
shutdown_hooks::add_shutdown_hook(connection_shutdown_hook);
|
||||
});
|
||||
Self(id, conn_type)
|
||||
}
|
||||
|
||||
fn check_wake_lock() {
|
||||
let mut wake_lock = WAKE_LOCK.lock().unwrap();
|
||||
let remote_count = AUTHED_CONNS
|
||||
.lock()
|
||||
.unwrap()
|
||||
.iter()
|
||||
.filter(|c| c.1 == AuthConnType::Remote)
|
||||
.count();
|
||||
let display = remote_count > 0;
|
||||
if let Some((_, last_display)) = *wake_lock {
|
||||
if last_display != display {
|
||||
*wake_lock = None;
|
||||
}
|
||||
}
|
||||
let empty = AUTHED_CONNS.lock().unwrap().is_empty();
|
||||
if empty {
|
||||
*wake_lock = None;
|
||||
} else {
|
||||
if wake_lock.is_none() {
|
||||
*wake_lock = Some((crate::platform::get_wake_lock(display), display));
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl Drop for AuthedConnID {
|
||||
@ -3271,9 +3303,14 @@ mod raii {
|
||||
if self.1 == AuthConnType::Remote {
|
||||
scrap::codec::Encoder::update(self.0, scrap::codec::EncodingUpdate::Remove);
|
||||
}
|
||||
let mut lock = AUTHED_CONNS.lock().unwrap();
|
||||
lock.retain(|&c| c.0 != self.0);
|
||||
if lock.iter().filter(|c| c.1 == AuthConnType::Remote).count() == 0 {
|
||||
AUTHED_CONNS.lock().unwrap().retain(|&c| c.0 != self.0);
|
||||
let remote_count = AUTHED_CONNS
|
||||
.lock()
|
||||
.unwrap()
|
||||
.iter()
|
||||
.filter(|c| c.1 == AuthConnType::Remote)
|
||||
.count();
|
||||
if remote_count == 0 {
|
||||
#[cfg(any(target_os = "windows", target_os = "linux"))]
|
||||
{
|
||||
*WALLPAPER_REMOVER.lock().unwrap() = None;
|
||||
@ -3283,6 +3320,7 @@ mod raii {
|
||||
#[cfg(all(windows, feature = "virtual_display_driver"))]
|
||||
let _ = virtual_display_manager::reset_all();
|
||||
}
|
||||
Self::check_wake_lock();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -618,10 +618,11 @@ pub mod client {
|
||||
}
|
||||
|
||||
pub extern "C" fn drop_portable_service_shared_memory() {
|
||||
// https://stackoverflow.com/questions/35980148/why-does-an-atexit-handler-panic-when-it-accesses-stdout
|
||||
// Please make sure there is no print in the call stack
|
||||
let mut lock = SHMEM.lock().unwrap();
|
||||
if lock.is_some() {
|
||||
*lock = None;
|
||||
log::info!("drop shared memory");
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -363,13 +363,6 @@ fn get_capturer(current: usize, portable_service_running: bool) -> ResultType<Ca
|
||||
}
|
||||
|
||||
fn run(vs: VideoService) -> ResultType<()> {
|
||||
#[cfg(not(target_os = "android"))]
|
||||
let _wake_lock = get_wake_lock();
|
||||
#[cfg(target_os = "android")]
|
||||
let wake_lock = crate::platform::WakeLock::new("video service");
|
||||
#[cfg(target_os = "android")]
|
||||
let _lock_guard = wake_lock.acquire();
|
||||
|
||||
// Wayland only support one video capturer for now. It is ok to call ensure_inited() here.
|
||||
//
|
||||
// ensure_inited() is needed because clear() may be called.
|
||||
@ -735,19 +728,6 @@ fn start_uac_elevation_check() {
|
||||
});
|
||||
}
|
||||
|
||||
#[cfg(not(target_os = "android"))]
|
||||
fn get_wake_lock() -> crate::platform::WakeLock {
|
||||
let (display, idle, sleep) = if cfg!(windows) {
|
||||
(true, false, false)
|
||||
} else if cfg!(linux) {
|
||||
(false, false, true)
|
||||
} else {
|
||||
//macos
|
||||
(true, false, false)
|
||||
};
|
||||
crate::platform::WakeLock::new(display, idle, sleep)
|
||||
}
|
||||
|
||||
#[inline]
|
||||
fn try_broadcast_display_changed(
|
||||
sp: &GenericService,
|
||||
|
Loading…
Reference in New Issue
Block a user