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"
|
||||
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]]
|
||||
name = "android_log-sys"
|
||||
version = "0.3.1"
|
||||
@ -5197,6 +5208,7 @@ dependencies = [
|
||||
name = "rustdesk"
|
||||
version = "1.2.4"
|
||||
dependencies = [
|
||||
"android-wakelock",
|
||||
"android_logger",
|
||||
"arboard",
|
||||
"async-process",
|
||||
@ -5487,6 +5499,7 @@ dependencies = [
|
||||
"lazy_static",
|
||||
"log",
|
||||
"ndk",
|
||||
"ndk-context",
|
||||
"num_cpus",
|
||||
"pkg-config",
|
||||
"quest",
|
||||
|
@ -147,6 +147,7 @@ once_cell = {version = "1.18", optional = true}
|
||||
[target.'cfg(target_os = "android")'.dependencies]
|
||||
android_logger = "0.13"
|
||||
jni = "0.21"
|
||||
android-wakelock = "0.1"
|
||||
|
||||
[workspace]
|
||||
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() {
|
||||
super.onCreate()
|
||||
Log.d(logTag,"MainService onCreate")
|
||||
init(this)
|
||||
HandlerThread("Service", Process.THREAD_PRIORITY_BACKGROUND).apply {
|
||||
start()
|
||||
serviceLooper = looper
|
||||
@ -315,7 +316,6 @@ class MainService : Service() {
|
||||
mediaProjection =
|
||||
mediaProjectionManager.getMediaProjection(Activity.RESULT_OK, it)
|
||||
checkMediaPermission()
|
||||
init(this)
|
||||
_isReady = true
|
||||
} ?: let {
|
||||
Log.d(logTag, "getParcelableExtra intent null, invoke requestMediaProjection")
|
||||
|
@ -36,6 +36,7 @@ lazy_static = "1.4"
|
||||
log = "0.4"
|
||||
serde_json = "1.0"
|
||||
ndk = { version = "0.7", features = ["media"], optional = true}
|
||||
ndk-context = "0.1"
|
||||
|
||||
[target.'cfg(not(target_os = "android"))'.dev-dependencies]
|
||||
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 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 NDK_CONTEXT_INITED: Mutex<bool> = Default::default();
|
||||
}
|
||||
|
||||
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);
|
||||
if let Ok(context) = env.new_global_ref(ctx) {
|
||||
*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,
|
||||
"rustPointerInput",
|
||||
"(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(());
|
||||
} else {
|
||||
@ -246,3 +253,26 @@ pub fn call_main_service_set_by_name(
|
||||
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")]
|
||||
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
|
||||
|
||||
impl InstallingService {
|
||||
|
@ -363,8 +363,12 @@ fn get_capturer(current: usize, portable_service_running: bool) -> ResultType<Ca
|
||||
}
|
||||
|
||||
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();
|
||||
#[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.
|
||||
//
|
||||
@ -619,7 +623,6 @@ fn get_recorder(
|
||||
height: usize,
|
||||
codec_name: &CodecName,
|
||||
) -> Arc<Mutex<Option<Recorder>>> {
|
||||
#[cfg(not(target_os = "ios"))]
|
||||
let recorder = if !Config::get_option("allow-auto-record-incoming").is_empty() {
|
||||
use crate::hbbs_http::record_upload;
|
||||
|
||||
@ -644,8 +647,6 @@ fn get_recorder(
|
||||
} else {
|
||||
Default::default()
|
||||
};
|
||||
#[cfg(target_os = "ios")]
|
||||
let recorder: Arc<Mutex<Option<Recorder>>> = Default::default();
|
||||
|
||||
recorder
|
||||
}
|
||||
@ -690,7 +691,6 @@ fn handle_one_frame(
|
||||
vf.display = display as _;
|
||||
let mut msg = Message::new();
|
||||
msg.set_video_frame(vf);
|
||||
#[cfg(not(target_os = "ios"))]
|
||||
recorder
|
||||
.lock()
|
||||
.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 {
|
||||
let (display, idle, sleep) = if cfg!(windows) {
|
||||
(true, false, false)
|
||||
@ -784,7 +784,7 @@ pub fn make_display_changed_msg(
|
||||
width: display.width,
|
||||
height: display.height,
|
||||
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: if display.name.is_empty() {
|
||||
vec![]
|
||||
|
Loading…
Reference in New Issue
Block a user