portable-service: exchange ipc server/client
Signed-off-by: 21pages <pages21@163.com>
This commit is contained in:
parent
e186eec5df
commit
9f73b89f21
@ -429,31 +429,31 @@ impl Connection {
|
||||
_ = second_timer.tick() => {
|
||||
#[cfg(windows)]
|
||||
{
|
||||
use crate::portable_service::client::{PORTABLE_SERVICE_STATUS, PortableServiceStatus::*};
|
||||
let uac = crate::video_service::IS_UAC_RUNNING.lock().unwrap().clone();
|
||||
if last_uac != uac {
|
||||
last_uac = uac;
|
||||
if PORTABLE_SERVICE_STATUS.lock().unwrap().clone() == NotStarted {
|
||||
let mut misc = Misc::new();
|
||||
misc.set_uac(uac);
|
||||
let mut msg = Message::new();
|
||||
msg.set_misc(misc);
|
||||
conn.inner.send(msg.into());
|
||||
}
|
||||
}
|
||||
let foreground_window_elevated = crate::video_service::IS_FOREGROUND_WINDOW_ELEVATED.lock().unwrap().clone();
|
||||
if last_foreground_window_elevated != foreground_window_elevated {
|
||||
last_foreground_window_elevated = foreground_window_elevated;
|
||||
if PORTABLE_SERVICE_STATUS.lock().unwrap().clone() == NotStarted {
|
||||
let mut misc = Misc::new();
|
||||
misc.set_foreground_window_elevated(foreground_window_elevated);
|
||||
let mut msg = Message::new();
|
||||
msg.set_misc(misc);
|
||||
conn.inner.send(msg.into());
|
||||
}
|
||||
}
|
||||
if !is_installed {
|
||||
let show_elevation = PORTABLE_SERVICE_STATUS.lock().unwrap().clone() == NotStarted;
|
||||
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();
|
||||
if last_uac != uac {
|
||||
last_uac = uac;
|
||||
if !portable_service_running {
|
||||
let mut misc = Misc::new();
|
||||
misc.set_uac(uac);
|
||||
let mut msg = Message::new();
|
||||
msg.set_misc(misc);
|
||||
conn.inner.send(msg.into());
|
||||
}
|
||||
}
|
||||
let foreground_window_elevated = crate::video_service::IS_FOREGROUND_WINDOW_ELEVATED.lock().unwrap().clone();
|
||||
if last_foreground_window_elevated != foreground_window_elevated {
|
||||
last_foreground_window_elevated = foreground_window_elevated;
|
||||
if !portable_service_running {
|
||||
let mut misc = Misc::new();
|
||||
misc.set_foreground_window_elevated(foreground_window_elevated);
|
||||
let mut msg = Message::new();
|
||||
msg.set_misc(misc);
|
||||
conn.inner.send(msg.into());
|
||||
}
|
||||
}
|
||||
let show_elevation = !portable_service_running;
|
||||
conn.send_to_cm(ipc::Data::DataPortableService(ipc::DataPortableService::CmShowElevation(show_elevation)));
|
||||
|
||||
}
|
||||
|
@ -7,7 +7,6 @@ use hbb_common::{
|
||||
log,
|
||||
message_proto::{KeyEvent, MouseEvent},
|
||||
protobuf::Message,
|
||||
sleep,
|
||||
tokio::{self, sync::mpsc},
|
||||
ResultType,
|
||||
};
|
||||
@ -17,7 +16,7 @@ use std::{
|
||||
mem::size_of,
|
||||
ops::{Deref, DerefMut},
|
||||
sync::{Arc, Mutex},
|
||||
time::Duration,
|
||||
time::{Duration, Instant},
|
||||
};
|
||||
use winapi::{
|
||||
shared::minwindef::{BOOL, FALSE, TRUE},
|
||||
@ -48,18 +47,6 @@ const ADDR_CAPTURE_FRAME: usize =
|
||||
const IPC_PROFIX: &str = "_portable_service";
|
||||
pub const SHMEM_NAME: &str = "_portable_service";
|
||||
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 {
|
||||
inner: Shmem,
|
||||
@ -200,8 +187,6 @@ mod utils {
|
||||
|
||||
// functions called in seperate SYSTEM user process.
|
||||
pub mod server {
|
||||
use hbb_common::tokio::time::Instant;
|
||||
|
||||
use super::*;
|
||||
|
||||
lazy_static::lazy_static! {
|
||||
@ -220,7 +205,7 @@ pub mod server {
|
||||
run_capture(shmem2);
|
||||
}));
|
||||
threads.push(std::thread::spawn(|| {
|
||||
run_ipc_server();
|
||||
run_ipc_client();
|
||||
}));
|
||||
threads.push(std::thread::spawn(|| {
|
||||
run_exit_check();
|
||||
@ -270,7 +255,7 @@ pub mod server {
|
||||
if EXIT.lock().unwrap().clone() {
|
||||
break;
|
||||
}
|
||||
let start = std::time::Instant::now();
|
||||
let start = Instant::now();
|
||||
unsafe {
|
||||
let para_ptr = shmem.as_ptr().add(ADDR_CAPTURER_PARA);
|
||||
let para = para_ptr as *const CapturerPara;
|
||||
@ -278,7 +263,6 @@ pub mod server {
|
||||
let use_yuv = (*para).use_yuv;
|
||||
let timeout_ms = (*para).timeout_ms;
|
||||
if c.is_none() {
|
||||
let use_yuv = true;
|
||||
*crate::video_service::CURRENT_DISPLAY.lock().unwrap() = current_display;
|
||||
let (_, _current, display) = get_current_display().unwrap();
|
||||
match Capturer::new(display, use_yuv) {
|
||||
@ -348,114 +332,78 @@ pub mod server {
|
||||
}
|
||||
|
||||
#[tokio::main(flavor = "current_thread")]
|
||||
async fn run_ipc_server() {
|
||||
async fn run_ipc_client() {
|
||||
use DataPortableService::*;
|
||||
|
||||
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 {
|
||||
Ok(mut incoming) => loop {
|
||||
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 nack = 0;
|
||||
let mut old_conn_count = 0;
|
||||
loop {
|
||||
tokio::select! {
|
||||
res = stream.next() => {
|
||||
if res.is_ok() {
|
||||
*last_recv_time_cloned.lock().unwrap() = Instant::now();
|
||||
}
|
||||
match res {
|
||||
Err(err) => {
|
||||
log::error!(
|
||||
"ipc{} connection closed: {}",
|
||||
postfix,
|
||||
err
|
||||
);
|
||||
*EXIT.lock().unwrap() = true;
|
||||
break;
|
||||
}
|
||||
Ok(Some(Data::DataPortableService(data))) => match data {
|
||||
Ping => {
|
||||
allow_err!(
|
||||
stream
|
||||
.send(&Data::DataPortableService(Pong))
|
||||
.await
|
||||
);
|
||||
}
|
||||
Pong => {
|
||||
nack = 0;
|
||||
}
|
||||
ConnCount(Some(n)) => {
|
||||
if old_conn_count != 0 && n == 0 {
|
||||
log::info!("Connection count decrease to 0, exit");
|
||||
stream.send(&Data::DataPortableService(WillClose)).await.ok();
|
||||
*EXIT.lock().unwrap() = true;
|
||||
break;
|
||||
}
|
||||
old_conn_count = n;
|
||||
}
|
||||
Mouse(v) => {
|
||||
if let Ok(evt) = MouseEvent::parse_from_bytes(&v) {
|
||||
crate::input_service::handle_mouse_(&evt);
|
||||
}
|
||||
}
|
||||
Key(v) => {
|
||||
if let Ok(evt) = KeyEvent::parse_from_bytes(&v) {
|
||||
crate::input_service::handle_key_(&evt);
|
||||
}
|
||||
}
|
||||
_ => {}
|
||||
},
|
||||
_ => {}
|
||||
}
|
||||
}
|
||||
_ = timer.tick() => {
|
||||
nack+=1;
|
||||
if nack > MAX_NACK {
|
||||
log::info!("max ping nack, exit");
|
||||
*EXIT.lock().unwrap() = true;
|
||||
break;
|
||||
}
|
||||
stream.send(&Data::DataPortableService(Ping)).await.ok();
|
||||
stream.send(&Data::DataPortableService(ConnCount(None))).await.ok();
|
||||
}
|
||||
match ipc::connect(1000, postfix).await {
|
||||
Ok(mut stream) => {
|
||||
let mut timer = tokio::time::interval(Duration::from_secs(1));
|
||||
let mut nack = 0;
|
||||
loop {
|
||||
tokio::select! {
|
||||
res = stream.next() => {
|
||||
match res {
|
||||
Err(err) => {
|
||||
log::error!(
|
||||
"ipc{} connection closed: {}",
|
||||
postfix,
|
||||
err
|
||||
);
|
||||
break;
|
||||
}
|
||||
Ok(Some(Data::DataPortableService(data))) => match data {
|
||||
Ping => {
|
||||
allow_err!(
|
||||
stream
|
||||
.send(&Data::DataPortableService(Pong))
|
||||
.await
|
||||
);
|
||||
}
|
||||
Pong => {
|
||||
nack = 0;
|
||||
}
|
||||
ConnCount(Some(n)) => {
|
||||
if n == 0 {
|
||||
log::info!("Connnection count equals 0, exit");
|
||||
stream.send(&Data::DataPortableService(WillClose)).await.ok();
|
||||
break;
|
||||
}
|
||||
}
|
||||
});
|
||||
}
|
||||
Err(err) => {
|
||||
log::error!("Couldn't get portable client: {:?}", err);
|
||||
*EXIT.lock().unwrap() = true;
|
||||
Mouse(v) => {
|
||||
if let Ok(evt) = MouseEvent::parse_from_bytes(&v) {
|
||||
crate::input_service::handle_mouse_(&evt);
|
||||
}
|
||||
}
|
||||
Key(v) => {
|
||||
if let Ok(evt) = KeyEvent::parse_from_bytes(&v) {
|
||||
crate::input_service::handle_key_(&evt);
|
||||
}
|
||||
}
|
||||
_ => {}
|
||||
},
|
||||
_ => {}
|
||||
}
|
||||
}
|
||||
}
|
||||
_ = 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;
|
||||
_ = timer.tick() => {
|
||||
nack+=1;
|
||||
if nack > MAX_NACK {
|
||||
log::info!("max ping nack, exit");
|
||||
break;
|
||||
}
|
||||
stream.send(&Data::DataPortableService(Ping)).await.ok();
|
||||
stream.send(&Data::DataPortableService(ConnCount(None))).await.ok();
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
Err(err) => {
|
||||
log::error!("Failed to start cm ipc server: {}", err);
|
||||
*EXIT.lock().unwrap() = true;
|
||||
}
|
||||
Err(e) => {
|
||||
log::error!("Failed to connect portable service ipc:{:?}", e);
|
||||
}
|
||||
}
|
||||
|
||||
*EXIT.lock().unwrap() = true;
|
||||
}
|
||||
}
|
||||
|
||||
@ -466,54 +414,46 @@ pub mod client {
|
||||
use super::*;
|
||||
|
||||
lazy_static::lazy_static! {
|
||||
pub static ref SHMEM: Arc<Mutex<Option<SharedMemory>>> = Default::default();
|
||||
pub static ref PORTABLE_SERVICE_STATUS: Arc<Mutex<PortableServiceStatus>> = Default::default();
|
||||
static ref SENDER : Mutex<mpsc::UnboundedSender<ipc::Data>> = Mutex::new(client::start_ipc_client());
|
||||
}
|
||||
|
||||
#[derive(Debug, Clone, Copy, PartialEq, Eq)]
|
||||
pub enum PortableServiceStatus {
|
||||
NotStarted,
|
||||
Starting,
|
||||
Running,
|
||||
}
|
||||
|
||||
impl Default for PortableServiceStatus {
|
||||
fn default() -> Self {
|
||||
Self::NotStarted
|
||||
}
|
||||
pub static ref PORTABLE_SERVICE_RUNNING: Arc<Mutex<bool>> = Default::default();
|
||||
static ref SHMEM: Arc<Mutex<Option<SharedMemory>>> = Default::default();
|
||||
static ref SENDER : Mutex<mpsc::UnboundedSender<ipc::Data>> = Mutex::new(client::start_ipc_server());
|
||||
}
|
||||
|
||||
pub(crate) fn start_portable_service() -> ResultType<()> {
|
||||
if PORTABLE_SERVICE_STATUS.lock().unwrap().clone() == PortableServiceStatus::NotStarted {
|
||||
if SHMEM.lock().unwrap().is_none() {
|
||||
let displays = scrap::Display::all()?;
|
||||
if displays.is_empty() {
|
||||
bail!("no display available!");
|
||||
}
|
||||
let mut max_pixel = 0;
|
||||
let align = 64;
|
||||
for d in displays {
|
||||
let pixel = utils::align(d.width(), align) * utils::align(d.height(), align);
|
||||
if max_pixel < pixel {
|
||||
max_pixel = pixel;
|
||||
}
|
||||
}
|
||||
let shmem_size = utils::align(ADDR_CAPTURE_FRAME + max_pixel * 4, align);
|
||||
// os error 112, no enough space
|
||||
*SHMEM.lock().unwrap() = Some(crate::portable_service::SharedMemory::create(
|
||||
crate::portable_service::SHMEM_NAME,
|
||||
shmem_size,
|
||||
)?);
|
||||
shutdown_hooks::add_shutdown_hook(drop_shmem);
|
||||
}
|
||||
if crate::common::run_me(vec!["--portable-service"]).is_err() {
|
||||
*SHMEM.lock().unwrap() = None;
|
||||
bail!("Failed to run portable service process");
|
||||
}
|
||||
*PORTABLE_SERVICE_STATUS.lock().unwrap() = PortableServiceStatus::Starting;
|
||||
let _sender = SENDER.lock().unwrap();
|
||||
if PORTABLE_SERVICE_RUNNING.lock().unwrap().clone() {
|
||||
bail!("already running");
|
||||
}
|
||||
if SHMEM.lock().unwrap().is_none() {
|
||||
let displays = scrap::Display::all()?;
|
||||
if displays.is_empty() {
|
||||
bail!("no display available!");
|
||||
}
|
||||
let mut max_pixel = 0;
|
||||
let align = 64;
|
||||
for d in displays {
|
||||
let pixel = utils::align(d.width(), align) * utils::align(d.height(), align);
|
||||
if max_pixel < pixel {
|
||||
max_pixel = pixel;
|
||||
}
|
||||
}
|
||||
let shmem_size = utils::align(ADDR_CAPTURE_FRAME + max_pixel * 4, align);
|
||||
// os error 112, no enough space
|
||||
*SHMEM.lock().unwrap() = Some(crate::portable_service::SharedMemory::create(
|
||||
crate::portable_service::SHMEM_NAME,
|
||||
shmem_size,
|
||||
)?);
|
||||
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() {
|
||||
*SHMEM.lock().unwrap() = None;
|
||||
bail!("Failed to run portable service process");
|
||||
}
|
||||
let _sender = SENDER.lock().unwrap();
|
||||
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>();
|
||||
std::thread::spawn(move || start_ipc_client_async(rx));
|
||||
std::thread::spawn(move || start_ipc_server_async(rx));
|
||||
tx
|
||||
}
|
||||
|
||||
#[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::*;
|
||||
let mut rx = rx;
|
||||
let mut connect_failed = 0;
|
||||
loop {
|
||||
if PORTABLE_SERVICE_STATUS.lock().unwrap().clone() == PortableServiceStatus::NotStarted
|
||||
{
|
||||
sleep(1.).await;
|
||||
continue;
|
||||
}
|
||||
if let Ok(mut c) = ipc::connect(1000, IPC_PROFIX).await {
|
||||
let mut nack = 0;
|
||||
let mut timer = tokio::time::interval(Duration::from_secs(1));
|
||||
loop {
|
||||
tokio::select! {
|
||||
res = c.next() => {
|
||||
match res {
|
||||
Err(err) => {
|
||||
log::error!("ipc connection closed: {}", err);
|
||||
break;
|
||||
}
|
||||
Ok(Some(Data::DataPortableService(data))) => {
|
||||
match data {
|
||||
Ping => {
|
||||
c.send(&Data::DataPortableService(Pong)).await.ok();
|
||||
}
|
||||
Pong => {
|
||||
nack = 0;
|
||||
*PORTABLE_SERVICE_STATUS.lock().unwrap() = PortableServiceStatus::Running;
|
||||
},
|
||||
ConnCount(None) => {
|
||||
let cnt = crate::server::CONN_COUNT.lock().unwrap().clone();
|
||||
c.send(&Data::DataPortableService(ConnCount(Some(cnt)))).await.ok();
|
||||
},
|
||||
WillClose => {
|
||||
log::info!("portable service will close, set status to not started");
|
||||
*PORTABLE_SERVICE_STATUS.lock().unwrap() = PortableServiceStatus::NotStarted;
|
||||
break;
|
||||
}
|
||||
_=>{}
|
||||
}
|
||||
}
|
||||
_ => {}
|
||||
}
|
||||
}
|
||||
_ = timer.tick() => {
|
||||
nack+=1;
|
||||
if nack > 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");
|
||||
*PORTABLE_SERVICE_STATUS.lock().unwrap() = PortableServiceStatus::NotStarted;
|
||||
break;
|
||||
}
|
||||
c.send(&Data::DataPortableService(Ping)).await.ok();
|
||||
}
|
||||
Some(data) = rx.recv() => {
|
||||
allow_err!(c.send(&data).await);
|
||||
}
|
||||
let rx = Arc::new(tokio::sync::Mutex::new(rx));
|
||||
let postfix = IPC_PROFIX;
|
||||
|
||||
match new_listener(postfix).await {
|
||||
Ok(mut incoming) => loop {
|
||||
{
|
||||
tokio::select! {
|
||||
Some(result) = incoming.next() => {
|
||||
match result {
|
||||
Ok(stream) => {
|
||||
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 nack = 0;
|
||||
let mut rx = rx_clone.lock().await;
|
||||
loop {
|
||||
tokio::select! {
|
||||
res = stream.next() => {
|
||||
match res {
|
||||
Err(err) => {
|
||||
log::info!(
|
||||
"ipc{} connection closed: {}",
|
||||
postfix,
|
||||
err
|
||||
);
|
||||
break;
|
||||
}
|
||||
Ok(Some(Data::DataPortableService(data))) => match data {
|
||||
Ping => {
|
||||
stream.send(&Data::DataPortableService(Pong)).await.ok();
|
||||
}
|
||||
Pong => {
|
||||
nack = 0;
|
||||
*PORTABLE_SERVICE_RUNNING.lock().unwrap() = true;
|
||||
},
|
||||
ConnCount(None) => {
|
||||
let cnt = crate::server::CONN_COUNT.lock().unwrap().clone();
|
||||
stream.send(&Data::DataPortableService(ConnCount(Some(cnt)))).await.ok();
|
||||
},
|
||||
WillClose => {
|
||||
log::info!("portable service will close");
|
||||
break;
|
||||
}
|
||||
_=>{}
|
||||
}
|
||||
_=>{}
|
||||
}
|
||||
}
|
||||
_ = timer.tick() => {
|
||||
nack+=1;
|
||||
if nack > MAX_NACK {
|
||||
// In fact, this will not happen, ipc will be closed before max nack.
|
||||
log::error!("max ipc nack");
|
||||
break;
|
||||
}
|
||||
stream.send(&Data::DataPortableService(Ping)).await.ok();
|
||||
}
|
||||
Some(data) = rx.recv() => {
|
||||
allow_err!(stream.send(&data).await);
|
||||
}
|
||||
}
|
||||
}
|
||||
*PORTABLE_SERVICE_RUNNING.lock().unwrap() = false;
|
||||
});
|
||||
}
|
||||
Err(err) => {
|
||||
log::error!("Couldn't get portable client: {:?}", err);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
} 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!(
|
||||
"client ip connect failed, status:{:?}",
|
||||
PORTABLE_SERVICE_STATUS.lock().unwrap().clone(),
|
||||
);
|
||||
},
|
||||
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();
|
||||
sender
|
||||
.send(data)
|
||||
@ -721,21 +665,25 @@ pub mod client {
|
||||
fn handle_mouse_(evt: &MouseEvent) -> ResultType<()> {
|
||||
let mut v = vec![];
|
||||
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<()> {
|
||||
let mut v = vec![];
|
||||
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(
|
||||
current_display: usize,
|
||||
display: scrap::Display,
|
||||
use_yuv: bool,
|
||||
portable_service_running: bool,
|
||||
) -> 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");
|
||||
return Ok(Box::new(CapturerPortable::new(current_display, use_yuv)));
|
||||
} else {
|
||||
@ -747,7 +695,7 @@ pub mod client {
|
||||
}
|
||||
|
||||
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)
|
||||
} else {
|
||||
unsafe { winuser::GetCursorInfo(pci) }
|
||||
@ -755,7 +703,7 @@ pub mod client {
|
||||
}
|
||||
|
||||
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();
|
||||
} else {
|
||||
crate::input_service::handle_mouse_(evt);
|
||||
@ -763,7 +711,7 @@ pub mod client {
|
||||
}
|
||||
|
||||
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();
|
||||
} else {
|
||||
crate::input_service::handle_key_(evt);
|
||||
|
@ -20,7 +20,7 @@
|
||||
|
||||
use super::{video_qos::VideoQoS, *};
|
||||
#[cfg(windows)]
|
||||
use crate::portable_service::client::{PortableServiceStatus, PORTABLE_SERVICE_STATUS};
|
||||
use crate::portable_service::client::PORTABLE_SERVICE_RUNNING;
|
||||
use hbb_common::tokio::sync::{
|
||||
mpsc::{unbounded_channel, UnboundedReceiver, UnboundedSender},
|
||||
Mutex as TokioMutex,
|
||||
@ -191,6 +191,7 @@ fn create_capturer(
|
||||
display: Display,
|
||||
use_yuv: bool,
|
||||
current: usize,
|
||||
_portable_service_running: bool,
|
||||
) -> ResultType<Box<dyn TraitCapturer>> {
|
||||
#[cfg(not(windows))]
|
||||
let c: Option<Box<dyn TraitCapturer>> = None;
|
||||
@ -252,7 +253,12 @@ fn create_capturer(
|
||||
None => {
|
||||
log::debug!("Create capturer dxgi|gdi");
|
||||
#[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))]
|
||||
return Ok(Box::new(
|
||||
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();
|
||||
while test_begin.elapsed().as_millis() < timeout_millis as _ {
|
||||
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;
|
||||
}
|
||||
}
|
||||
@ -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")]
|
||||
{
|
||||
if !scrap::is_x11() {
|
||||
@ -373,7 +379,13 @@ fn get_capturer(use_yuv: bool) -> ResultType<CapturerInfo> {
|
||||
} else {
|
||||
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 {
|
||||
origin,
|
||||
width,
|
||||
@ -393,8 +405,12 @@ fn run(sp: GenericService) -> ResultType<()> {
|
||||
// ensure_inited() is needed because release_resouce() may be called.
|
||||
#[cfg(target_os = "linux")]
|
||||
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();
|
||||
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();
|
||||
#[cfg(windows)]
|
||||
start_uac_elevation_check();
|
||||
#[cfg(windows)]
|
||||
let portable_service_status = crate::portable_service::client::PORTABLE_SERVICE_STATUS
|
||||
.lock()
|
||||
.unwrap()
|
||||
.clone();
|
||||
|
||||
#[cfg(target_os = "linux")]
|
||||
let mut would_block_count = 0u32;
|
||||
@ -508,15 +519,14 @@ fn run(sp: GenericService) -> ResultType<()> {
|
||||
bail!("SWITCH");
|
||||
}
|
||||
#[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");
|
||||
}
|
||||
check_privacy_mode_changed(&sp, c.privacy_mode_id)?;
|
||||
#[cfg(windows)]
|
||||
{
|
||||
if crate::platform::windows::desktop_changed()
|
||||
&& PORTABLE_SERVICE_STATUS.lock().unwrap().clone()
|
||||
== PortableServiceStatus::NotStarted
|
||||
&& !PORTABLE_SERVICE_RUNNING.lock().unwrap().clone()
|
||||
{
|
||||
bail!("Desktop changed");
|
||||
}
|
||||
|
@ -770,11 +770,11 @@ fn cm_inner_send(id: i32, data: Data) {
|
||||
pub fn can_elevate() -> bool {
|
||||
#[cfg(windows)]
|
||||
{
|
||||
use crate::portable_service::client::{
|
||||
PortableServiceStatus::NotStarted, PORTABLE_SERVICE_STATUS,
|
||||
};
|
||||
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))]
|
||||
return false;
|
||||
|
Loading…
Reference in New Issue
Block a user