mirror of
https://github.com/tauri-apps/tauri.git
synced 2024-12-29 05:51:59 +03:00
feat(core): add API to call Android plugin (#6239)
This commit is contained in:
parent
62f1526592
commit
9feab904bf
6
.changes/refactor-macros.md
Normal file
6
.changes/refactor-macros.md
Normal file
@ -0,0 +1,6 @@
|
||||
---
|
||||
"tauri-macros": patch
|
||||
"tauri": patch
|
||||
---
|
||||
|
||||
Refactored the implementation of the `mobile_entry_point` macro.
|
5
.changes/run-android-plugin.md
Normal file
5
.changes/run-android-plugin.md
Normal file
@ -0,0 +1,5 @@
|
||||
---
|
||||
"tauri": patch
|
||||
---
|
||||
|
||||
Added `App::run_android_plugin` and `AppHandle::run_android_plugin`.
|
@ -39,12 +39,9 @@ impl PluginBuilder {
|
||||
|
||||
println!("cargo:rerun-if-env-changed=TAURI_PLUGIN_OUTPUT_PATH");
|
||||
println!("cargo:rerun-if-env-changed=TAURI_GRADLE_SETTINGS_PATH");
|
||||
println!(
|
||||
"cargo:rerun-if-changed={}{}{}",
|
||||
out_dir, MAIN_SEPARATOR, pkg_name
|
||||
);
|
||||
println!("cargo:rerun-if-changed={}", gradle_settings_path);
|
||||
println!("cargo:rerun-if-changed={}", app_build_gradle_path);
|
||||
println!("cargo:rerun-if-changed={out_dir}{MAIN_SEPARATOR}{pkg_name}",);
|
||||
println!("cargo:rerun-if-changed={gradle_settings_path}");
|
||||
println!("cargo:rerun-if-changed={app_build_gradle_path}");
|
||||
|
||||
let out_dir = PathBuf::from(out_dir);
|
||||
let target = out_dir.join(&pkg_name);
|
||||
@ -73,7 +70,7 @@ impl PluginBuilder {
|
||||
}
|
||||
|
||||
if let Some(out_dir) = out_dir {
|
||||
rename(&out_dir, &build_path)?;
|
||||
rename(out_dir, &build_path)?;
|
||||
}
|
||||
|
||||
let gradle_settings = fs::read_to_string(&gradle_settings_path)?;
|
||||
@ -84,7 +81,7 @@ project(':{pkg_name}').projectDir = new File('./tauri-plugins/{pkg_name}')"
|
||||
if !gradle_settings.contains(&include) {
|
||||
fs::write(
|
||||
&gradle_settings_path,
|
||||
&format!("{gradle_settings}\n{include}"),
|
||||
format!("{gradle_settings}\n{include}"),
|
||||
)?;
|
||||
}
|
||||
|
||||
|
@ -62,8 +62,7 @@ pub fn entry_point(_attributes: TokenStream, item: TokenStream) -> TokenStream {
|
||||
::tauri::log_stdout();
|
||||
#[cfg(target_os = "android")]
|
||||
{
|
||||
use ::tauri::paste;
|
||||
::tauri::wry_android_binding!(#domain, #app_name, _start_app, ::tauri::wry);
|
||||
::tauri::android_binding!(#domain, #app_name, _start_app, ::tauri::wry);
|
||||
}
|
||||
stop_unwind(#function_name);
|
||||
}
|
||||
|
@ -109,7 +109,6 @@ version = "0.44"
|
||||
features = [ "Win32_Foundation" ]
|
||||
|
||||
[target."cfg(target_os = \"android\")".dependencies]
|
||||
paste = "1.0"
|
||||
log = "0.4"
|
||||
jni = "0.20"
|
||||
|
||||
|
@ -860,6 +860,88 @@ macro_rules! shared_app_impl {
|
||||
}
|
||||
Ok(())
|
||||
}
|
||||
|
||||
/// Executes the given Android plugin method.
|
||||
#[cfg(target_os = "android")]
|
||||
pub fn run_android_plugin<T: serde::de::DeserializeOwned, E: serde::de::DeserializeOwned>(
|
||||
&self,
|
||||
plugin: impl Into<String>,
|
||||
method: impl Into<String>,
|
||||
payload: impl serde::Serialize
|
||||
) -> Result<Result<T, E>, jni::errors::Error> {
|
||||
use jni::{
|
||||
errors::Error as JniError,
|
||||
objects::JObject,
|
||||
JNIEnv,
|
||||
};
|
||||
|
||||
fn run<R: Runtime>(
|
||||
id: i32,
|
||||
plugin: String,
|
||||
method: String,
|
||||
payload: serde_json::Value,
|
||||
runtime_handle: &R::Handle,
|
||||
env: JNIEnv<'_>,
|
||||
activity: JObject<'_>,
|
||||
) -> Result<(), JniError> {
|
||||
let data = crate::jni_helpers::to_jsobject::<R>(env, activity, runtime_handle, payload)?;
|
||||
let plugin_manager = env
|
||||
.call_method(
|
||||
activity,
|
||||
"getPluginManager",
|
||||
"()Lapp/tauri/plugin/PluginManager;",
|
||||
&[],
|
||||
)?
|
||||
.l()?;
|
||||
|
||||
env.call_method(
|
||||
plugin_manager,
|
||||
"runPluginMethod",
|
||||
"(ILjava/lang/String;Ljava/lang/String;Lapp/tauri/plugin/JSObject;)V",
|
||||
&[
|
||||
id.into(),
|
||||
env.new_string(plugin)?.into(),
|
||||
env.new_string(&method)?.into(),
|
||||
data.into(),
|
||||
],
|
||||
)?;
|
||||
|
||||
Ok(())
|
||||
}
|
||||
|
||||
let handle = match self.runtime() {
|
||||
RuntimeOrDispatch::Runtime(r) => r.handle(),
|
||||
RuntimeOrDispatch::RuntimeHandle(h) => h,
|
||||
_ => unreachable!(),
|
||||
};
|
||||
|
||||
let id: i32 = rand::random();
|
||||
let plugin = plugin.into();
|
||||
let method = method.into();
|
||||
let payload = serde_json::to_value(payload).unwrap();
|
||||
let handle_ = handle.clone();
|
||||
|
||||
let (tx, rx) = std::sync::mpsc::channel();
|
||||
let tx_ = tx.clone();
|
||||
PENDING_PLUGIN_CALLS
|
||||
.get_or_init(Default::default)
|
||||
.lock()
|
||||
.unwrap().insert(id, Box::new(move |arg| {
|
||||
tx.send(Ok(arg)).unwrap();
|
||||
}));
|
||||
|
||||
handle.run_on_android_context(move |env, activity, _webview| {
|
||||
if let Err(e) = run::<R>(id, plugin, method, payload, &handle_, env, activity) {
|
||||
tx_.send(Err(e)).unwrap();
|
||||
}
|
||||
});
|
||||
|
||||
rx.recv().unwrap().map(|response| {
|
||||
response
|
||||
.map(|r| serde_json::from_value(r).unwrap())
|
||||
.map_err(|e| serde_json::from_value(e).unwrap())
|
||||
})
|
||||
}
|
||||
}
|
||||
};
|
||||
}
|
||||
@ -1868,6 +1950,57 @@ impl Default for Builder<crate::Wry> {
|
||||
}
|
||||
}
|
||||
|
||||
#[cfg(target_os = "android")]
|
||||
type PendingPluginCallHandler =
|
||||
Box<dyn FnOnce(std::result::Result<serde_json::Value, serde_json::Value>) + Send + 'static>;
|
||||
|
||||
#[cfg(target_os = "android")]
|
||||
static PENDING_PLUGIN_CALLS: once_cell::sync::OnceCell<
|
||||
std::sync::Mutex<HashMap<i32, PendingPluginCallHandler>>,
|
||||
> = once_cell::sync::OnceCell::new();
|
||||
|
||||
#[cfg(target_os = "android")]
|
||||
#[doc(hidden)]
|
||||
pub fn handle_android_plugin_response(
|
||||
env: jni::JNIEnv<'_>,
|
||||
id: i32,
|
||||
success: jni::objects::JString<'_>,
|
||||
error: jni::objects::JString<'_>,
|
||||
) {
|
||||
let (payload, is_ok): (serde_json::Value, bool) = match (
|
||||
env
|
||||
.is_same_object(success, jni::objects::JObject::default())
|
||||
.unwrap_or_default(),
|
||||
env
|
||||
.is_same_object(error, jni::objects::JObject::default())
|
||||
.unwrap_or_default(),
|
||||
) {
|
||||
// both null
|
||||
(true, true) => (serde_json::Value::Null, true),
|
||||
// error null
|
||||
(false, true) => (
|
||||
serde_json::from_str(env.get_string(success).unwrap().to_str().unwrap()).unwrap(),
|
||||
true,
|
||||
),
|
||||
// success null
|
||||
(true, false) => (
|
||||
serde_json::from_str(env.get_string(error).unwrap().to_str().unwrap()).unwrap(),
|
||||
false,
|
||||
),
|
||||
// both are set - impossible in the Kotlin code
|
||||
(false, false) => unreachable!(),
|
||||
};
|
||||
|
||||
if let Some(handler) = PENDING_PLUGIN_CALLS
|
||||
.get_or_init(Default::default)
|
||||
.lock()
|
||||
.unwrap()
|
||||
.remove(&id)
|
||||
{
|
||||
handler(if is_ok { Ok(payload) } else { Err(payload) });
|
||||
}
|
||||
}
|
||||
|
||||
#[cfg(test)]
|
||||
mod tests {
|
||||
#[test]
|
||||
|
83
core/tauri/src/jni_helpers.rs
Normal file
83
core/tauri/src/jni_helpers.rs
Normal file
@ -0,0 +1,83 @@
|
||||
use crate::Runtime;
|
||||
use jni::{
|
||||
errors::Error as JniError,
|
||||
objects::{JObject, JValue},
|
||||
JNIEnv,
|
||||
};
|
||||
use serde_json::Value as JsonValue;
|
||||
use tauri_runtime::RuntimeHandle;
|
||||
|
||||
fn json_to_java<'a, R: Runtime>(
|
||||
env: JNIEnv<'a>,
|
||||
activity: JObject<'a>,
|
||||
runtime_handle: &R::Handle,
|
||||
json: JsonValue,
|
||||
) -> Result<(&'static str, JValue<'a>), JniError> {
|
||||
let (class, v) = match json {
|
||||
JsonValue::Null => ("Ljava/lang/Object;", JObject::null().into()),
|
||||
JsonValue::Bool(val) => ("Z", val.into()),
|
||||
JsonValue::Number(val) => {
|
||||
if let Some(v) = val.as_i64() {
|
||||
("J", v.into())
|
||||
} else if let Some(v) = val.as_f64() {
|
||||
("D", v.into())
|
||||
} else {
|
||||
("Ljava/lang/Object;", JObject::null().into())
|
||||
}
|
||||
}
|
||||
JsonValue::String(val) => (
|
||||
"Ljava/lang/Object;",
|
||||
JObject::from(env.new_string(&val)?).into(),
|
||||
),
|
||||
JsonValue::Array(val) => {
|
||||
let js_array_class = runtime_handle.find_class(env, activity, "app/tauri/plugin/JSArray")?;
|
||||
let data = env.new_object(js_array_class, "()V", &[])?;
|
||||
|
||||
for v in val {
|
||||
let (signature, val) = json_to_java::<R>(env, activity, runtime_handle, v)?;
|
||||
env.call_method(
|
||||
data,
|
||||
"put",
|
||||
format!("({signature})Lorg/json/JSONArray;"),
|
||||
&[val],
|
||||
)?;
|
||||
}
|
||||
|
||||
("Ljava/lang/Object;", data.into())
|
||||
}
|
||||
JsonValue::Object(val) => {
|
||||
let js_object_class =
|
||||
runtime_handle.find_class(env, activity, "app/tauri/plugin/JSObject")?;
|
||||
let data = env.new_object(js_object_class, "()V", &[])?;
|
||||
|
||||
for (key, value) in val {
|
||||
let (signature, val) = json_to_java::<R>(env, activity, runtime_handle, value)?;
|
||||
env.call_method(
|
||||
data,
|
||||
"put",
|
||||
format!("(Ljava/lang/String;{signature})Lapp/tauri/plugin/JSObject;"),
|
||||
&[env.new_string(&key)?.into(), val],
|
||||
)?;
|
||||
}
|
||||
|
||||
("Ljava/lang/Object;", data.into())
|
||||
}
|
||||
};
|
||||
Ok((class, v))
|
||||
}
|
||||
|
||||
pub fn to_jsobject<'a, R: Runtime>(
|
||||
env: JNIEnv<'a>,
|
||||
activity: JObject<'a>,
|
||||
runtime_handle: &R::Handle,
|
||||
json: JsonValue,
|
||||
) -> Result<JValue<'a>, JniError> {
|
||||
if let JsonValue::Object(_) = &json {
|
||||
json_to_java::<R>(env, activity, runtime_handle, json).map(|(_class, data)| data)
|
||||
} else {
|
||||
// currently the Kotlin lib cannot handle nulls or raw values, it must be an object
|
||||
let js_object_class = runtime_handle.find_class(env, activity, "app/tauri/plugin/JSObject")?;
|
||||
let data = env.new_object(js_object_class, "()V", &[])?;
|
||||
Ok(data.into())
|
||||
}
|
||||
}
|
@ -188,6 +188,8 @@ mod pattern;
|
||||
pub mod plugin;
|
||||
pub mod window;
|
||||
use tauri_runtime as runtime;
|
||||
#[cfg(target_os = "android")]
|
||||
mod jni_helpers;
|
||||
/// The allowlist scopes.
|
||||
pub mod scope;
|
||||
mod state;
|
||||
@ -204,11 +206,35 @@ pub type Wry = tauri_runtime_wry::Wry<EventLoopMessage>;
|
||||
|
||||
#[cfg(all(feature = "wry", target_os = "android"))]
|
||||
#[cfg_attr(doc_cfg, doc(cfg(all(feature = "wry", target_os = "android"))))]
|
||||
pub use tauri_runtime_wry::wry::android_binding as wry_android_binding;
|
||||
#[doc(hidden)]
|
||||
#[macro_export]
|
||||
macro_rules! android_binding {
|
||||
($domain:ident, $package:ident, $main: ident, $wry: path) => {
|
||||
::tauri::wry::android_binding!($domain, $package, $main, $wry);
|
||||
::tauri::wry::application::android_fn!(
|
||||
app_tauri,
|
||||
plugin,
|
||||
PluginManager,
|
||||
handlePluginResponse,
|
||||
[i32, JString, JString],
|
||||
);
|
||||
|
||||
#[allow(non_snake_case)]
|
||||
pub unsafe fn handlePluginResponse(
|
||||
env: JNIEnv,
|
||||
_: JClass,
|
||||
id: i32,
|
||||
success: JString,
|
||||
error: JString,
|
||||
) {
|
||||
::tauri::handle_android_plugin_response(env, id, success, error);
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
#[cfg(all(feature = "wry", target_os = "android"))]
|
||||
#[doc(hidden)]
|
||||
pub use paste;
|
||||
pub use app::handle_android_plugin_response;
|
||||
#[cfg(all(feature = "wry", target_os = "android"))]
|
||||
#[doc(hidden)]
|
||||
pub use tauri_runtime_wry::wry;
|
||||
|
@ -1365,89 +1365,12 @@ impl<R: Runtime> Window<R> {
|
||||
let plugin = plugin.to_string();
|
||||
self.with_webview(move |webview| {
|
||||
webview.jni_handle().exec(move |env, activity, webview| {
|
||||
use crate::api::ipc::CallbackFn;
|
||||
use jni::{
|
||||
errors::Error as JniError,
|
||||
objects::{JObject, JValue},
|
||||
objects::JObject,
|
||||
JNIEnv,
|
||||
};
|
||||
use serde_json::Value as JsonValue;
|
||||
|
||||
fn json_to_java<'a, R: Runtime>(
|
||||
env: JNIEnv<'a>,
|
||||
activity: JObject<'a>,
|
||||
runtime_handle: &R::Handle,
|
||||
json: JsonValue,
|
||||
) -> Result<(&'static str, JValue<'a>), JniError> {
|
||||
let (class, v) = match json {
|
||||
JsonValue::Null => ("Ljava/lang/Object;", JObject::null().into()),
|
||||
JsonValue::Bool(val) => ("Z", val.into()),
|
||||
JsonValue::Number(val) => {
|
||||
if let Some(v) = val.as_i64() {
|
||||
("J", v.into())
|
||||
} else if let Some(v) = val.as_f64() {
|
||||
("D", v.into())
|
||||
} else {
|
||||
("Ljava/lang/Object;", JObject::null().into())
|
||||
}
|
||||
}
|
||||
JsonValue::String(val) => (
|
||||
"Ljava/lang/Object;",
|
||||
JObject::from(env.new_string(&val)?).into(),
|
||||
),
|
||||
JsonValue::Array(val) => {
|
||||
let js_array_class =
|
||||
runtime_handle.find_class(env, activity, "app/tauri/plugin/JSArray")?;
|
||||
let data = env.new_object(js_array_class, "()V", &[])?;
|
||||
|
||||
for v in val {
|
||||
let (signature, val) =
|
||||
json_to_java::<R>(env, activity, runtime_handle, v)?;
|
||||
env.call_method(
|
||||
data,
|
||||
"put",
|
||||
format!("({signature})Lorg/json/JSONArray;"),
|
||||
&[val],
|
||||
)?;
|
||||
}
|
||||
|
||||
("Ljava/lang/Object;", data.into())
|
||||
}
|
||||
JsonValue::Object(val) => {
|
||||
let js_object_class =
|
||||
runtime_handle.find_class(env, activity, "app/tauri/plugin/JSObject")?;
|
||||
let data = env.new_object(js_object_class, "()V", &[])?;
|
||||
|
||||
for (key, value) in val {
|
||||
let (signature, val) =
|
||||
json_to_java::<R>(env, activity, runtime_handle, value)?;
|
||||
env.call_method(
|
||||
data,
|
||||
"put",
|
||||
format!("(Ljava/lang/String;{signature})Lapp/tauri/plugin/JSObject;"),
|
||||
&[env.new_string(&key)?.into(), val],
|
||||
)?;
|
||||
}
|
||||
|
||||
("Ljava/lang/Object;", data.into())
|
||||
}
|
||||
};
|
||||
Ok((class, v))
|
||||
}
|
||||
|
||||
fn to_jsobject<'a, R: Runtime>(
|
||||
env: JNIEnv<'a>,
|
||||
activity: JObject<'a>,
|
||||
runtime_handle: &R::Handle,
|
||||
json: JsonValue,
|
||||
) -> Result<JValue<'a>, JniError> {
|
||||
if let JsonValue::Object(_) = &json {
|
||||
json_to_java::<R>(env, activity, runtime_handle, json)
|
||||
.map(|(_class, data)| data)
|
||||
} else {
|
||||
Ok(JObject::null().into())
|
||||
}
|
||||
}
|
||||
use crate::api::ipc::CallbackFn;
|
||||
|
||||
fn handle_message<R: Runtime>(
|
||||
plugin: &str,
|
||||
@ -1459,7 +1382,7 @@ impl<R: Runtime> Window<R> {
|
||||
activity: JObject<'_>,
|
||||
webview: JObject<'_>,
|
||||
) -> Result<(), JniError> {
|
||||
let data = to_jsobject::<R>(env, activity, runtime_handle, message.payload)?;
|
||||
let data = crate::jni_helpers::to_jsobject::<R>(env, activity, runtime_handle, message.payload)?;
|
||||
let plugin_manager = env
|
||||
.call_method(
|
||||
activity,
|
||||
@ -1471,7 +1394,7 @@ impl<R: Runtime> Window<R> {
|
||||
|
||||
env.call_method(
|
||||
plugin_manager,
|
||||
"postMessage",
|
||||
"postIpcMessage",
|
||||
"(Landroid/webkit/WebView;Ljava/lang/String;Ljava/lang/String;Lapp/tauri/plugin/JSObject;JJ)V",
|
||||
&[
|
||||
webview.into(),
|
||||
|
7
examples/api/src-tauri/Cargo.lock
generated
7
examples/api/src-tauri/Cargo.lock
generated
@ -2052,12 +2052,6 @@ dependencies = [
|
||||
"windows-sys 0.45.0",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "paste"
|
||||
version = "1.0.11"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "d01a5bd0424d00070b0098dd17ebca6f961a959dead1dbcbbbc1d1cd8d3deeba"
|
||||
|
||||
[[package]]
|
||||
name = "pathdiff"
|
||||
version = "0.2.1"
|
||||
@ -3028,7 +3022,6 @@ dependencies = [
|
||||
"open",
|
||||
"os_info",
|
||||
"os_pipe",
|
||||
"paste",
|
||||
"percent-encoding",
|
||||
"png",
|
||||
"rand 0.8.5",
|
||||
|
@ -94,6 +94,16 @@ impl AppBuilder {
|
||||
#[cfg(debug_assertions)]
|
||||
window.open_devtools();
|
||||
|
||||
#[cfg(target_os = "android")]
|
||||
{
|
||||
let response = app.run_android_plugin::<serde_json::Value, serde_json::Value>(
|
||||
"sample",
|
||||
"ping",
|
||||
serde_json::Value::default(),
|
||||
);
|
||||
println!("got response: {:?}", response);
|
||||
}
|
||||
|
||||
std::thread::spawn(|| {
|
||||
let server = match tiny_http::Server::http("localhost:3003") {
|
||||
Ok(s) => s,
|
||||
|
@ -7,7 +7,7 @@ import app.tauri.Logger
|
||||
|
||||
class Invoke(
|
||||
private val sendResponse: (succcess: PluginResult?, error: PluginResult?) -> Unit,
|
||||
val data: JSObject?) {
|
||||
val data: JSObject) {
|
||||
|
||||
fun resolve(data: JSObject?) {
|
||||
val result = PluginResult(data)
|
||||
@ -68,7 +68,7 @@ class Invoke(
|
||||
}
|
||||
|
||||
fun getString(name: String, defaultValue: String?): String? {
|
||||
val value = data!!.opt(name) ?: return defaultValue
|
||||
val value = data.opt(name) ?: return defaultValue
|
||||
return if (value is String) {
|
||||
value
|
||||
} else defaultValue
|
||||
@ -79,7 +79,7 @@ class Invoke(
|
||||
}
|
||||
|
||||
fun getInt(name: String, defaultValue: Int?): Int? {
|
||||
val value = data!!.opt(name) ?: return defaultValue
|
||||
val value = data.opt(name) ?: return defaultValue
|
||||
return if (value is Int) {
|
||||
value
|
||||
} else defaultValue
|
||||
@ -90,7 +90,7 @@ class Invoke(
|
||||
}
|
||||
|
||||
fun getLong(name: String, defaultValue: Long?): Long? {
|
||||
val value = data!!.opt(name) ?: return defaultValue
|
||||
val value = data.opt(name) ?: return defaultValue
|
||||
return if (value is Long) {
|
||||
value
|
||||
} else defaultValue
|
||||
@ -101,7 +101,7 @@ class Invoke(
|
||||
}
|
||||
|
||||
fun getFloat(name: String, defaultValue: Float?): Float? {
|
||||
val value = data!!.opt(name) ?: return defaultValue
|
||||
val value = data.opt(name) ?: return defaultValue
|
||||
if (value is Float) {
|
||||
return value
|
||||
}
|
||||
@ -118,7 +118,7 @@ class Invoke(
|
||||
}
|
||||
|
||||
fun getDouble(name: String, defaultValue: Double?): Double? {
|
||||
val value = data!!.opt(name) ?: return defaultValue
|
||||
val value = data.opt(name) ?: return defaultValue
|
||||
if (value is Double) {
|
||||
return value
|
||||
}
|
||||
@ -135,7 +135,7 @@ class Invoke(
|
||||
}
|
||||
|
||||
fun getBoolean(name: String, defaultValue: Boolean?): Boolean? {
|
||||
val value = data!!.opt(name) ?: return defaultValue
|
||||
val value = data.opt(name) ?: return defaultValue
|
||||
return if (value is Boolean) {
|
||||
value
|
||||
} else defaultValue
|
||||
@ -146,7 +146,7 @@ class Invoke(
|
||||
}
|
||||
|
||||
fun getObject(name: String, defaultValue: JSObject?): JSObject? {
|
||||
val value = data!!.opt(name) ?: return defaultValue
|
||||
val value = data.opt(name) ?: return defaultValue
|
||||
return if (value is JSObject) value else defaultValue
|
||||
}
|
||||
|
||||
@ -155,11 +155,11 @@ class Invoke(
|
||||
}
|
||||
|
||||
fun getArray(name: String, defaultValue: JSArray?): JSArray? {
|
||||
val value = data!!.opt(name) ?: return defaultValue
|
||||
val value = data.opt(name) ?: return defaultValue
|
||||
return if (value is JSArray) value else defaultValue
|
||||
}
|
||||
|
||||
fun hasOption(name: String): Boolean {
|
||||
return data!!.has(name)
|
||||
return data.has(name)
|
||||
}
|
||||
}
|
||||
|
@ -22,12 +22,7 @@ class PluginManager {
|
||||
}
|
||||
}
|
||||
|
||||
fun postMessage(webView: WebView, pluginId: String, methodName: String, data: JSObject, callback: Long, error: Long) {
|
||||
Logger.verbose(
|
||||
Logger.tags("Plugin"),
|
||||
"Tauri plugin: pluginId: $pluginId, methodName: $methodName, callback: $callback, error: $error"
|
||||
)
|
||||
|
||||
fun postIpcMessage(webView: WebView, pluginId: String, methodName: String, data: JSObject, callback: Long, error: Long) {
|
||||
val invoke = Invoke({ successResult, errorResult ->
|
||||
val (fn, result) = if (errorResult == null) Pair(callback, successResult) else Pair(
|
||||
error,
|
||||
@ -35,6 +30,24 @@ class PluginManager {
|
||||
)
|
||||
webView.evaluateJavascript("window['_$fn']($result)", null)
|
||||
}, data)
|
||||
|
||||
dispatchPluginMessage(invoke, pluginId, methodName)
|
||||
}
|
||||
|
||||
fun runPluginMethod(id: Int, pluginId: String, methodName: String, data: JSObject) {
|
||||
val invoke = Invoke({ successResult, errorResult ->
|
||||
handlePluginResponse(id, successResult?.toString(), errorResult?.toString())
|
||||
}, data)
|
||||
|
||||
dispatchPluginMessage(invoke, pluginId, methodName)
|
||||
}
|
||||
|
||||
private fun dispatchPluginMessage(invoke: Invoke, pluginId: String, methodName: String) {
|
||||
Logger.verbose(
|
||||
Logger.tags("Plugin"),
|
||||
"Tauri plugin: pluginId: $pluginId, methodName: $methodName"
|
||||
)
|
||||
|
||||
try {
|
||||
val plugin = plugins[pluginId]
|
||||
if (plugin == null) {
|
||||
@ -46,4 +59,6 @@ class PluginManager {
|
||||
invoke.reject(e.toString())
|
||||
}
|
||||
}
|
||||
|
||||
private external fun handlePluginResponse(id: Int, success: String?, error: String?)
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user