portable-service: exchange ipc server/client

Signed-off-by: 21pages <pages21@163.com>
This commit is contained in:
21pages 2022-11-11 11:40:23 +08:00
parent e186eec5df
commit 9f73b89f21
4 changed files with 239 additions and 281 deletions

View File

@ -429,11 +429,12 @@ impl Connection {
_ = second_timer.tick() => { _ = second_timer.tick() => {
#[cfg(windows)] #[cfg(windows)]
{ {
use crate::portable_service::client::{PORTABLE_SERVICE_STATUS, PortableServiceStatus::*}; if !is_installed {
let portable_service_running = crate::portable_service::client::PORTABLE_SERVICE_RUNNING.lock().unwrap().clone();
let uac = crate::video_service::IS_UAC_RUNNING.lock().unwrap().clone(); let uac = crate::video_service::IS_UAC_RUNNING.lock().unwrap().clone();
if last_uac != uac { if last_uac != uac {
last_uac = uac; last_uac = uac;
if PORTABLE_SERVICE_STATUS.lock().unwrap().clone() == NotStarted { if !portable_service_running {
let mut misc = Misc::new(); let mut misc = Misc::new();
misc.set_uac(uac); misc.set_uac(uac);
let mut msg = Message::new(); let mut msg = Message::new();
@ -444,7 +445,7 @@ impl Connection {
let foreground_window_elevated = crate::video_service::IS_FOREGROUND_WINDOW_ELEVATED.lock().unwrap().clone(); let foreground_window_elevated = crate::video_service::IS_FOREGROUND_WINDOW_ELEVATED.lock().unwrap().clone();
if last_foreground_window_elevated != foreground_window_elevated { if last_foreground_window_elevated != foreground_window_elevated {
last_foreground_window_elevated = foreground_window_elevated; last_foreground_window_elevated = foreground_window_elevated;
if PORTABLE_SERVICE_STATUS.lock().unwrap().clone() == NotStarted { if !portable_service_running {
let mut misc = Misc::new(); let mut misc = Misc::new();
misc.set_foreground_window_elevated(foreground_window_elevated); misc.set_foreground_window_elevated(foreground_window_elevated);
let mut msg = Message::new(); let mut msg = Message::new();
@ -452,8 +453,7 @@ impl Connection {
conn.inner.send(msg.into()); conn.inner.send(msg.into());
} }
} }
if !is_installed { let show_elevation = !portable_service_running;
let show_elevation = PORTABLE_SERVICE_STATUS.lock().unwrap().clone() == NotStarted;
conn.send_to_cm(ipc::Data::DataPortableService(ipc::DataPortableService::CmShowElevation(show_elevation))); conn.send_to_cm(ipc::Data::DataPortableService(ipc::DataPortableService::CmShowElevation(show_elevation)));
} }

View File

@ -7,7 +7,6 @@ use hbb_common::{
log, log,
message_proto::{KeyEvent, MouseEvent}, message_proto::{KeyEvent, MouseEvent},
protobuf::Message, protobuf::Message,
sleep,
tokio::{self, sync::mpsc}, tokio::{self, sync::mpsc},
ResultType, ResultType,
}; };
@ -17,7 +16,7 @@ use std::{
mem::size_of, mem::size_of,
ops::{Deref, DerefMut}, ops::{Deref, DerefMut},
sync::{Arc, Mutex}, sync::{Arc, Mutex},
time::Duration, time::{Duration, Instant},
}; };
use winapi::{ use winapi::{
shared::minwindef::{BOOL, FALSE, TRUE}, shared::minwindef::{BOOL, FALSE, TRUE},
@ -48,18 +47,6 @@ const ADDR_CAPTURE_FRAME: usize =
const IPC_PROFIX: &str = "_portable_service"; const IPC_PROFIX: &str = "_portable_service";
pub const SHMEM_NAME: &str = "_portable_service"; pub const SHMEM_NAME: &str = "_portable_service";
const MAX_NACK: usize = 3; const MAX_NACK: usize = 3;
const IPC_CONN_TIMEOUT: Duration = Duration::from_secs(3);
pub enum PortableServiceStatus {
NonStart,
Running,
}
impl Default for PortableServiceStatus {
fn default() -> Self {
Self::NonStart
}
}
pub struct SharedMemory { pub struct SharedMemory {
inner: Shmem, inner: Shmem,
@ -200,8 +187,6 @@ mod utils {
// functions called in seperate SYSTEM user process. // functions called in seperate SYSTEM user process.
pub mod server { pub mod server {
use hbb_common::tokio::time::Instant;
use super::*; use super::*;
lazy_static::lazy_static! { lazy_static::lazy_static! {
@ -220,7 +205,7 @@ pub mod server {
run_capture(shmem2); run_capture(shmem2);
})); }));
threads.push(std::thread::spawn(|| { threads.push(std::thread::spawn(|| {
run_ipc_server(); run_ipc_client();
})); }));
threads.push(std::thread::spawn(|| { threads.push(std::thread::spawn(|| {
run_exit_check(); run_exit_check();
@ -270,7 +255,7 @@ pub mod server {
if EXIT.lock().unwrap().clone() { if EXIT.lock().unwrap().clone() {
break; break;
} }
let start = std::time::Instant::now(); let start = Instant::now();
unsafe { unsafe {
let para_ptr = shmem.as_ptr().add(ADDR_CAPTURER_PARA); let para_ptr = shmem.as_ptr().add(ADDR_CAPTURER_PARA);
let para = para_ptr as *const CapturerPara; let para = para_ptr as *const CapturerPara;
@ -278,7 +263,6 @@ pub mod server {
let use_yuv = (*para).use_yuv; let use_yuv = (*para).use_yuv;
let timeout_ms = (*para).timeout_ms; let timeout_ms = (*para).timeout_ms;
if c.is_none() { if c.is_none() {
let use_yuv = true;
*crate::video_service::CURRENT_DISPLAY.lock().unwrap() = current_display; *crate::video_service::CURRENT_DISPLAY.lock().unwrap() = current_display;
let (_, _current, display) = get_current_display().unwrap(); let (_, _current, display) = get_current_display().unwrap();
match Capturer::new(display, use_yuv) { match Capturer::new(display, use_yuv) {
@ -348,33 +332,18 @@ pub mod server {
} }
#[tokio::main(flavor = "current_thread")] #[tokio::main(flavor = "current_thread")]
async fn run_ipc_server() { async fn run_ipc_client() {
use DataPortableService::*; use DataPortableService::*;
let postfix = IPC_PROFIX; let postfix = IPC_PROFIX;
let last_recv_time = Arc::new(Mutex::new(Instant::now()));
let mut interval = tokio::time::interval(Duration::from_secs(1));
match new_listener(postfix).await { match ipc::connect(1000, postfix).await {
Ok(mut incoming) => loop { Ok(mut stream) => {
tokio::select! {
Some(result) = incoming.next() => {
match result {
Ok(stream) => {
log::info!("Got new connection");
let last_recv_time_cloned = last_recv_time.clone();
tokio::spawn(async move {
let mut stream = Connection::new(stream);
let postfix = postfix.to_owned();
let mut timer = tokio::time::interval(Duration::from_secs(1)); let mut timer = tokio::time::interval(Duration::from_secs(1));
let mut nack = 0; let mut nack = 0;
let mut old_conn_count = 0;
loop { loop {
tokio::select! { tokio::select! {
res = stream.next() => { res = stream.next() => {
if res.is_ok() {
*last_recv_time_cloned.lock().unwrap() = Instant::now();
}
match res { match res {
Err(err) => { Err(err) => {
log::error!( log::error!(
@ -382,7 +351,6 @@ pub mod server {
postfix, postfix,
err err
); );
*EXIT.lock().unwrap() = true;
break; break;
} }
Ok(Some(Data::DataPortableService(data))) => match data { Ok(Some(Data::DataPortableService(data))) => match data {
@ -397,13 +365,11 @@ pub mod server {
nack = 0; nack = 0;
} }
ConnCount(Some(n)) => { ConnCount(Some(n)) => {
if old_conn_count != 0 && n == 0 { if n == 0 {
log::info!("Connection count decrease to 0, exit"); log::info!("Connnection count equals 0, exit");
stream.send(&Data::DataPortableService(WillClose)).await.ok(); stream.send(&Data::DataPortableService(WillClose)).await.ok();
*EXIT.lock().unwrap() = true;
break; break;
} }
old_conn_count = n;
} }
Mouse(v) => { Mouse(v) => {
if let Ok(evt) = MouseEvent::parse_from_bytes(&v) { if let Ok(evt) = MouseEvent::parse_from_bytes(&v) {
@ -424,7 +390,6 @@ pub mod server {
nack+=1; nack+=1;
if nack > MAX_NACK { if nack > MAX_NACK {
log::info!("max ping nack, exit"); log::info!("max ping nack, exit");
*EXIT.lock().unwrap() = true;
break; break;
} }
stream.send(&Data::DataPortableService(Ping)).await.ok(); stream.send(&Data::DataPortableService(Ping)).await.ok();
@ -432,31 +397,14 @@ pub mod server {
} }
} }
} }
});
} }
Err(err) => { Err(e) => {
log::error!("Couldn't get portable client: {:?}", err); log::error!("Failed to connect portable service ipc:{:?}", e);
}
}
*EXIT.lock().unwrap() = true; *EXIT.lock().unwrap() = true;
} }
}
}
_ = interval.tick() => {
if last_recv_time.lock().unwrap().elapsed() > IPC_CONN_TIMEOUT {
log::error!("receive data timeout");
*EXIT.lock().unwrap() = true;
}
if EXIT.lock().unwrap().clone() {
break;
}
}
}
},
Err(err) => {
log::error!("Failed to start cm ipc server: {}", err);
*EXIT.lock().unwrap() = true;
}
}
}
} }
// functions called in main process. // functions called in main process.
@ -466,26 +414,15 @@ pub mod client {
use super::*; use super::*;
lazy_static::lazy_static! { lazy_static::lazy_static! {
pub static ref SHMEM: Arc<Mutex<Option<SharedMemory>>> = Default::default(); pub static ref PORTABLE_SERVICE_RUNNING: Arc<Mutex<bool>> = Default::default();
pub static ref PORTABLE_SERVICE_STATUS: Arc<Mutex<PortableServiceStatus>> = Default::default(); static ref SHMEM: Arc<Mutex<Option<SharedMemory>>> = Default::default();
static ref SENDER : Mutex<mpsc::UnboundedSender<ipc::Data>> = Mutex::new(client::start_ipc_client()); static ref SENDER : Mutex<mpsc::UnboundedSender<ipc::Data>> = Mutex::new(client::start_ipc_server());
}
#[derive(Debug, Clone, Copy, PartialEq, Eq)]
pub enum PortableServiceStatus {
NotStarted,
Starting,
Running,
}
impl Default for PortableServiceStatus {
fn default() -> Self {
Self::NotStarted
}
} }
pub(crate) fn start_portable_service() -> ResultType<()> { pub(crate) fn start_portable_service() -> ResultType<()> {
if PORTABLE_SERVICE_STATUS.lock().unwrap().clone() == PortableServiceStatus::NotStarted { if PORTABLE_SERVICE_RUNNING.lock().unwrap().clone() {
bail!("already running");
}
if SHMEM.lock().unwrap().is_none() { if SHMEM.lock().unwrap().is_none() {
let displays = scrap::Display::all()?; let displays = scrap::Display::all()?;
if displays.is_empty() { if displays.is_empty() {
@ -507,13 +444,16 @@ pub mod client {
)?); )?);
shutdown_hooks::add_shutdown_hook(drop_shmem); shutdown_hooks::add_shutdown_hook(drop_shmem);
} }
let mut option = SHMEM.lock().unwrap();
let shmem = option.as_mut().unwrap();
unsafe {
libc::memset(shmem.as_ptr() as _, 0, shmem.len() as _);
}
if crate::common::run_me(vec!["--portable-service"]).is_err() { if crate::common::run_me(vec!["--portable-service"]).is_err() {
*SHMEM.lock().unwrap() = None; *SHMEM.lock().unwrap() = None;
bail!("Failed to run portable service process"); bail!("Failed to run portable service process");
} }
*PORTABLE_SERVICE_STATUS.lock().unwrap() = PortableServiceStatus::Starting;
let _sender = SENDER.lock().unwrap(); let _sender = SENDER.lock().unwrap();
}
Ok(()) Ok(())
} }
@ -613,94 +553,98 @@ pub mod client {
} }
} }
pub(super) fn start_ipc_client() -> mpsc::UnboundedSender<Data> { pub(super) fn start_ipc_server() -> mpsc::UnboundedSender<Data> {
let (tx, rx) = mpsc::unbounded_channel::<Data>(); let (tx, rx) = mpsc::unbounded_channel::<Data>();
std::thread::spawn(move || start_ipc_client_async(rx)); std::thread::spawn(move || start_ipc_server_async(rx));
tx tx
} }
#[tokio::main(flavor = "current_thread")] #[tokio::main(flavor = "current_thread")]
async fn start_ipc_client_async(rx: mpsc::UnboundedReceiver<Data>) { async fn start_ipc_server_async(rx: mpsc::UnboundedReceiver<Data>) {
use DataPortableService::*; use DataPortableService::*;
let mut rx = rx; let rx = Arc::new(tokio::sync::Mutex::new(rx));
let mut connect_failed = 0; let postfix = IPC_PROFIX;
loop {
if PORTABLE_SERVICE_STATUS.lock().unwrap().clone() == PortableServiceStatus::NotStarted match new_listener(postfix).await {
Ok(mut incoming) => loop {
{ {
sleep(1.).await; tokio::select! {
continue; Some(result) = incoming.next() => {
} match result {
if let Ok(mut c) = ipc::connect(1000, IPC_PROFIX).await { Ok(stream) => {
let mut nack = 0; log::info!("Got portable service ipc connection");
let rx_clone = rx.clone();
tokio::spawn(async move {
let mut stream = Connection::new(stream);
let postfix = postfix.to_owned();
let mut timer = tokio::time::interval(Duration::from_secs(1)); let mut timer = tokio::time::interval(Duration::from_secs(1));
let mut nack = 0;
let mut rx = rx_clone.lock().await;
loop { loop {
tokio::select! { tokio::select! {
res = c.next() => { res = stream.next() => {
match res { match res {
Err(err) => { Err(err) => {
log::error!("ipc connection closed: {}", err); log::info!(
"ipc{} connection closed: {}",
postfix,
err
);
break; break;
} }
Ok(Some(Data::DataPortableService(data))) => { Ok(Some(Data::DataPortableService(data))) => match data {
match data {
Ping => { Ping => {
c.send(&Data::DataPortableService(Pong)).await.ok(); stream.send(&Data::DataPortableService(Pong)).await.ok();
} }
Pong => { Pong => {
nack = 0; nack = 0;
*PORTABLE_SERVICE_STATUS.lock().unwrap() = PortableServiceStatus::Running; *PORTABLE_SERVICE_RUNNING.lock().unwrap() = true;
}, },
ConnCount(None) => { ConnCount(None) => {
let cnt = crate::server::CONN_COUNT.lock().unwrap().clone(); let cnt = crate::server::CONN_COUNT.lock().unwrap().clone();
c.send(&Data::DataPortableService(ConnCount(Some(cnt)))).await.ok(); stream.send(&Data::DataPortableService(ConnCount(Some(cnt)))).await.ok();
}, },
WillClose => { WillClose => {
log::info!("portable service will close, set status to not started"); log::info!("portable service will close");
*PORTABLE_SERVICE_STATUS.lock().unwrap() = PortableServiceStatus::NotStarted;
break; break;
} }
_=>{} _=>{}
} }
} _=>{}
_ => {}
} }
} }
_ = timer.tick() => { _ = timer.tick() => {
nack+=1; nack+=1;
if nack > MAX_NACK { if nack > MAX_NACK {
// In fact, this will not happen, ipc will be closed before max nack. // In fact, this will not happen, ipc will be closed before max nack.
log::error!("max ipc nack, set status to not started"); log::error!("max ipc nack");
*PORTABLE_SERVICE_STATUS.lock().unwrap() = PortableServiceStatus::NotStarted;
break; break;
} }
c.send(&Data::DataPortableService(Ping)).await.ok(); stream.send(&Data::DataPortableService(Ping)).await.ok();
} }
Some(data) = rx.recv() => { Some(data) = rx.recv() => {
allow_err!(c.send(&data).await); allow_err!(stream.send(&data).await);
}
} }
} }
} else {
connect_failed += 1;
if connect_failed > IPC_CONN_TIMEOUT.as_secs() {
connect_failed = 0;
*PORTABLE_SERVICE_STATUS.lock().unwrap() = PortableServiceStatus::NotStarted;
log::info!(
"connect failed {} times, set status to not started",
connect_failed
);
} }
log::info!( *PORTABLE_SERVICE_RUNNING.lock().unwrap() = false;
"client ip connect failed, status:{:?}", });
PORTABLE_SERVICE_STATUS.lock().unwrap().clone(), }
); Err(err) => {
log::error!("Couldn't get portable client: {:?}", err);
}
}
}
}
}
},
Err(err) => {
log::error!("Failed to start portable service ipc server: {}", err);
} }
sleep(1.).await;
} }
} }
fn client_ipc_send(data: Data) -> ResultType<()> { fn ipc_send(data: Data) -> ResultType<()> {
let sender = SENDER.lock().unwrap(); let sender = SENDER.lock().unwrap();
sender sender
.send(data) .send(data)
@ -721,21 +665,25 @@ pub mod client {
fn handle_mouse_(evt: &MouseEvent) -> ResultType<()> { fn handle_mouse_(evt: &MouseEvent) -> ResultType<()> {
let mut v = vec![]; let mut v = vec![];
evt.write_to_vec(&mut v)?; evt.write_to_vec(&mut v)?;
client_ipc_send(Data::DataPortableService(DataPortableService::Mouse(v))) ipc_send(Data::DataPortableService(DataPortableService::Mouse(v)))
} }
fn handle_key_(evt: &KeyEvent) -> ResultType<()> { fn handle_key_(evt: &KeyEvent) -> ResultType<()> {
let mut v = vec![]; let mut v = vec![];
evt.write_to_vec(&mut v)?; evt.write_to_vec(&mut v)?;
client_ipc_send(Data::DataPortableService(DataPortableService::Key(v))) ipc_send(Data::DataPortableService(DataPortableService::Key(v)))
} }
pub fn create_capturer( pub fn create_capturer(
current_display: usize, current_display: usize,
display: scrap::Display, display: scrap::Display,
use_yuv: bool, use_yuv: bool,
portable_service_running: bool,
) -> ResultType<Box<dyn TraitCapturer>> { ) -> ResultType<Box<dyn TraitCapturer>> {
if PORTABLE_SERVICE_STATUS.lock().unwrap().clone() == PortableServiceStatus::Running { if portable_service_running != PORTABLE_SERVICE_RUNNING.lock().unwrap().clone() {
log::info!("portable service status mismatch");
}
if portable_service_running {
log::info!("Create shared memeory capturer"); log::info!("Create shared memeory capturer");
return Ok(Box::new(CapturerPortable::new(current_display, use_yuv))); return Ok(Box::new(CapturerPortable::new(current_display, use_yuv)));
} else { } else {
@ -747,7 +695,7 @@ pub mod client {
} }
pub fn get_cursor_info(pci: PCURSORINFO) -> BOOL { pub fn get_cursor_info(pci: PCURSORINFO) -> BOOL {
if PORTABLE_SERVICE_STATUS.lock().unwrap().clone() == PortableServiceStatus::Running { if PORTABLE_SERVICE_RUNNING.lock().unwrap().clone() {
get_cursor_info_(&mut SHMEM.lock().unwrap().as_mut().unwrap(), pci) get_cursor_info_(&mut SHMEM.lock().unwrap().as_mut().unwrap(), pci)
} else { } else {
unsafe { winuser::GetCursorInfo(pci) } unsafe { winuser::GetCursorInfo(pci) }
@ -755,7 +703,7 @@ pub mod client {
} }
pub fn handle_mouse(evt: &MouseEvent) { pub fn handle_mouse(evt: &MouseEvent) {
if PORTABLE_SERVICE_STATUS.lock().unwrap().clone() == PortableServiceStatus::Running { if PORTABLE_SERVICE_RUNNING.lock().unwrap().clone() {
handle_mouse_(evt).ok(); handle_mouse_(evt).ok();
} else { } else {
crate::input_service::handle_mouse_(evt); crate::input_service::handle_mouse_(evt);
@ -763,7 +711,7 @@ pub mod client {
} }
pub fn handle_key(evt: &KeyEvent) { pub fn handle_key(evt: &KeyEvent) {
if PORTABLE_SERVICE_STATUS.lock().unwrap().clone() == PortableServiceStatus::Running { if PORTABLE_SERVICE_RUNNING.lock().unwrap().clone() {
handle_key_(evt).ok(); handle_key_(evt).ok();
} else { } else {
crate::input_service::handle_key_(evt); crate::input_service::handle_key_(evt);

View File

@ -20,7 +20,7 @@
use super::{video_qos::VideoQoS, *}; use super::{video_qos::VideoQoS, *};
#[cfg(windows)] #[cfg(windows)]
use crate::portable_service::client::{PortableServiceStatus, PORTABLE_SERVICE_STATUS}; use crate::portable_service::client::PORTABLE_SERVICE_RUNNING;
use hbb_common::tokio::sync::{ use hbb_common::tokio::sync::{
mpsc::{unbounded_channel, UnboundedReceiver, UnboundedSender}, mpsc::{unbounded_channel, UnboundedReceiver, UnboundedSender},
Mutex as TokioMutex, Mutex as TokioMutex,
@ -191,6 +191,7 @@ fn create_capturer(
display: Display, display: Display,
use_yuv: bool, use_yuv: bool,
current: usize, current: usize,
_portable_service_running: bool,
) -> ResultType<Box<dyn TraitCapturer>> { ) -> ResultType<Box<dyn TraitCapturer>> {
#[cfg(not(windows))] #[cfg(not(windows))]
let c: Option<Box<dyn TraitCapturer>> = None; let c: Option<Box<dyn TraitCapturer>> = None;
@ -252,7 +253,12 @@ fn create_capturer(
None => { None => {
log::debug!("Create capturer dxgi|gdi"); log::debug!("Create capturer dxgi|gdi");
#[cfg(windows)] #[cfg(windows)]
return crate::portable_service::client::create_capturer(current, display, use_yuv); return crate::portable_service::client::create_capturer(
current,
display,
use_yuv,
_portable_service_running,
);
#[cfg(not(windows))] #[cfg(not(windows))]
return Ok(Box::new( return Ok(Box::new(
Capturer::new(display, use_yuv).with_context(|| "Failed to create capturer")?, Capturer::new(display, use_yuv).with_context(|| "Failed to create capturer")?,
@ -282,7 +288,7 @@ pub fn test_create_capturer(privacy_mode_id: i32, timeout_millis: u64) -> bool {
let test_begin = Instant::now(); let test_begin = Instant::now();
while test_begin.elapsed().as_millis() < timeout_millis as _ { while test_begin.elapsed().as_millis() < timeout_millis as _ {
if let Ok((_, current, display)) = get_current_display() { if let Ok((_, current, display)) = get_current_display() {
if let Ok(_) = create_capturer(privacy_mode_id, display, true, current) { if let Ok(_) = create_capturer(privacy_mode_id, display, true, current, false) {
return true; return true;
} }
} }
@ -331,7 +337,7 @@ impl DerefMut for CapturerInfo {
} }
} }
fn get_capturer(use_yuv: bool) -> ResultType<CapturerInfo> { fn get_capturer(use_yuv: bool, portable_service_running: bool) -> ResultType<CapturerInfo> {
#[cfg(target_os = "linux")] #[cfg(target_os = "linux")]
{ {
if !scrap::is_x11() { if !scrap::is_x11() {
@ -373,7 +379,13 @@ fn get_capturer(use_yuv: bool) -> ResultType<CapturerInfo> {
} else { } else {
log::info!("In privacy mode, the peer side cannot watch the screen"); log::info!("In privacy mode, the peer side cannot watch the screen");
} }
let capturer = create_capturer(captuerer_privacy_mode_id, display, use_yuv, current)?; let capturer = create_capturer(
captuerer_privacy_mode_id,
display,
use_yuv,
current,
portable_service_running,
)?;
Ok(CapturerInfo { Ok(CapturerInfo {
origin, origin,
width, width,
@ -393,8 +405,12 @@ fn run(sp: GenericService) -> ResultType<()> {
// ensure_inited() is needed because release_resouce() may be called. // ensure_inited() is needed because release_resouce() may be called.
#[cfg(target_os = "linux")] #[cfg(target_os = "linux")]
super::wayland::ensure_inited()?; super::wayland::ensure_inited()?;
#[cfg(windows)]
let last_portable_service_running = PORTABLE_SERVICE_RUNNING.lock().unwrap().clone();
#[cfg(not(windows))]
let last_portable_service_running = false;
let mut c = get_capturer(true)?; let mut c = get_capturer(true, last_portable_service_running)?;
let mut video_qos = VIDEO_QOS.lock().unwrap(); let mut video_qos = VIDEO_QOS.lock().unwrap();
video_qos.set_size(c.width as _, c.height as _); video_qos.set_size(c.width as _, c.height as _);
@ -472,11 +488,6 @@ fn run(sp: GenericService) -> ResultType<()> {
let recorder: Arc<Mutex<Option<Recorder>>> = Default::default(); let recorder: Arc<Mutex<Option<Recorder>>> = Default::default();
#[cfg(windows)] #[cfg(windows)]
start_uac_elevation_check(); start_uac_elevation_check();
#[cfg(windows)]
let portable_service_status = crate::portable_service::client::PORTABLE_SERVICE_STATUS
.lock()
.unwrap()
.clone();
#[cfg(target_os = "linux")] #[cfg(target_os = "linux")]
let mut would_block_count = 0u32; let mut would_block_count = 0u32;
@ -508,15 +519,14 @@ fn run(sp: GenericService) -> ResultType<()> {
bail!("SWITCH"); bail!("SWITCH");
} }
#[cfg(windows)] #[cfg(windows)]
if portable_service_status != PORTABLE_SERVICE_STATUS.lock().unwrap().clone() { if last_portable_service_running != PORTABLE_SERVICE_RUNNING.lock().unwrap().clone() {
bail!("SWITCH"); bail!("SWITCH");
} }
check_privacy_mode_changed(&sp, c.privacy_mode_id)?; check_privacy_mode_changed(&sp, c.privacy_mode_id)?;
#[cfg(windows)] #[cfg(windows)]
{ {
if crate::platform::windows::desktop_changed() if crate::platform::windows::desktop_changed()
&& PORTABLE_SERVICE_STATUS.lock().unwrap().clone() && !PORTABLE_SERVICE_RUNNING.lock().unwrap().clone()
== PortableServiceStatus::NotStarted
{ {
bail!("Desktop changed"); bail!("Desktop changed");
} }

View File

@ -770,11 +770,11 @@ fn cm_inner_send(id: i32, data: Data) {
pub fn can_elevate() -> bool { pub fn can_elevate() -> bool {
#[cfg(windows)] #[cfg(windows)]
{ {
use crate::portable_service::client::{
PortableServiceStatus::NotStarted, PORTABLE_SERVICE_STATUS,
};
return !crate::platform::is_installed() return !crate::platform::is_installed()
&& PORTABLE_SERVICE_STATUS.lock().unwrap().clone() == NotStarted; && !crate::portable_service::client::PORTABLE_SERVICE_RUNNING
.lock()
.unwrap()
.clone();
} }
#[cfg(not(windows))] #[cfg(not(windows))]
return false; return false;