privacy_mode_win_magnifier: more check on privacy mode
Signed-off-by: fufesou <shuanglongchen@yeah.net>
This commit is contained in:
parent
867d26b79c
commit
62cb9eb51e
@ -277,6 +277,29 @@ impl CapturerMag {
|
||||
height: usize,
|
||||
use_yuv: bool,
|
||||
) -> Result<Self> {
|
||||
unsafe {
|
||||
let x = GetSystemMetrics(SM_XVIRTUALSCREEN);
|
||||
let y = GetSystemMetrics(SM_YVIRTUALSCREEN);
|
||||
let w = GetSystemMetrics(SM_CXVIRTUALSCREEN);
|
||||
let h = GetSystemMetrics(SM_CYVIRTUALSCREEN);
|
||||
if !(origin.0 == x as _ && origin.1 == y as _ && width == w as _ && height == h as _) {
|
||||
return Err(Error::new(
|
||||
ErrorKind::Other,
|
||||
format!(
|
||||
"Failed Check screen rect ({}, {}, {} , {}) to ({}, {}, {}, {})",
|
||||
origin.0,
|
||||
origin.1,
|
||||
origin.0 + width as i32,
|
||||
origin.1 + height as i32,
|
||||
x,
|
||||
y,
|
||||
x + w,
|
||||
y + h
|
||||
),
|
||||
));
|
||||
}
|
||||
}
|
||||
|
||||
let mut s = Self {
|
||||
mag_interface: MagInterface::new()?,
|
||||
host_window: 0 as _,
|
||||
@ -364,17 +387,6 @@ impl CapturerMag {
|
||||
));
|
||||
}
|
||||
|
||||
let x = GetSystemMetrics(SM_XVIRTUALSCREEN);
|
||||
let y = GetSystemMetrics(SM_YVIRTUALSCREEN);
|
||||
let w = GetSystemMetrics(SM_CXVIRTUALSCREEN);
|
||||
let h = GetSystemMetrics(SM_CYVIRTUALSCREEN);
|
||||
s.rect = RECT {
|
||||
left: x as _,
|
||||
top: y as _,
|
||||
right: (x + w) as _,
|
||||
bottom: (y + h) as _,
|
||||
};
|
||||
|
||||
// Create the magnifier control.
|
||||
s.magnifier_window = CreateWindowExA(
|
||||
0,
|
||||
|
@ -386,9 +386,12 @@ impl Connection {
|
||||
}
|
||||
}
|
||||
|
||||
if video_service::get_privacy_mode_conn_id() == id {
|
||||
let video_privacy_conn_id = video_service::get_privacy_mode_conn_id();
|
||||
if video_privacy_conn_id == id {
|
||||
video_service::set_privacy_mode_conn_id(0);
|
||||
let _ = privacy_mode::turn_off_privacy(id).await;
|
||||
let _ = privacy_mode::turn_off_privacy(id);
|
||||
} else if video_privacy_conn_id == 0 {
|
||||
let _ = privacy_mode::turn_off_privacy(0);
|
||||
}
|
||||
video_service::notify_video_frame_feched(id, None);
|
||||
video_service::update_test_latency(id, 0);
|
||||
@ -657,7 +660,8 @@ impl Connection {
|
||||
features: Some(Features {
|
||||
privacy_mode: video_service::is_privacy_mode_supported(),
|
||||
..Default::default()
|
||||
}).into(),
|
||||
})
|
||||
.into(),
|
||||
..Default::default()
|
||||
};
|
||||
let mut sub_service = false;
|
||||
@ -1170,18 +1174,30 @@ impl Connection {
|
||||
} else {
|
||||
match privacy_mode::turn_on_privacy(self.inner.id) {
|
||||
Ok(true) => {
|
||||
video_service::set_privacy_mode_conn_id(self.inner.id);
|
||||
crate::common::make_privacy_mode_msg(
|
||||
back_notification::PrivacyModeState::OnSucceeded,
|
||||
)
|
||||
}
|
||||
Ok(false) => {
|
||||
crate::common::make_privacy_mode_msg(
|
||||
back_notification::PrivacyModeState::OnFailedPlugin,
|
||||
)
|
||||
if video_service::test_create_capturer(self.inner.id, 5_000) {
|
||||
video_service::set_privacy_mode_conn_id(self.inner.id);
|
||||
crate::common::make_privacy_mode_msg(
|
||||
back_notification::PrivacyModeState::OnSucceeded,
|
||||
)
|
||||
} else {
|
||||
log::error!(
|
||||
"Wait privacy mode timeout, turn off privacy mode"
|
||||
);
|
||||
video_service::set_privacy_mode_conn_id(0);
|
||||
let _ = privacy_mode::turn_off_privacy(self.inner.id);
|
||||
crate::common::make_privacy_mode_msg(
|
||||
back_notification::PrivacyModeState::OnFailed,
|
||||
)
|
||||
}
|
||||
}
|
||||
Ok(false) => crate::common::make_privacy_mode_msg(
|
||||
back_notification::PrivacyModeState::OnFailedPlugin,
|
||||
),
|
||||
Err(e) => {
|
||||
log::error!("Failed to turn on privacy mode. {}", e);
|
||||
if video_service::get_privacy_mode_conn_id() == 0 {
|
||||
let _ = privacy_mode::turn_off_privacy(0);
|
||||
}
|
||||
crate::common::make_privacy_mode_msg(
|
||||
back_notification::PrivacyModeState::OnFailed,
|
||||
)
|
||||
@ -1197,7 +1213,7 @@ impl Connection {
|
||||
)
|
||||
} else {
|
||||
video_service::set_privacy_mode_conn_id(0);
|
||||
privacy_mode::turn_off_privacy(self.inner.id).await
|
||||
privacy_mode::turn_off_privacy(self.inner.id)
|
||||
};
|
||||
self.send(msg_out).await;
|
||||
}
|
||||
@ -1354,7 +1370,7 @@ fn try_activate_screen() {
|
||||
mod privacy_mode {
|
||||
use super::*;
|
||||
|
||||
pub(super) async fn turn_off_privacy(_conn_id: i32) -> Message {
|
||||
pub(super) fn turn_off_privacy(_conn_id: i32) -> Message {
|
||||
#[cfg(windows)]
|
||||
{
|
||||
use crate::ui::win_privacy::*;
|
||||
|
@ -19,12 +19,9 @@
|
||||
// https://slhck.info/video/2017/03/01/rate-control.html
|
||||
|
||||
use super::*;
|
||||
use hbb_common::tokio::{
|
||||
runtime::Runtime,
|
||||
sync::{
|
||||
mpsc::{unbounded_channel, UnboundedReceiver, UnboundedSender},
|
||||
Mutex as TokioMutex,
|
||||
},
|
||||
use hbb_common::tokio::sync::{
|
||||
mpsc::{unbounded_channel, UnboundedReceiver, UnboundedSender},
|
||||
Mutex as TokioMutex,
|
||||
};
|
||||
use scrap::{Capturer, Config, Display, EncodeFrame, Encoder, Frame, VideoCodecId, STRIDE_ALIGN};
|
||||
use std::{
|
||||
@ -80,7 +77,6 @@ pub fn is_privacy_mode_supported() -> bool {
|
||||
struct VideoFrameController {
|
||||
cur: Instant,
|
||||
send_conn_ids: HashSet<i32>,
|
||||
rt: Runtime,
|
||||
}
|
||||
|
||||
impl VideoFrameController {
|
||||
@ -88,7 +84,6 @@ impl VideoFrameController {
|
||||
Self {
|
||||
cur: Instant::now(),
|
||||
send_conn_ids: HashSet::new(),
|
||||
rt: Runtime::new().unwrap(),
|
||||
}
|
||||
}
|
||||
|
||||
@ -103,46 +98,29 @@ impl VideoFrameController {
|
||||
}
|
||||
}
|
||||
|
||||
fn blocking_wait_next(&mut self, timeout_millis: u128) {
|
||||
#[tokio::main(flavor = "current_thread")]
|
||||
async fn try_wait_next(&mut self, fetched_conn_ids: &mut HashSet<i32>, timeout_millis: u64) {
|
||||
if self.send_conn_ids.is_empty() {
|
||||
return;
|
||||
}
|
||||
|
||||
let send_conn_ids = self.send_conn_ids.clone();
|
||||
self.rt.block_on(async move {
|
||||
let mut fetched_conn_ids = HashSet::new();
|
||||
let begin = Instant::now();
|
||||
while begin.elapsed().as_millis() < timeout_millis {
|
||||
let timeout_dur =
|
||||
Duration::from_millis((timeout_millis - begin.elapsed().as_millis()) as u64);
|
||||
match tokio::time::timeout(
|
||||
timeout_dur,
|
||||
FRAME_FETCHED_NOTIFIER.1.lock().await.recv(),
|
||||
)
|
||||
.await
|
||||
{
|
||||
Err(_) => {
|
||||
// break if timeout
|
||||
// log::error!("blocking wait frame receiving timeout {}", timeout_millis);
|
||||
break;
|
||||
}
|
||||
Ok(Some((id, instant))) => {
|
||||
if let Some(tm) = instant {
|
||||
log::trace!("Channel recv latency: {}", tm.elapsed().as_secs_f32());
|
||||
}
|
||||
fetched_conn_ids.insert(id);
|
||||
|
||||
// break if all connections have received current frame
|
||||
if fetched_conn_ids.len() >= send_conn_ids.len() {
|
||||
break;
|
||||
}
|
||||
}
|
||||
Ok(None) => {
|
||||
// this branch would nerver be reached
|
||||
}
|
||||
}
|
||||
let timeout_dur = Duration::from_millis(timeout_millis as u64);
|
||||
match tokio::time::timeout(timeout_dur, FRAME_FETCHED_NOTIFIER.1.lock().await.recv()).await
|
||||
{
|
||||
Err(_) => {
|
||||
// break if timeout
|
||||
// log::error!("blocking wait frame receiving timeout {}", timeout_millis);
|
||||
}
|
||||
});
|
||||
Ok(Some((id, instant))) => {
|
||||
if let Some(tm) = instant {
|
||||
log::trace!("Channel recv latency: {}", tm.elapsed().as_secs_f32());
|
||||
}
|
||||
fetched_conn_ids.insert(id);
|
||||
}
|
||||
Ok(None) => {
|
||||
// this branch would nerver be reached
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@ -271,7 +249,7 @@ fn create_capturer(privacy_mode_id: i32, display: Display) -> ResultType<Box<dyn
|
||||
PRIVACY_WINDOW_NAME
|
||||
);
|
||||
}
|
||||
log::info!("Create maginifier capture for {}", privacy_mode_id);
|
||||
log::debug!("Create maginifier capture for {}", privacy_mode_id);
|
||||
c = Some(Box::new(c1));
|
||||
}
|
||||
Err(e) => {
|
||||
@ -286,6 +264,7 @@ fn create_capturer(privacy_mode_id: i32, display: Display) -> ResultType<Box<dyn
|
||||
None => {
|
||||
let c1 =
|
||||
Capturer::new(display, use_yuv).with_context(|| "Failed to create capturer")?;
|
||||
log::debug!("Create capturer dxgi|gdi");
|
||||
Box::new(c1)
|
||||
}
|
||||
};
|
||||
@ -309,6 +288,19 @@ fn ensure_close_virtual_device() -> ResultType<()> {
|
||||
Ok(())
|
||||
}
|
||||
|
||||
pub fn test_create_capturer(privacy_mode_id: i32, timeout_millis: u64) -> bool {
|
||||
let test_begin = Instant::now();
|
||||
while test_begin.elapsed().as_millis() < timeout_millis as _ {
|
||||
if let Ok((_, _, display)) = get_current_display() {
|
||||
if let Ok(_) = create_capturer(privacy_mode_id, display) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
std::thread::sleep(Duration::from_millis(300));
|
||||
}
|
||||
false
|
||||
}
|
||||
|
||||
fn run(sp: GenericService) -> ResultType<()> {
|
||||
#[cfg(windows)]
|
||||
ensure_close_virtual_device()?;
|
||||
@ -330,6 +322,10 @@ fn run(sp: GenericService) -> ResultType<()> {
|
||||
);
|
||||
|
||||
let privacy_mode_id = *PRIVACY_MODE_CONN_ID.lock().unwrap();
|
||||
log::debug!(
|
||||
"Try create capturer with privacy mode id {}",
|
||||
privacy_mode_id,
|
||||
);
|
||||
let mut c = create_capturer(privacy_mode_id, display)?;
|
||||
|
||||
let q = get_image_quality();
|
||||
@ -403,6 +399,7 @@ fn run(sp: GenericService) -> ResultType<()> {
|
||||
bail!("SWITCH");
|
||||
}
|
||||
}
|
||||
|
||||
*LAST_ACTIVE.lock().unwrap() = now;
|
||||
|
||||
frame_controller.reset();
|
||||
@ -478,8 +475,17 @@ fn run(sp: GenericService) -> ResultType<()> {
|
||||
_ => {}
|
||||
}
|
||||
|
||||
// i love 3, 6, 8
|
||||
frame_controller.blocking_wait_next(3_000);
|
||||
let mut fetched_conn_ids = HashSet::new();
|
||||
let timeout_millis = 3_000u64;
|
||||
let wait_begin = Instant::now();
|
||||
while wait_begin.elapsed().as_millis() < timeout_millis as _ {
|
||||
check_privacy_mode_changed(&sp, privacy_mode_id)?;
|
||||
frame_controller.try_wait_next(&mut fetched_conn_ids, 300);
|
||||
// break if all connections have received current frame
|
||||
if fetched_conn_ids.len() >= frame_controller.send_conn_ids.len() {
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
let elapsed = now.elapsed();
|
||||
// may need to enable frame(timeout)
|
||||
|
@ -154,7 +154,7 @@ pub fn start() -> ResultType<()> {
|
||||
|
||||
let hwnd = wait_find_privacy_hwnd(1_000)?;
|
||||
if !hwnd.is_null() {
|
||||
log::info!("Privacy window is already created");
|
||||
log::info!("Privacy window is ready");
|
||||
return Ok(());
|
||||
}
|
||||
|
||||
@ -320,9 +320,7 @@ async fn set_privacy_mode_state(
|
||||
state: PrivacyModeState,
|
||||
ms_timeout: u64,
|
||||
) -> ResultType<()> {
|
||||
println!("set_privacy_mode_state begin");
|
||||
let mut c = connect(ms_timeout, "_cm").await?;
|
||||
println!("set_privacy_mode_state connect done");
|
||||
c.send(&Data::PrivacyModeState((conn_id, state))).await
|
||||
}
|
||||
|
||||
|
Loading…
x
Reference in New Issue
Block a user