crossbow_android/plugin/
mod.rs

1mod handlers;
2mod jni_rust_type;
3mod jni_singleton;
4
5pub use async_channel::{Receiver, Sender};
6pub(crate) use handlers::*;
7pub use jni_rust_type::*;
8pub use jni_singleton::*;
9
10use crate::error::*;
11use jni::JavaVM;
12use std::{
13    collections::HashMap,
14    sync::{Arc, Mutex},
15};
16
17pub trait CrossbowPlugin {
18    fn from_java_vm(vm: Arc<JavaVM>) -> Result<Self>
19    where
20        Self: Sized;
21    fn get_plugin_name() -> &'static str;
22    fn get_receiver(&self) -> &Receiver<Signal>;
23}
24
25lazy_static::lazy_static! {
26    static ref JNI_SINGLETONS: Mutex<HashMap<String, Arc<JniSingleton>>> = Default::default();
27    static ref JNI_SIGNAL_SENDERS: Mutex<HashMap<String, Sender<Signal>>> = Default::default();
28}
29
30fn insert_jni_singleton(
31    singleton_name: &str,
32    singleton: JniSingleton,
33) -> Option<Arc<JniSingleton>> {
34    let mut jni_signletons_guard = JNI_SINGLETONS.lock().unwrap();
35    jni_signletons_guard.insert(singleton_name.to_owned(), Arc::new(singleton))
36}
37
38pub fn get_jni_singleton(singleton_name: &str) -> Option<Arc<JniSingleton>> {
39    let jni_signletons_guard = JNI_SINGLETONS.lock().unwrap();
40    jni_signletons_guard.get(singleton_name).cloned()
41}
42
43fn insert_sender(singleton_name: &str, sender: Sender<Signal>) -> Option<Sender<Signal>> {
44    JNI_SIGNAL_SENDERS
45        .lock()
46        .unwrap()
47        .insert(singleton_name.to_owned(), sender)
48}
49
50pub fn get_jni_singleton_with_error(singleton_name: &str) -> Result<Arc<JniSingleton>> {
51    if let Some(jni_signleton) = get_jni_singleton(singleton_name) {
52        Ok(jni_signleton)
53    } else {
54        Err(AndroidError::SingletonNotRegistered(
55            singleton_name.to_owned(),
56        ))
57    }
58}
59
60pub fn get_sender(singleton_name: &str) -> Result<Sender<Signal>> {
61    let jni_signals = JNI_SIGNAL_SENDERS.lock().unwrap();
62    let sender = jni_signals
63        .get(singleton_name)
64        .ok_or_else(|| AndroidError::SignalSenderNotAvailable(singleton_name.to_owned()))?;
65    if sender.is_closed() {
66        return Err(AndroidError::SignalSenderNotAvailable(
67            singleton_name.to_owned(),
68        ));
69    }
70    Ok(sender.clone())
71}