android video service wakelock

Signed-off-by: 21pages <pages21@163.com>
This commit is contained in:
21pages 2023-11-23 19:47:16 +08:00
parent c6ace470e3
commit bd81e4d0fb
7 changed files with 87 additions and 9 deletions

13
Cargo.lock generated
View File

@ -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",

View File

@ -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"]

View File

@ -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")

View File

@ -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"

View File

@ -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))
}

View File

@ -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 {

View File

@ -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![]