diff --git a/Cargo.lock b/Cargo.lock index 4588765b317..9ccee76fa66 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -101,7 +101,7 @@ dependencies = [ "bitflags 2.5.0", "cc", "cesu8", - "jni 0.21.1", + "jni", "jni-sys", "libc", "log", @@ -3119,20 +3119,6 @@ dependencies = [ "libc", ] -[[package]] -name = "jni" -version = "0.18.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "24967112a1e4301ca5342ea339763613a37592b8a6ce6cf2e4494537c7a42faf" -dependencies = [ - "cesu8", - "combine", - "jni-sys", - "log", - "thiserror", - "walkdir", -] - [[package]] name = "jni" version = "0.21.1" @@ -5727,7 +5713,7 @@ dependencies = [ "getopts", "gl_generator", "ipc-channel", - "jni 0.18.0", + "jni", "libc", "libloading 0.8.3", "libservo", diff --git a/ports/jniapi/Cargo.toml b/ports/jniapi/Cargo.toml index c8fa1f4e8cd..b89fdb73f69 100644 --- a/ports/jniapi/Cargo.toml +++ b/ports/jniapi/Cargo.toml @@ -17,7 +17,7 @@ bench = false android_logger = "0.13" getopts = { workspace = true } ipc-channel = { workspace = true } -jni = "0.18.0" +jni = "0.21.1" libc = { workspace = true } libloading = "0.8" libservo = { path = "../../components/servo" } diff --git a/ports/jniapi/src/lib.rs b/ports/jniapi/src/lib.rs index 917788466e2..c912762917b 100644 --- a/ports/jniapi/src/lib.rs +++ b/ports/jniapi/src/lib.rs @@ -13,8 +13,8 @@ use std::sync::Arc; use std::thread; use android_logger::{self, Config, FilterBuilder}; -use jni::objects::{GlobalRef, JClass, JObject, JString, JValue}; -use jni::sys::{jboolean, jfloat, jint, jstring, JNI_TRUE}; +use jni::objects::{GlobalRef, JClass, JObject, JString, JValue, JValueOwned}; +use jni::sys::{jboolean, jfloat, jint, jobject, jstring, JNI_TRUE}; use jni::{JNIEnv, JavaVM}; use libc::{dup2, pipe, read}; use log::{debug, error, info, warn}; @@ -29,7 +29,7 @@ struct HostCallbacks { } extern "C" { - fn ANativeWindow_fromSurface(env: *mut jni::sys::JNIEnv, surface: JObject) -> *mut c_void; + fn ANativeWindow_fromSurface(env: *mut jni::sys::JNIEnv, surface: jobject) -> *mut c_void; } #[no_mangle] @@ -41,7 +41,7 @@ pub extern "C" fn android_main() { // this currently. } -fn call(env: &JNIEnv, f: F) +fn call(env: &mut JNIEnv, f: F) where F: Fn(&mut ServoGlue) -> Result<(), &str>, { @@ -56,27 +56,28 @@ where } #[no_mangle] -pub extern "C" fn Java_org_mozilla_servoview_JNIServo_version( - env: JNIEnv, - _class: JClass, -) -> jstring { +pub extern "C" fn Java_org_mozilla_servoview_JNIServo_version<'local>( + mut env: JNIEnv<'local>, + _class: JClass<'local>, +) -> JString<'local> { let v = simpleservo::servo_version(); - new_string(&env, &v).unwrap_or_else(|null| null) + env.new_string(&v) + .unwrap_or_else(|_str| JObject::null().into()) } #[no_mangle] -pub extern "C" fn Java_org_mozilla_servoview_JNIServo_init( - env: JNIEnv, - _: JClass, - _activity: JObject, - opts: JObject, - callbacks_obj: JObject, - surface: JObject, +pub extern "C" fn Java_org_mozilla_servoview_JNIServo_init<'local>( + mut env: JNIEnv<'local>, + _: JClass<'local>, + _activity: JObject<'local>, + opts: JObject<'local>, + callbacks_obj: JObject<'local>, + surface: JObject<'local>, ) { - let (opts, log, log_str, _gst_debug_str) = match get_options(&env, opts, surface) { + let (opts, log, log_str, _gst_debug_str) = match get_options(&mut env, &opts, &surface) { Ok((opts, log, log_str, gst_debug_str)) => (opts, log, log_str, gst_debug_str), Err(err) => { - throw(&env, &err); + throw(&mut env, &err); return; }, }; @@ -122,7 +123,10 @@ pub extern "C" fn Java_org_mozilla_servoview_JNIServo_init( let callbacks_ref = match env.new_global_ref(callbacks_obj) { Ok(r) => r, Err(_) => { - throw(&env, "Failed to get global reference of callback argument"); + throw( + &mut env, + "Failed to get global reference of callback argument", + ); return; }, }; @@ -133,270 +137,301 @@ pub extern "C" fn Java_org_mozilla_servoview_JNIServo_init( if let Err(err) = gl_glue::egl::init() .and_then(|egl_init| simpleservo::init(opts, egl_init.gl_wrapper, wakeup, callbacks)) { - throw(&env, err) + throw(&mut env, err) }; } #[no_mangle] -pub extern "C" fn Java_org_mozilla_servoview_JNIServo_setBatchMode( - env: JNIEnv, - _: JClass, +pub extern "C" fn Java_org_mozilla_servoview_JNIServo_setBatchMode<'local>( + mut env: JNIEnv<'local>, + _: JClass<'local>, batch: jboolean, ) { debug!("setBatchMode"); - call(&env, |s| s.set_batch_mode(batch == JNI_TRUE)); + call(&mut env, |s| s.set_batch_mode(batch == JNI_TRUE)); } #[no_mangle] -pub extern "C" fn Java_org_mozilla_servoview_JNIServo_requestShutdown(env: JNIEnv, _class: JClass) { +pub extern "C" fn Java_org_mozilla_servoview_JNIServo_requestShutdown<'local>( + mut env: JNIEnv<'local>, + _class: JClass<'local>, +) { debug!("requestShutdown"); - call(&env, |s| s.request_shutdown()); + call(&mut env, |s| s.request_shutdown()); } #[no_mangle] -pub extern "C" fn Java_org_mozilla_servoview_JNIServo_deinit(_env: JNIEnv, _class: JClass) { +pub extern "C" fn Java_org_mozilla_servoview_JNIServo_deinit<'local>( + _env: JNIEnv<'local>, + _class: JClass<'local>, +) { debug!("deinit"); simpleservo::deinit(); } #[no_mangle] -pub extern "C" fn Java_org_mozilla_servoview_JNIServo_resize( - env: JNIEnv, - _: JClass, - coordinates: JObject, +pub extern "C" fn Java_org_mozilla_servoview_JNIServo_resize<'local>( + mut env: JNIEnv<'local>, + _: JClass<'local>, + coordinates: JObject<'local>, ) { - let coords = jni_coords_to_rust_coords(&env, coordinates); + let coords = jni_coords_to_rust_coords(&mut env, &coordinates); debug!("resize {:#?}", coords); match coords { - Ok(coords) => call(&env, |s| s.resize(coords.clone())), - Err(error) => throw(&env, &error), + Ok(coords) => call(&mut env, |s| s.resize(coords.clone())), + Err(error) => throw(&mut env, &error), } } #[no_mangle] -pub extern "C" fn Java_org_mozilla_servoview_JNIServo_performUpdates(env: JNIEnv, _class: JClass) { +pub extern "C" fn Java_org_mozilla_servoview_JNIServo_performUpdates<'local>( + mut env: JNIEnv<'local>, + _class: JClass<'local>, +) { debug!("performUpdates"); - call(&env, |s| s.perform_updates()); + call(&mut env, |s| s.perform_updates()); } #[no_mangle] -pub extern "C" fn Java_org_mozilla_servoview_JNIServo_loadUri( - env: JNIEnv, - _class: JClass, - url: JString, +pub extern "C" fn Java_org_mozilla_servoview_JNIServo_loadUri<'local>( + mut env: JNIEnv<'local>, + _class: JClass<'local>, + url: JString<'local>, ) { debug!("loadUri"); - match env.get_string(url) { + match env.get_string(&url) { Ok(url) => { let url: String = url.into(); - call(&env, |s| s.load_uri(&url)); + call(&mut env, |s| s.load_uri(&url)); }, Err(_) => { - throw(&env, "Failed to convert Java string"); + throw(&mut env, "Failed to convert Java string"); }, }; } #[no_mangle] -pub extern "C" fn Java_org_mozilla_servoview_JNIServo_reload(env: JNIEnv, _class: JClass) { +pub extern "C" fn Java_org_mozilla_servoview_JNIServo_reload<'local>( + mut env: JNIEnv<'local>, + _class: JClass<'local>, +) { debug!("reload"); - call(&env, |s| s.reload()); + call(&mut env, |s| s.reload()); } #[no_mangle] -pub extern "C" fn Java_org_mozilla_servoview_JNIServo_stop(env: JNIEnv, _class: JClass) { +pub extern "C" fn Java_org_mozilla_servoview_JNIServo_stop<'local>( + mut env: JNIEnv<'local>, + _class: JClass<'local>, +) { debug!("stop"); - call(&env, |s| s.stop()); + call(&mut env, |s| s.stop()); } #[no_mangle] -pub extern "C" fn Java_org_mozilla_servoview_JNIServo_refresh(env: JNIEnv, _class: JClass) { +pub extern "C" fn Java_org_mozilla_servoview_JNIServo_refresh<'local>( + mut env: JNIEnv<'local>, + _class: JClass<'local>, +) { debug!("refresh"); - call(&env, |s| s.refresh()); + call(&mut env, |s| s.refresh()); } #[no_mangle] -pub extern "C" fn Java_org_mozilla_servoview_JNIServo_goBack(env: JNIEnv, _class: JClass) { +pub extern "C" fn Java_org_mozilla_servoview_JNIServo_goBack<'local>( + mut env: JNIEnv<'local>, + _class: JClass<'local>, +) { debug!("goBack"); - call(&env, |s| s.go_back()); + call(&mut env, |s| s.go_back()); } #[no_mangle] -pub extern "C" fn Java_org_mozilla_servoview_JNIServo_goForward(env: JNIEnv, _class: JClass) { +pub extern "C" fn Java_org_mozilla_servoview_JNIServo_goForward<'local>( + mut env: JNIEnv<'local>, + _class: JClass<'local>, +) { debug!("goForward"); - call(&env, |s| s.go_forward()); + call(&mut env, |s| s.go_forward()); } #[no_mangle] -pub extern "C" fn Java_org_mozilla_servoview_JNIServo_scrollStart( - env: JNIEnv, - _: JClass, +pub extern "C" fn Java_org_mozilla_servoview_JNIServo_scrollStart<'local>( + mut env: JNIEnv<'local>, + _: JClass<'local>, dx: jint, dy: jint, x: jint, y: jint, ) { debug!("scrollStart"); - call(&env, |s| { + call(&mut env, |s| { s.scroll_start(dx as f32, dy as f32, x as i32, y as i32) }); } #[no_mangle] -pub extern "C" fn Java_org_mozilla_servoview_JNIServo_scrollEnd( - env: JNIEnv, - _: JClass, +pub extern "C" fn Java_org_mozilla_servoview_JNIServo_scrollEnd<'local>( + mut env: JNIEnv<'local>, + _: JClass<'local>, dx: jint, dy: jint, x: jint, y: jint, ) { debug!("scrollEnd"); - call(&env, |s| { + call(&mut env, |s| { s.scroll_end(dx as f32, dy as f32, x as i32, y as i32) }); } #[no_mangle] -pub extern "C" fn Java_org_mozilla_servoview_JNIServo_scroll( - env: JNIEnv, - _: JClass, +pub extern "C" fn Java_org_mozilla_servoview_JNIServo_scroll<'local>( + mut env: JNIEnv<'local>, + _: JClass<'local>, dx: jint, dy: jint, x: jint, y: jint, ) { debug!("scroll"); - call(&env, |s| s.scroll(dx as f32, dy as f32, x as i32, y as i32)); + call(&mut env, |s| { + s.scroll(dx as f32, dy as f32, x as i32, y as i32) + }); } #[no_mangle] -pub extern "C" fn Java_org_mozilla_servoview_JNIServo_touchDown( - env: JNIEnv, - _: JClass, +pub extern "C" fn Java_org_mozilla_servoview_JNIServo_touchDown<'local>( + mut env: JNIEnv<'local>, + _: JClass<'local>, x: jfloat, y: jfloat, pointer_id: jint, ) { debug!("touchDown"); - call(&env, |s| s.touch_down(x, y, pointer_id as i32)); + call(&mut env, |s| s.touch_down(x, y, pointer_id as i32)); } #[no_mangle] -pub extern "C" fn Java_org_mozilla_servoview_JNIServo_touchUp( - env: JNIEnv, - _: JClass, +pub extern "C" fn Java_org_mozilla_servoview_JNIServo_touchUp<'local>( + mut env: JNIEnv<'local>, + _: JClass<'local>, x: jfloat, y: jfloat, pointer_id: jint, ) { debug!("touchUp"); - call(&env, |s| s.touch_up(x, y, pointer_id as i32)); + call(&mut env, |s| s.touch_up(x, y, pointer_id as i32)); } #[no_mangle] -pub extern "C" fn Java_org_mozilla_servoview_JNIServo_touchMove( - env: JNIEnv, - _: JClass, +pub extern "C" fn Java_org_mozilla_servoview_JNIServo_touchMove<'local>( + mut env: JNIEnv<'local>, + _: JClass<'local>, x: jfloat, y: jfloat, pointer_id: jint, ) { debug!("touchMove"); - call(&env, |s| s.touch_move(x, y, pointer_id as i32)); + call(&mut env, |s| s.touch_move(x, y, pointer_id as i32)); } #[no_mangle] -pub extern "C" fn Java_org_mozilla_servoview_JNIServo_touchCancel( - env: JNIEnv, - _: JClass, +pub extern "C" fn Java_org_mozilla_servoview_JNIServo_touchCancel<'local>( + mut env: JNIEnv<'local>, + _: JClass<'local>, x: jfloat, y: jfloat, pointer_id: jint, ) { debug!("touchCancel"); - call(&env, |s| s.touch_cancel(x, y, pointer_id as i32)); + call(&mut env, |s| s.touch_cancel(x, y, pointer_id as i32)); } #[no_mangle] -pub extern "C" fn Java_org_mozilla_servoview_JNIServo_pinchZoomStart( - env: JNIEnv, - _: JClass, +pub extern "C" fn Java_org_mozilla_servoview_JNIServo_pinchZoomStart<'local>( + mut env: JNIEnv<'local>, + _: JClass<'local>, factor: jfloat, x: jint, y: jint, ) { debug!("pinchZoomStart"); - call(&env, |s| { + call(&mut env, |s| { s.pinchzoom_start(factor as f32, x as u32, y as u32) }); } #[no_mangle] -pub extern "C" fn Java_org_mozilla_servoview_JNIServo_pinchZoom( - env: JNIEnv, - _: JClass, +pub extern "C" fn Java_org_mozilla_servoview_JNIServo_pinchZoom<'local>( + mut env: JNIEnv<'local>, + _: JClass<'local>, factor: jfloat, x: jint, y: jint, ) { debug!("pinchZoom"); - call(&env, |s| s.pinchzoom(factor as f32, x as u32, y as u32)); + call(&mut env, |s| s.pinchzoom(factor as f32, x as u32, y as u32)); } #[no_mangle] -pub extern "C" fn Java_org_mozilla_servoview_JNIServo_pinchZoomEnd( - env: JNIEnv, - _: JClass, +pub extern "C" fn Java_org_mozilla_servoview_JNIServo_pinchZoomEnd<'local>( + mut env: JNIEnv<'local>, + _: JClass<'local>, factor: jfloat, x: jint, y: jint, ) { debug!("pinchZoomEnd"); - call(&env, |s| s.pinchzoom_end(factor as f32, x as u32, y as u32)); + call(&mut env, |s| { + s.pinchzoom_end(factor as f32, x as u32, y as u32) + }); } #[no_mangle] -pub extern "C" fn Java_org_mozilla_servoview_JNIServo_click( - env: JNIEnv, - _: JClass, +pub extern "C" fn Java_org_mozilla_servoview_JNIServo_click<'local>( + mut env: JNIEnv<'local>, + _: JClass<'local>, x: jfloat, y: jfloat, ) { debug!("click"); - call(&env, |s| s.click(x as f32, y as f32)); + call(&mut env, |s| s.click(x as f32, y as f32)); } #[no_mangle] -pub extern "C" fn Java_org_mozilla_servoview_JNIServo_pauseCompositor(env: JNIEnv, _: JClass) { +pub extern "C" fn Java_org_mozilla_servoview_JNIServo_pauseCompositor<'local>( + mut env: JNIEnv, + _: JClass<'local>, +) { debug!("pauseCompositor"); - call(&env, |s| s.pause_compositor()); + call(&mut env, |s| s.pause_compositor()); } #[no_mangle] -pub extern "C" fn Java_org_mozilla_servoview_JNIServo_resumeCompositor( - env: JNIEnv, - _: JClass, - surface: JObject, - coordinates: JObject, +pub extern "C" fn Java_org_mozilla_servoview_JNIServo_resumeCompositor<'local>( + mut env: JNIEnv<'local>, + _: JClass<'local>, + surface: JObject<'local>, + coordinates: JObject<'local>, ) { debug!("resumeCompositor"); - let widget = unsafe { ANativeWindow_fromSurface(env.get_native_interface(), surface) }; - let coords = jni_coords_to_rust_coords(&env, coordinates); + let widget = unsafe { ANativeWindow_fromSurface(env.get_native_interface(), surface.as_raw()) }; + let coords = jni_coords_to_rust_coords(&mut env, &coordinates); match coords { - Ok(coords) => call(&env, |s| s.resume_compositor(widget, coords.clone())), - Err(error) => throw(&env, &error), + Ok(coords) => call(&mut env, |s| s.resume_compositor(widget, coords.clone())), + Err(error) => throw(&mut env, &error), } } #[no_mangle] -pub extern "C" fn Java_org_mozilla_servoview_JNIServo_mediaSessionAction( - env: JNIEnv, - _: JClass, +pub extern "C" fn Java_org_mozilla_servoview_JNIServo_mediaSessionAction<'local>( + mut env: JNIEnv<'local>, + _: JClass<'local>, action: jint, ) { debug!("mediaSessionAction"); - call(&env, |s| s.media_session_action((action as i32).into())); + call(&mut env, |s| s.media_session_action((action as i32).into())); } pub struct WakeupCallback { @@ -420,7 +455,7 @@ impl EventLoopWaker for WakeupCallback { } fn wake(&self) { debug!("wakeup"); - let env = self.jvm.attach_current_thread().unwrap(); + let mut env = self.jvm.attach_current_thread().unwrap(); env.call_method(self.callback.as_obj(), "wakeup", "()V", &[]) .unwrap(); } @@ -436,17 +471,15 @@ impl HostCallbacks { impl HostTrait for HostCallbacks { fn prompt_alert(&self, message: String, _trusted: bool) { debug!("prompt_alert"); - let env = self.jvm.get_env().unwrap(); - let s = match new_string(&env, &message) { - Ok(s) => s, - Err(_) => return, + let mut env = self.jvm.get_env().unwrap(); + let Ok(string) = new_string_as_jvalue(&mut env, &message) else { + return; }; - let s = JValue::from(JObject::from(s)); env.call_method( self.callbacks.as_obj(), "onAlert", "(Ljava/lang/String;)V", - &[s], + &[(&string).into()], ) .unwrap(); } @@ -468,56 +501,52 @@ impl HostTrait for HostCallbacks { fn on_load_started(&self) { debug!("on_load_started"); - let env = self.jvm.get_env().unwrap(); + let mut env = self.jvm.get_env().unwrap(); env.call_method(self.callbacks.as_obj(), "onLoadStarted", "()V", &[]) .unwrap(); } fn on_load_ended(&self) { debug!("on_load_ended"); - let env = self.jvm.get_env().unwrap(); + let mut env = self.jvm.get_env().unwrap(); env.call_method(self.callbacks.as_obj(), "onLoadEnded", "()V", &[]) .unwrap(); } fn on_shutdown_complete(&self) { debug!("on_shutdown_complete"); - let env = self.jvm.get_env().unwrap(); + let mut env = self.jvm.get_env().unwrap(); env.call_method(self.callbacks.as_obj(), "onShutdownComplete", "()V", &[]) .unwrap(); } fn on_title_changed(&self, title: Option) { debug!("on_title_changed"); - let env = self.jvm.get_env().unwrap(); + let mut env = self.jvm.get_env().unwrap(); let title = title.unwrap_or_else(String::new); - let s = match new_string(&env, &title) { - Ok(s) => s, - Err(_) => return, + let Ok(title_string) = new_string_as_jvalue(&mut env, &title) else { + return; }; - let s = JValue::from(JObject::from(s)); env.call_method( self.callbacks.as_obj(), "onTitleChanged", "(Ljava/lang/String;)V", - &[s], + &[(&title_string).into()], ) .unwrap(); } fn on_allow_navigation(&self, url: String) -> bool { debug!("on_allow_navigation"); - let env = self.jvm.get_env().unwrap(); - let s = match new_string(&env, &url) { - Ok(s) => s, - Err(_) => return false, + let mut env = self.jvm.get_env().unwrap(); + let Ok(url_string) = new_string_as_jvalue(&mut env, &url) else { + return false; }; - let s = JValue::from(JObject::from(s)); let allow = env.call_method( self.callbacks.as_obj(), "onAllowNavigation", "(Ljava/lang/String;)Z", - &[s], + &[(&url_string).into()], ); match allow { Ok(allow) => return allow.z().unwrap(), @@ -527,24 +556,22 @@ impl HostTrait for HostCallbacks { fn on_url_changed(&self, url: String) { debug!("on_url_changed"); - let env = self.jvm.get_env().unwrap(); - let s = match new_string(&env, &url) { - Ok(s) => s, - Err(_) => return, + let mut env = self.jvm.get_env().unwrap(); + let Ok(url_string) = new_string_as_jvalue(&mut env, &url) else { + return; }; - let s = JValue::Object(JObject::from(s)); env.call_method( self.callbacks.as_obj(), "onUrlChanged", "(Ljava/lang/String;)V", - &[s], + &[(&url_string).into()], ) .unwrap(); } fn on_history_changed(&self, can_go_back: bool, can_go_forward: bool) { debug!("on_history_changed"); - let env = self.jvm.get_env().unwrap(); + let mut env = self.jvm.get_env().unwrap(); let can_go_back = JValue::Bool(can_go_back as jboolean); let can_go_forward = JValue::Bool(can_go_forward as jboolean); env.call_method( @@ -558,7 +585,7 @@ impl HostTrait for HostCallbacks { fn on_animating_changed(&self, animating: bool) { debug!("on_animating_changed"); - let env = self.jvm.get_env().unwrap(); + let mut env = self.jvm.get_env().unwrap(); let animating = JValue::Bool(animating as jboolean); env.call_method( self.callbacks.as_obj(), @@ -587,36 +614,31 @@ impl HostTrait for HostCallbacks { fn on_media_session_metadata(&self, title: String, artist: String, album: String) { info!("on_media_session_metadata"); - let env = self.jvm.get_env().unwrap(); - let title = match new_string(&env, &title) { - Ok(s) => s, - Err(_) => return, + let mut env = self.jvm.get_env().unwrap(); + let Ok(title) = new_string_as_jvalue(&mut env, &title) else { + return; }; - let title = JValue::Object(JObject::from(title)); - let artist = match new_string(&env, &artist) { - Ok(s) => s, - Err(_) => return, + let Ok(artist) = new_string_as_jvalue(&mut env, &artist) else { + return; }; - let artist = JValue::Object(JObject::from(artist)); - let album = match new_string(&env, &album) { - Ok(s) => s, - Err(_) => return, + let Ok(album) = new_string_as_jvalue(&mut env, &album) else { + return; }; - let album = JValue::Object(JObject::from(album)); + env.call_method( self.callbacks.as_obj(), "onMediaSessionMetadata", "(Ljava/lang/String;Ljava/lang/String;Ljava/lang/String;)V", - &[title, artist, album], + &[(&title).into(), (&artist).into(), (&album).into()], ) .unwrap(); } fn on_media_session_playback_state_change(&self, state: MediaSessionPlaybackState) { info!("on_media_session_playback_state_change {:?}", state); - let env = self.jvm.get_env().unwrap(); + let mut env = self.jvm.get_env().unwrap(); let state = state as i32; let state = JValue::Int(state as jint); env.call_method( @@ -638,7 +660,7 @@ impl HostTrait for HostCallbacks { "on_media_session_playback_state_change ({:?}, {:?}, {:?})", duration, position, playback_rate ); - let env = self.jvm.get_env().unwrap(); + let mut env = self.jvm.get_env().unwrap(); let duration = JValue::Float(duration as jfloat); let position = JValue::Float(position as jfloat); let playback_rate = JValue::Float(playback_rate as jfloat); @@ -753,7 +775,7 @@ fn redirect_stdout_to_logcat() { }); } -fn throw(env: &JNIEnv, err: &str) { +fn throw(env: &mut JNIEnv, err: &str) { if let Err(e) = env.throw(("java/lang/Exception", err)) { warn!( "Failed to throw Java exception: `{}`. Exception was: `{}`", @@ -762,17 +784,34 @@ fn throw(env: &JNIEnv, err: &str) { } } -fn new_string(env: &JNIEnv, s: &str) -> Result { +fn new_string(env: &mut JNIEnv, s: &str) -> Result { match env.new_string(s) { - Ok(s) => Ok(s.into_inner()), + Ok(s) => Ok(s.into_raw()), Err(_) => { - throw(&env, "Couldn't create java string"); - Err(JObject::null().into_inner()) + throw(env, "Couldn't create Java string"); + Err("Couldn't create Java String") }, } } -fn jni_coords_to_rust_coords(env: &JNIEnv, obj: JObject) -> Result { +fn new_string_as_jvalue<'local>( + env: &mut JNIEnv<'local>, + input_string: &str, +) -> Result, &'static str> { + let jstring = match env.new_string(input_string) { + Ok(jstring) => jstring, + Err(_) => { + throw(env, "Couldn't create Java string"); + return Err("Couldn't create Java string"); + }, + }; + Ok(JValueOwned::from(jstring)) +} + +fn jni_coords_to_rust_coords<'local>( + env: &mut JNIEnv<'local>, + obj: &JObject<'local>, +) -> Result { let x = get_non_null_field(env, obj, "x", "I")? .i() .map_err(|_| "x not an int")? as i32; @@ -794,55 +833,64 @@ fn jni_coords_to_rust_coords(env: &JNIEnv, obj: JObject) -> Result( - env: &'a JNIEnv, - obj: JObject<'a>, +fn get_field<'local>( + env: &mut JNIEnv<'local>, + obj: &JObject<'local>, field: &str, type_: &str, -) -> Result>, String> { - if env.get_field_id(obj, field, type_).is_err() { +) -> Result>, String> { + let Ok(class) = env.get_object_class(obj) else { + return Err("Can't get object class".to_owned()); + }; + + if env.get_field_id(class, field, type_).is_err() { return Err(format!("Can't find `{}` field", field)); } + env.get_field(obj, field, type_) .map(|value| Some(value)) .or_else(|_| Err(format!("Can't find `{}` field", field))) } -fn get_non_null_field<'a>( - env: &'a JNIEnv, - obj: JObject<'a>, +fn get_non_null_field<'local>( + env: &mut JNIEnv<'local>, + obj: &JObject<'local>, field: &str, type_: &str, -) -> Result, String> { +) -> Result, String> { match get_field(env, obj, field, type_)? { None => Err(format!("Field {} is null", field)), Some(f) => Ok(f), } } -fn get_string(env: &JNIEnv, obj: JObject, field: &str) -> Result, String> { - let value = get_field(env, obj, field, "Ljava/lang/String;")?; - match value { - Some(value) => { - let string = value - .l() - .map_err(|_| format!("field `{}` is not an Object", field))? - .into(); - Ok(env.get_string(string).map(|s| s.into()).ok()) - }, - None => Ok(None), - } +fn get_field_as_string<'local>( + env: &mut JNIEnv<'local>, + obj: &JObject<'local>, + field: &str, +) -> Result, String> { + let string = { + let value = get_field(env, obj, field, "Ljava/lang/String;")?; + let Some(value) = value else { + return Ok(None); + }; + value + .l() + .map_err(|_| format!("field `{}` is not an Object", field))? + }; + + Ok(env.get_string((&string).into()).map(|s| s.into()).ok()) } -fn get_options( - env: &JNIEnv, - opts: JObject, - surface: JObject, +fn get_options<'local>( + env: &mut JNIEnv<'local>, + opts: &JObject<'local>, + surface: &JObject<'local>, ) -> Result<(InitOptions, bool, Option, Option), String> { - let args = get_string(env, opts, "args")?; - let url = get_string(env, opts, "url")?; - let log_str = get_string(env, opts, "logStr")?; - let gst_debug_str = get_string(env, opts, "gstDebugStr")?; + let args = get_field_as_string(env, opts, "args")?; + let url = get_field_as_string(env, opts, "url")?; + let log_str = get_field_as_string(env, opts, "logStr")?; + let gst_debug_str = get_field_as_string(env, opts, "gstDebugStr")?; let density = get_non_null_field(env, opts, "density", "F")? .f() .map_err(|_| "densitiy not a float")? as f32; @@ -857,7 +905,7 @@ fn get_options( )? .l() .map_err(|_| "coordinates is not an object")?; - let coordinates = jni_coords_to_rust_coords(&env, coordinates)?; + let coordinates = jni_coords_to_rust_coords(env, &coordinates)?; let args = match args { Some(args) => serde_json::from_str(&args) @@ -865,7 +913,8 @@ fn get_options( None => None, }; - let native_window = unsafe { ANativeWindow_fromSurface(env.get_native_interface(), surface) }; + let native_window = + unsafe { ANativeWindow_fromSurface(env.get_native_interface(), surface.as_raw()) }; // FIXME: enable JIT compilation on 32-bit Android after the startup crash issue (#31134) is fixed. let prefs = if cfg!(target_pointer_width = "32") { diff --git a/servo-tidy.toml b/servo-tidy.toml index 6db10c6da0e..b05b6d97413 100644 --- a/servo-tidy.toml +++ b/servo-tidy.toml @@ -37,7 +37,6 @@ packages = [ "toml", # Duplicated by winit. - "jni", "windows-sys", "windows-targets", "windows_aarch64_gnullvm",