wake lock for all connection type
Signed-off-by: 21pages <pages21@163.com>
This commit is contained in:
parent
bd81e4d0fb
commit
2de1c62daf
3
Cargo.lock
generated
3
Cargo.lock
generated
@ -124,8 +124,7 @@ checksum = "e999941b234f3131b00bc13c22d06e8c5ff726d1b6318ac7eb276997bbb4fef0"
|
|||||||
[[package]]
|
[[package]]
|
||||||
name = "android-wakelock"
|
name = "android-wakelock"
|
||||||
version = "0.1.0"
|
version = "0.1.0"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "git+https://github.com/21pages/android-wakelock#d0292e5a367e627c4fa6f1ca6bdfad005dca7d90"
|
||||||
checksum = "296e5b7c23adb32743194b1810604b772f2be10f0b0387365cb3ba09cd5c1851"
|
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"jni 0.21.1",
|
"jni 0.21.1",
|
||||||
"log",
|
"log",
|
||||||
|
@ -81,6 +81,7 @@ cidr-utils = "0.5"
|
|||||||
libloading = "0.8"
|
libloading = "0.8"
|
||||||
fon = "0.6"
|
fon = "0.6"
|
||||||
zip = "0.6"
|
zip = "0.6"
|
||||||
|
shutdown_hooks = "0.1"
|
||||||
|
|
||||||
[target.'cfg(not(any(target_os = "android", target_os = "linux")))'.dependencies]
|
[target.'cfg(not(any(target_os = "android", target_os = "linux")))'.dependencies]
|
||||||
cpal = "0.15"
|
cpal = "0.15"
|
||||||
@ -95,7 +96,6 @@ clipboard = { path = "libs/clipboard" }
|
|||||||
ctrlc = "3.2"
|
ctrlc = "3.2"
|
||||||
arboard = "3.2"
|
arboard = "3.2"
|
||||||
system_shutdown = "4.0"
|
system_shutdown = "4.0"
|
||||||
shutdown_hooks = "0.1"
|
|
||||||
|
|
||||||
[target.'cfg(target_os = "windows")'.dependencies]
|
[target.'cfg(target_os = "windows")'.dependencies]
|
||||||
winapi = { version = "0.3", features = ["winuser", "wincrypt", "shellscalingapi", "pdh", "synchapi", "memoryapi"] }
|
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]
|
[target.'cfg(target_os = "android")'.dependencies]
|
||||||
android_logger = "0.13"
|
android_logger = "0.13"
|
||||||
jni = "0.21"
|
jni = "0.21"
|
||||||
android-wakelock = "0.1"
|
android-wakelock = { git = "https://github.com/21pages/android-wakelock" }
|
||||||
|
|
||||||
[workspace]
|
[workspace]
|
||||||
members = ["libs/scrap", "libs/hbb_common", "libs/enigo", "libs/clipboard", "libs/virtual_display", "libs/virtual_display/dylib", "libs/portable"]
|
members = ["libs/scrap", "libs/hbb_common", "libs/enigo", "libs/clipboard", "libs/virtual_display", "libs/virtual_display/dylib", "libs/portable"]
|
||||||
|
@ -624,8 +624,6 @@ class _PeerTabPageState extends State<PeerTabPage>
|
|||||||
searchWidth -
|
searchWidth -
|
||||||
(actions.length == 2 ? otherActionWidth : 0);
|
(actions.length == 2 ? otherActionWidth : 0);
|
||||||
final availablePositions = rightWidth ~/ otherActionWidth;
|
final availablePositions = rightWidth ~/ otherActionWidth;
|
||||||
debugPrint(
|
|
||||||
"dynamic action count:${dynamicActions.length}, available positions: $availablePositions");
|
|
||||||
|
|
||||||
if (availablePositions < dynamicActions.length &&
|
if (availablePositions < dynamicActions.length &&
|
||||||
dynamicActions.length > 1) {
|
dynamicActions.length > 1) {
|
||||||
@ -767,7 +765,11 @@ class PeerViewDropdown extends StatefulWidget {
|
|||||||
class _PeerViewDropdownState extends State<PeerViewDropdown> {
|
class _PeerViewDropdownState extends State<PeerViewDropdown> {
|
||||||
@override
|
@override
|
||||||
Widget build(BuildContext context) {
|
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(
|
final style = TextStyle(
|
||||||
color: Theme.of(context).textTheme.titleLarge?.color,
|
color: Theme.of(context).textTheme.titleLarge?.color,
|
||||||
fontSize: MenuConfig.fontSize,
|
fontSize: MenuConfig.fontSize,
|
||||||
@ -784,13 +786,16 @@ class _PeerViewDropdownState extends State<PeerViewDropdown> {
|
|||||||
child: SizedBox(
|
child: SizedBox(
|
||||||
height: 36,
|
height: 36,
|
||||||
child: getRadio<PeerUiType>(
|
child: getRadio<PeerUiType>(
|
||||||
Text(translate(
|
Text(
|
||||||
types.indexOf(e) == 0 ? 'Big tiles' : types.indexOf(e) == 1 ? 'Small tiles' : 'List'
|
translate(types.indexOf(e) == 0
|
||||||
), style: style),
|
? 'Big tiles'
|
||||||
|
: types.indexOf(e) == 1
|
||||||
|
? 'Small tiles'
|
||||||
|
: 'List'),
|
||||||
|
style: style),
|
||||||
e,
|
e,
|
||||||
peerCardUiType.value,
|
peerCardUiType.value,
|
||||||
dense: true,
|
dense: true, (PeerUiType? v) async {
|
||||||
(PeerUiType? v) async {
|
|
||||||
if (v != null) {
|
if (v != null) {
|
||||||
peerCardUiType.value = v;
|
peerCardUiType.value = v;
|
||||||
setState(() {});
|
setState(() {});
|
||||||
@ -798,8 +803,8 @@ class _PeerViewDropdownState extends State<PeerViewDropdown> {
|
|||||||
k: "peer-card-ui-type",
|
k: "peer-card-ui-type",
|
||||||
v: peerCardUiType.value.index.toString(),
|
v: peerCardUiType.value.index.toString(),
|
||||||
);
|
);
|
||||||
}}
|
}
|
||||||
),
|
}),
|
||||||
),
|
),
|
||||||
))));
|
))));
|
||||||
}
|
}
|
||||||
@ -827,12 +832,10 @@ class _PeerViewDropdownState extends State<PeerViewDropdown> {
|
|||||||
position: menuPos,
|
position: menuPos,
|
||||||
items: items,
|
items: items,
|
||||||
elevation: 8,
|
elevation: 8,
|
||||||
)
|
));
|
||||||
);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
class PeerSortDropdown extends StatefulWidget {
|
class PeerSortDropdown extends StatefulWidget {
|
||||||
const PeerSortDropdown({super.key});
|
const PeerSortDropdown({super.key});
|
||||||
|
|
||||||
|
@ -260,6 +260,7 @@ fn init_ndk_context() -> JniResult<()> {
|
|||||||
unsafe {
|
unsafe {
|
||||||
ndk_context::release_android_context();
|
ndk_context::release_android_context();
|
||||||
}
|
}
|
||||||
|
*lock = false;
|
||||||
}
|
}
|
||||||
if let (Some(jvm), Some(ctx)) = (
|
if let (Some(jvm), Some(ctx)) = (
|
||||||
JVM.read().unwrap().as_ref(),
|
JVM.read().unwrap().as_ref(),
|
||||||
|
@ -310,7 +310,7 @@ impl RecorderApi for WebmRecorder {
|
|||||||
|
|
||||||
impl Drop for WebmRecorder {
|
impl Drop for WebmRecorder {
|
||||||
fn drop(&mut self) {
|
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;
|
let mut state = RecordState::WriteTail;
|
||||||
if !self.written || self.start.elapsed().as_secs() < MIN_SECS {
|
if !self.written || self.start.elapsed().as_secs() < MIN_SECS {
|
||||||
std::fs::remove_file(&self.ctx.filename).ok();
|
std::fs::remove_file(&self.ctx.filename).ok();
|
||||||
|
@ -82,35 +82,28 @@ pub const PA_SAMPLE_RATE: u32 = 48000;
|
|||||||
|
|
||||||
#[cfg(target_os = "android")]
|
#[cfg(target_os = "android")]
|
||||||
#[derive(Default)]
|
#[derive(Default)]
|
||||||
pub struct WakeLock {
|
pub struct WakeLock(Option<android_wakelock::WakeLock>);
|
||||||
lock: Option<android_wakelock::WakeLock>,
|
|
||||||
}
|
|
||||||
|
|
||||||
#[cfg(target_os = "android")]
|
#[cfg(target_os = "android")]
|
||||||
impl WakeLock {
|
impl WakeLock {
|
||||||
pub fn new(tag: &str) -> Self {
|
pub fn new(tag: &str) -> Self {
|
||||||
let tag = format!("{}:{tag}", crate::get_app_name());
|
let tag = format!("{}:{tag}", crate::get_app_name());
|
||||||
match android_wakelock::partial(tag) {
|
match android_wakelock::partial(tag) {
|
||||||
Ok(lock) => Self { lock: Some(lock) },
|
Ok(lock) => Self(Some(lock)),
|
||||||
Err(e) => {
|
Err(e) => {
|
||||||
hbb_common::log::error!("Failed to get wakelock: {e:?}");
|
hbb_common::log::error!("Failed to get wakelock: {e:?}");
|
||||||
Self::default()
|
Self::default()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
pub fn acquire(&self) -> Option<android_wakelock::Guard> {
|
pub fn get_wake_lock(_display: bool) -> WakeLock {
|
||||||
match self.lock.as_ref() {
|
hbb_common::log::info!("new wakelock, require display on: {_display}");
|
||||||
Some(lock) => match lock.acquire() {
|
#[cfg(target_os = "android")]
|
||||||
Ok(guard) => Some(guard),
|
return crate::platform::WakeLock::new("server");
|
||||||
Err(e) => {
|
#[cfg(not(target_os = "android"))]
|
||||||
hbb_common::log::error!("Failed to acquire wakelock guard: {e:?}");
|
return crate::platform::WakeLock::new(_display, true, true);
|
||||||
None
|
|
||||||
}
|
|
||||||
},
|
|
||||||
None => None,
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
pub(crate) struct InstallingService; // please use new
|
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 ALIVE_CONNS: Arc::<Mutex<Vec<i32>>> = Default::default();
|
||||||
static ref AUTHED_CONNS: Arc::<Mutex<Vec<(i32, AuthConnType)>>> = 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 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"))]
|
#[cfg(any(target_os = "windows", target_os = "linux"))]
|
||||||
@ -1248,8 +1249,6 @@ impl Connection {
|
|||||||
}
|
}
|
||||||
|
|
||||||
fn on_remote_authorized(&self) {
|
fn on_remote_authorized(&self) {
|
||||||
use std::sync::Once;
|
|
||||||
static _ONCE: Once = Once::new();
|
|
||||||
self.update_codec_on_login();
|
self.update_codec_on_login();
|
||||||
#[cfg(any(target_os = "windows", target_os = "linux"))]
|
#[cfg(any(target_os = "windows", target_os = "linux"))]
|
||||||
if !Config::get_option("allow-remove-wallpaper").is_empty() {
|
if !Config::get_option("allow-remove-wallpaper").is_empty() {
|
||||||
@ -1259,9 +1258,6 @@ impl Connection {
|
|||||||
match crate::platform::WallPaperRemover::new() {
|
match crate::platform::WallPaperRemover::new() {
|
||||||
Ok(remover) => {
|
Ok(remover) => {
|
||||||
*wallpaper = Some(remover);
|
*wallpaper = Some(remover);
|
||||||
_ONCE.call_once(|| {
|
|
||||||
shutdown_hooks::add_shutdown_hook(shutdown_hook);
|
|
||||||
});
|
|
||||||
}
|
}
|
||||||
Err(e) => {
|
Err(e) => {
|
||||||
log::info!("create wallpaper remover failed: {:?}", e);
|
log::info!("create wallpaper remover failed: {:?}", e);
|
||||||
@ -2372,7 +2368,8 @@ impl Connection {
|
|||||||
|
|
||||||
if t.on {
|
if t.on {
|
||||||
if !virtual_display_manager::is_virtual_display_supported() {
|
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 {
|
} else {
|
||||||
if let Err(e) =
|
if let Err(e) =
|
||||||
virtual_display_manager::plug_in_index_modes(t.display as _, Vec::new())
|
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 connection_shutdown_hook() {
|
||||||
extern "C" fn 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;
|
*WALLPAPER_REMOVER.lock().unwrap() = None;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
mod raii {
|
mod raii {
|
||||||
@ -3262,8 +3264,38 @@ mod raii {
|
|||||||
impl AuthedConnID {
|
impl AuthedConnID {
|
||||||
pub fn new(id: i32, conn_type: AuthConnType) -> Self {
|
pub fn new(id: i32, conn_type: AuthConnType) -> Self {
|
||||||
AUTHED_CONNS.lock().unwrap().push((id, conn_type));
|
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)
|
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 {
|
impl Drop for AuthedConnID {
|
||||||
@ -3271,9 +3303,14 @@ mod raii {
|
|||||||
if self.1 == AuthConnType::Remote {
|
if self.1 == AuthConnType::Remote {
|
||||||
scrap::codec::Encoder::update(self.0, scrap::codec::EncodingUpdate::Remove);
|
scrap::codec::Encoder::update(self.0, scrap::codec::EncodingUpdate::Remove);
|
||||||
}
|
}
|
||||||
let mut lock = AUTHED_CONNS.lock().unwrap();
|
AUTHED_CONNS.lock().unwrap().retain(|&c| c.0 != self.0);
|
||||||
lock.retain(|&c| c.0 != self.0);
|
let remote_count = AUTHED_CONNS
|
||||||
if lock.iter().filter(|c| c.1 == AuthConnType::Remote).count() == 0 {
|
.lock()
|
||||||
|
.unwrap()
|
||||||
|
.iter()
|
||||||
|
.filter(|c| c.1 == AuthConnType::Remote)
|
||||||
|
.count();
|
||||||
|
if remote_count == 0 {
|
||||||
#[cfg(any(target_os = "windows", target_os = "linux"))]
|
#[cfg(any(target_os = "windows", target_os = "linux"))]
|
||||||
{
|
{
|
||||||
*WALLPAPER_REMOVER.lock().unwrap() = None;
|
*WALLPAPER_REMOVER.lock().unwrap() = None;
|
||||||
@ -3283,6 +3320,7 @@ mod raii {
|
|||||||
#[cfg(all(windows, feature = "virtual_display_driver"))]
|
#[cfg(all(windows, feature = "virtual_display_driver"))]
|
||||||
let _ = virtual_display_manager::reset_all();
|
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() {
|
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();
|
let mut lock = SHMEM.lock().unwrap();
|
||||||
if lock.is_some() {
|
if lock.is_some() {
|
||||||
*lock = None;
|
*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<()> {
|
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.
|
// 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.
|
// 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]
|
#[inline]
|
||||||
fn try_broadcast_display_changed(
|
fn try_broadcast_display_changed(
|
||||||
sp: &GenericService,
|
sp: &GenericService,
|
||||||
|
Loading…
x
Reference in New Issue
Block a user