android video service wakelock
Signed-off-by: 21pages <pages21@163.com>
This commit is contained in:
parent
c6ace470e3
commit
bd81e4d0fb
13
Cargo.lock
generated
13
Cargo.lock
generated
@ -121,6 +121,17 @@ version = "0.1.1"
|
|||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "e999941b234f3131b00bc13c22d06e8c5ff726d1b6318ac7eb276997bbb4fef0"
|
checksum = "e999941b234f3131b00bc13c22d06e8c5ff726d1b6318ac7eb276997bbb4fef0"
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "android-wakelock"
|
||||||
|
version = "0.1.0"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "296e5b7c23adb32743194b1810604b772f2be10f0b0387365cb3ba09cd5c1851"
|
||||||
|
dependencies = [
|
||||||
|
"jni 0.21.1",
|
||||||
|
"log",
|
||||||
|
"ndk-context",
|
||||||
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "android_log-sys"
|
name = "android_log-sys"
|
||||||
version = "0.3.1"
|
version = "0.3.1"
|
||||||
@ -5197,6 +5208,7 @@ dependencies = [
|
|||||||
name = "rustdesk"
|
name = "rustdesk"
|
||||||
version = "1.2.4"
|
version = "1.2.4"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
|
"android-wakelock",
|
||||||
"android_logger",
|
"android_logger",
|
||||||
"arboard",
|
"arboard",
|
||||||
"async-process",
|
"async-process",
|
||||||
@ -5487,6 +5499,7 @@ dependencies = [
|
|||||||
"lazy_static",
|
"lazy_static",
|
||||||
"log",
|
"log",
|
||||||
"ndk",
|
"ndk",
|
||||||
|
"ndk-context",
|
||||||
"num_cpus",
|
"num_cpus",
|
||||||
"pkg-config",
|
"pkg-config",
|
||||||
"quest",
|
"quest",
|
||||||
|
@ -147,6 +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"
|
||||||
|
|
||||||
[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"]
|
||||||
|
@ -211,6 +211,7 @@ class MainService : Service() {
|
|||||||
override fun onCreate() {
|
override fun onCreate() {
|
||||||
super.onCreate()
|
super.onCreate()
|
||||||
Log.d(logTag,"MainService onCreate")
|
Log.d(logTag,"MainService onCreate")
|
||||||
|
init(this)
|
||||||
HandlerThread("Service", Process.THREAD_PRIORITY_BACKGROUND).apply {
|
HandlerThread("Service", Process.THREAD_PRIORITY_BACKGROUND).apply {
|
||||||
start()
|
start()
|
||||||
serviceLooper = looper
|
serviceLooper = looper
|
||||||
@ -315,7 +316,6 @@ class MainService : Service() {
|
|||||||
mediaProjection =
|
mediaProjection =
|
||||||
mediaProjectionManager.getMediaProjection(Activity.RESULT_OK, it)
|
mediaProjectionManager.getMediaProjection(Activity.RESULT_OK, it)
|
||||||
checkMediaPermission()
|
checkMediaPermission()
|
||||||
init(this)
|
|
||||||
_isReady = true
|
_isReady = true
|
||||||
} ?: let {
|
} ?: let {
|
||||||
Log.d(logTag, "getParcelableExtra intent null, invoke requestMediaProjection")
|
Log.d(logTag, "getParcelableExtra intent null, invoke requestMediaProjection")
|
||||||
|
@ -36,6 +36,7 @@ lazy_static = "1.4"
|
|||||||
log = "0.4"
|
log = "0.4"
|
||||||
serde_json = "1.0"
|
serde_json = "1.0"
|
||||||
ndk = { version = "0.7", features = ["media"], optional = true}
|
ndk = { version = "0.7", features = ["media"], optional = true}
|
||||||
|
ndk-context = "0.1"
|
||||||
|
|
||||||
[target.'cfg(not(target_os = "android"))'.dev-dependencies]
|
[target.'cfg(not(target_os = "android"))'.dev-dependencies]
|
||||||
repng = "0.2"
|
repng = "0.2"
|
||||||
|
@ -19,6 +19,7 @@ lazy_static! {
|
|||||||
static ref MAIN_SERVICE_CTX: RwLock<Option<GlobalRef>> = RwLock::new(None); // MainService -> video service / audio service / info
|
static ref MAIN_SERVICE_CTX: RwLock<Option<GlobalRef>> = RwLock::new(None); // MainService -> video service / audio service / info
|
||||||
static ref VIDEO_RAW: Mutex<FrameRaw> = Mutex::new(FrameRaw::new("video", MAX_VIDEO_FRAME_TIMEOUT));
|
static ref VIDEO_RAW: Mutex<FrameRaw> = Mutex::new(FrameRaw::new("video", MAX_VIDEO_FRAME_TIMEOUT));
|
||||||
static ref AUDIO_RAW: Mutex<FrameRaw> = Mutex::new(FrameRaw::new("audio", MAX_AUDIO_FRAME_TIMEOUT));
|
static ref AUDIO_RAW: Mutex<FrameRaw> = Mutex::new(FrameRaw::new("audio", MAX_AUDIO_FRAME_TIMEOUT));
|
||||||
|
static ref NDK_CONTEXT_INITED: Mutex<bool> = Default::default();
|
||||||
}
|
}
|
||||||
|
|
||||||
const MAX_VIDEO_FRAME_TIMEOUT: Duration = Duration::from_millis(100);
|
const MAX_VIDEO_FRAME_TIMEOUT: Duration = Duration::from_millis(100);
|
||||||
@ -150,6 +151,7 @@ pub extern "system" fn Java_com_carriez_flutter_1hbb_MainService_init(
|
|||||||
*JVM.write().unwrap() = Some(jvm);
|
*JVM.write().unwrap() = Some(jvm);
|
||||||
if let Ok(context) = env.new_global_ref(ctx) {
|
if let Ok(context) = env.new_global_ref(ctx) {
|
||||||
*MAIN_SERVICE_CTX.write().unwrap() = Some(context);
|
*MAIN_SERVICE_CTX.write().unwrap() = Some(context);
|
||||||
|
init_ndk_context().ok();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -165,7 +167,12 @@ pub fn call_main_service_pointer_input(kind: &str, mask: i32, x: i32, y: i32) ->
|
|||||||
ctx,
|
ctx,
|
||||||
"rustPointerInput",
|
"rustPointerInput",
|
||||||
"(Ljava/lang/String;III)V",
|
"(Ljava/lang/String;III)V",
|
||||||
&[JValue::Object(&JObject::from(kind)), JValue::Int(mask), JValue::Int(x), JValue::Int(y)],
|
&[
|
||||||
|
JValue::Object(&JObject::from(kind)),
|
||||||
|
JValue::Int(mask),
|
||||||
|
JValue::Int(x),
|
||||||
|
JValue::Int(y),
|
||||||
|
],
|
||||||
)?;
|
)?;
|
||||||
return Ok(());
|
return Ok(());
|
||||||
} else {
|
} else {
|
||||||
@ -246,3 +253,26 @@ pub fn call_main_service_set_by_name(
|
|||||||
return Err(JniError::ThrowFailed(-1));
|
return Err(JniError::ThrowFailed(-1));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fn init_ndk_context() -> JniResult<()> {
|
||||||
|
let mut lock = NDK_CONTEXT_INITED.lock().unwrap();
|
||||||
|
if *lock {
|
||||||
|
unsafe {
|
||||||
|
ndk_context::release_android_context();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if let (Some(jvm), Some(ctx)) = (
|
||||||
|
JVM.read().unwrap().as_ref(),
|
||||||
|
MAIN_SERVICE_CTX.read().unwrap().as_ref(),
|
||||||
|
) {
|
||||||
|
unsafe {
|
||||||
|
ndk_context::initialize_android_context(
|
||||||
|
jvm.get_java_vm_pointer() as _,
|
||||||
|
ctx.as_obj().as_raw() as _,
|
||||||
|
);
|
||||||
|
}
|
||||||
|
*lock = true;
|
||||||
|
return Ok(());
|
||||||
|
}
|
||||||
|
Err(JniError::ThrowFailed(-1))
|
||||||
|
}
|
||||||
|
@ -80,6 +80,39 @@ pub fn get_active_username() -> String {
|
|||||||
#[cfg(target_os = "android")]
|
#[cfg(target_os = "android")]
|
||||||
pub const PA_SAMPLE_RATE: u32 = 48000;
|
pub const PA_SAMPLE_RATE: u32 = 48000;
|
||||||
|
|
||||||
|
#[cfg(target_os = "android")]
|
||||||
|
#[derive(Default)]
|
||||||
|
pub struct WakeLock {
|
||||||
|
lock: 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) },
|
||||||
|
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(crate) struct InstallingService; // please use new
|
pub(crate) struct InstallingService; // please use new
|
||||||
|
|
||||||
impl InstallingService {
|
impl InstallingService {
|
||||||
|
@ -363,8 +363,12 @@ fn get_capturer(current: usize, portable_service_running: bool) -> ResultType<Ca
|
|||||||
}
|
}
|
||||||
|
|
||||||
fn run(vs: VideoService) -> ResultType<()> {
|
fn run(vs: VideoService) -> ResultType<()> {
|
||||||
#[cfg(not(any(target_os = "android", target_os = "ios")))]
|
#[cfg(not(target_os = "android"))]
|
||||||
let _wake_lock = get_wake_lock();
|
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.
|
||||||
//
|
//
|
||||||
@ -619,7 +623,6 @@ fn get_recorder(
|
|||||||
height: usize,
|
height: usize,
|
||||||
codec_name: &CodecName,
|
codec_name: &CodecName,
|
||||||
) -> Arc<Mutex<Option<Recorder>>> {
|
) -> Arc<Mutex<Option<Recorder>>> {
|
||||||
#[cfg(not(target_os = "ios"))]
|
|
||||||
let recorder = if !Config::get_option("allow-auto-record-incoming").is_empty() {
|
let recorder = if !Config::get_option("allow-auto-record-incoming").is_empty() {
|
||||||
use crate::hbbs_http::record_upload;
|
use crate::hbbs_http::record_upload;
|
||||||
|
|
||||||
@ -644,8 +647,6 @@ fn get_recorder(
|
|||||||
} else {
|
} else {
|
||||||
Default::default()
|
Default::default()
|
||||||
};
|
};
|
||||||
#[cfg(target_os = "ios")]
|
|
||||||
let recorder: Arc<Mutex<Option<Recorder>>> = Default::default();
|
|
||||||
|
|
||||||
recorder
|
recorder
|
||||||
}
|
}
|
||||||
@ -690,7 +691,6 @@ fn handle_one_frame(
|
|||||||
vf.display = display as _;
|
vf.display = display as _;
|
||||||
let mut msg = Message::new();
|
let mut msg = Message::new();
|
||||||
msg.set_video_frame(vf);
|
msg.set_video_frame(vf);
|
||||||
#[cfg(not(target_os = "ios"))]
|
|
||||||
recorder
|
recorder
|
||||||
.lock()
|
.lock()
|
||||||
.unwrap()
|
.unwrap()
|
||||||
@ -735,7 +735,7 @@ fn start_uac_elevation_check() {
|
|||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
#[cfg(not(any(target_os = "android", target_os = "ios")))]
|
#[cfg(not(target_os = "android"))]
|
||||||
fn get_wake_lock() -> crate::platform::WakeLock {
|
fn get_wake_lock() -> crate::platform::WakeLock {
|
||||||
let (display, idle, sleep) = if cfg!(windows) {
|
let (display, idle, sleep) = if cfg!(windows) {
|
||||||
(true, false, false)
|
(true, false, false)
|
||||||
@ -784,7 +784,7 @@ pub fn make_display_changed_msg(
|
|||||||
width: display.width,
|
width: display.width,
|
||||||
height: display.height,
|
height: display.height,
|
||||||
cursor_embedded: display_service::capture_cursor_embedded(),
|
cursor_embedded: display_service::capture_cursor_embedded(),
|
||||||
#[cfg(not(any(target_os = "android", target_os = "ios")))]
|
#[cfg(not(target_os = "android"))]
|
||||||
resolutions: Some(SupportedResolutions {
|
resolutions: Some(SupportedResolutions {
|
||||||
resolutions: if display.name.is_empty() {
|
resolutions: if display.name.is_empty() {
|
||||||
vec![]
|
vec![]
|
||||||
|
Loading…
x
Reference in New Issue
Block a user