bubba-core 0.2.2

Core runtime for the Bubba mobile framework
Documentation
//! Android JNI bridge — called from BubbaBridge.java and BubbaActivity.java

use jni::JNIEnv;
use jni::objects::{JClass, JString};
use jni::sys::{jstring, jboolean, jint, JNI_TRUE, JNI_FALSE};
use jni::JavaVM;
use std::sync::OnceLock;

use crate::runtime::{dispatch_event, did_navigate, render_current_to_json};
use crate::navigation::navigate_back;

static JVM: OnceLock<JavaVM> = OnceLock::new();

#[no_mangle]
pub extern "system" fn Java_rs_bubba_BubbaBridge_nativeInit(
    mut env: JNIEnv,
    _class: JClass,
) {
    env_logger::try_init().ok();
    log::info!("[Bubba] nativeInit called");
    if let Ok(vm) = env.get_java_vm() {
        JVM.set(vm).ok();
    }
}

#[no_mangle]
pub extern "system" fn Java_rs_bubba_BubbaBridge_nativeOnLifecycle(
    mut env: JNIEnv,
    _class: JClass,
    event: JString,
) {
    // jni 0.21 requires &JString not JString
    let event_str: String = env.get_string(&event)
        .map(|s| s.into())
        .unwrap_or_default();
    log::info!("[Bubba] Lifecycle: {}", event_str);
}

#[no_mangle]
pub extern "system" fn Java_rs_bubba_BubbaBridge_nativeRender(
    mut env: JNIEnv,
    _class: JClass,
) -> jstring {
    let json = render_current_to_json();
    log::debug!("[Bubba] nativeRender {} bytes", json.len());
    env.new_string(json)
        .map(|s| s.into_raw())
        .unwrap_or(std::ptr::null_mut())
}

#[no_mangle]
pub extern "system" fn Java_rs_bubba_BubbaBridge_nativeOnEvent(
    mut env: JNIEnv,
    _class: JClass,
    element_id: jint,
    event_kind: JString,
    value: JString,
) {
    // jni 0.21 requires &JString not JString
    let kind: String = env.get_string(&event_kind)
        .map(|s| s.into())
        .unwrap_or_default();
    let val: String = env.get_string(&value)
        .map(|s| s.into())
        .unwrap_or_default();

    log::debug!("[Bubba] nativeOnEvent: {} on #{}", kind, element_id);
    dispatch_event(element_id as u32, &kind, &val);
}

#[no_mangle]
pub extern "system" fn Java_rs_bubba_BubbaBridge_nativeDidNavigate(
    _env: JNIEnv,
    _class: JClass,
) -> jboolean {
    if did_navigate() { JNI_TRUE } else { JNI_FALSE }
}

#[no_mangle]
pub extern "system" fn Java_rs_bubba_BubbaBridge_nativeOnBack(
    _env: JNIEnv,
    _class: JClass,
) -> jboolean {
    if navigate_back() { JNI_TRUE } else { JNI_FALSE }
}