diff --git a/rustls-platform-verifier/src/android.rs b/rustls-platform-verifier/src/android.rs index f50db6c..98d3358 100644 --- a/rustls-platform-verifier/src/android.rs +++ b/rustls-platform-verifier/src/android.rs @@ -74,22 +74,62 @@ fn global() -> &'static Global { /// nothing else in your application needs access the Android runtime. /// /// Initialization must be done before any verification is attempted. -pub fn init_hosted(env: &mut JNIEnv, context: JObject) -> Result<(), JNIError> { +pub fn init_with_env(env: &mut JNIEnv, context: JObject) -> Result<(), JNIError> { GLOBAL.get_or_try_init(|| -> Result<_, JNIError> { let loader = env.call_method(&context, "getClassLoader", "()Ljava/lang/ClassLoader;", &[])?; - let global = Global::Internal { + + Ok(Global::Internal { java_vm: env.get_java_vm()?, context: env.new_global_ref(context)?, loader: env.new_global_ref(JObject::try_from(loader)?)?, - }; - - Ok(global) + }) })?; - Ok(()) } +/// Initializes and stores the required context for the Android platform. +/// +/// This method will setup and store an envrionment locally. This is useful if +/// nothing else in your application needs access the Android runtime. +/// +/// Initialization must be done before any verification is attempted. +#[deprecated(since = "0.5.0", note = "please use `init_with_env` instead")] +pub fn init_hosted(env: &mut JNIEnv, context: JObject) -> Result<(), JNIError> { + init_with_env(env, context) +} + +/// Initializes and stores the required context for the Android platform. +/// +/// This method takes a [`JavaVM`] and [`GlobalRef`]s to the needed context and class loader +/// objects. +/// +/// Initialization must be done before any verification is attempted. +/// +/// # Examples +/// +/// ```rust +/// use std::ffi::c_void; +/// +/// pub fn android_init(raw_env: *mut c_void, raw_context: *mut c_void) -> Result<(), jni::errors::Error> { +/// let mut env = unsafe { jni::JNIEnv::from_raw(raw_env as *mut jni::sys::JNIEnv).unwrap() }; +/// let context = unsafe { JObject::from_raw(raw_context as jni::sys::jobject) }; +/// let loader = env.call_method(&context, "getClassLoader", "()Ljava/lang/ClassLoader;", &[])?; +/// +/// rustls_platform_verifier::android::init_with_refs( +/// env.get_java_vm()?, +/// env.new_global_ref(context)?, +/// env.new_global_ref(JObject::try_from(loader)?)?, +/// } +/// ``` +pub fn init_with_refs(java_vm: JavaVM, context: GlobalRef, loader: GlobalRef) { + GLOBAL.get_or_init(|| Global::Internal { + java_vm, + context, + loader, + }); +} + /// Initializes and stores the required context for the Android platform. /// /// This method utilizes an existing Android runtime environment and set anything @@ -99,10 +139,24 @@ pub fn init_hosted(env: &mut JNIEnv, context: JObject) -> Result<(), JNIError> { /// This function will never panic, and is therefore safe to use at FFI boundaries. /// /// Initialization must be done before any verification is attempted. -pub fn init_external(runtime: &'static dyn Runtime) { +pub fn init_with_runtime(runtime: &'static dyn Runtime) { GLOBAL.get_or_init(|| Global::External(runtime)); } +/// Initializes and stores the required context for the Android platform. +/// +/// This method utilizes an existing Android runtime envrionment and set anything +/// else up on its own. This is useful if your application already interacts with +/// the runtime and has pre-existing handles. +/// +/// This function will never panic, and is therefore safe to use at FFI boundaries. +/// +/// Initialization must be done before any verification is attempted. +#[deprecated(since = "0.5.0", note = "please use `init_with_runtime` instead")] +pub fn init_external(runtime: &'static dyn Runtime) { + init_with_runtime(runtime); +} + /// Wrapper for JNI errors that will log and clear exceptions /// It should generally be preferred to `jni::errors::Error` #[derive(Debug)] diff --git a/rustls-platform-verifier/src/tests/ffi.rs b/rustls-platform-verifier/src/tests/ffi.rs index 9030cc3..70ab573 100644 --- a/rustls-platform-verifier/src/tests/ffi.rs +++ b/rustls-platform-verifier/src/tests/ffi.rs @@ -46,7 +46,7 @@ mod android { .with_max_level(log::Level::Trace.to_level_filter()) .with_filter(log_filter), ); - crate::android::init_hosted(env, cx).unwrap(); + crate::android::init_with_env(env, cx).unwrap(); crate::tests::ensure_global_state(); std::panic::set_hook(Box::new(|info| { let msg = if let Some(msg) = info.payload().downcast_ref::<&'static str>() {