Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

refactor(core): use webview's URI schemes for IPC #7170

Merged
merged 101 commits into from
Aug 10, 2023
Merged
Show file tree
Hide file tree
Changes from 96 commits
Commits
Show all changes
101 commits
Select commit Hold shift + click to select a range
3423f4e
refactor(core): use custom protocol for the IPC
lucasfernog Jun 8, 2023
fef3bf3
fix isolation check, respond
lucasfernog Jun 8, 2023
31ad027
feat: allow reading raw request and returning raw response bytes
lucasfernog Jun 8, 2023
7b9cd47
mobile impl [skip ci]
lucasfernog Jun 10, 2023
d4ae4ca
lint
lucasfernog Jun 10, 2023
02e39d5
fix tests [skip ci]
lucasfernog Jun 10, 2023
09c6d96
use current ipc on linux :(
lucasfernog Jun 11, 2023
6cbba9c
simplify cfg
lucasfernog Jun 11, 2023
82153f2
fix mobile build
lucasfernog Jun 11, 2023
868bef0
api format
lucasfernog Jun 11, 2023
431cf07
fix windows build
lucasfernog Jun 11, 2023
acff528
use the custom protocol IPC on channel.send
lucasfernog Jun 11, 2023
b4c888a
move format_callback to its own module, remove from public API
lucasfernog Jun 11, 2023
8c5ac32
add header, fix linux build
lucasfernog Jun 11, 2023
65e5c01
move hooks.rs to ipc.rs, move api::ipc to root
lucasfernog Jun 11, 2023
073f63a
fix mobile build
lucasfernog Jun 11, 2023
3d702b5
Merge remote-tracking branch 'origin/next' into feat/ipc-custom-protocol
lucasfernog Jun 11, 2023
a329082
headers
lucasfernog Jun 11, 2023
596968d
avoid into_json call so we dont need to clone
lucasfernog Jun 11, 2023
c5b841b
remove linux-protocol-headers feature from ci
lucasfernog Jun 11, 2023
da2d00b
use custom protocol on linux!!!!!!!!
lucasfernog Jun 12, 2023
6ca0f31
Revert "use custom protocol on linux!!!!!!!!"
lucasfernog Jun 12, 2023
e5397d3
feature flag for linux body, use protocol to send big responses
lucasfernog Jun 12, 2023
e4526d1
fix isIsolationMessage check when payload is empty
lucasfernog Jun 12, 2023
675bdaa
rename feature to linux-ipc-protocol
lucasfernog Jun 12, 2023
5372436
fix ipc JS script with linux-ipc-protocol feature flag
lucasfernog Jun 12, 2023
b35210b
fmt
lucasfernog Jun 12, 2023
c3306c0
update lockfile
lucasfernog Jun 12, 2023
307af2c
move protocol handlers to separate module
lucasfernog Jun 12, 2023
589353f
fix isolation build
lucasfernog Jun 12, 2023
f01d3e7
add header
lucasfernog Jun 12, 2023
1e5e18e
fix mobile build
lucasfernog Jun 12, 2023
4f086dc
fix linux ipc message handler build
lucasfernog Jun 12, 2023
157debd
use postMessage IPC on Android
lucasfernog Jun 13, 2023
f923c29
simplify proces-ipc-message-fn
lucasfernog Jun 13, 2023
909f4ca
remove test code [skip ci]
lucasfernog Jun 13, 2023
14c78c5
wry 0.29 [skip ci]
lucasfernog Jun 13, 2023
928d8ef
enhance ipc-protocol.js platform detection
lucasfernog Jun 13, 2023
f35e9f2
Merge remote-tracking branch 'origin/dev' into feat/ipc-custom-protocol
lucasfernog Jun 16, 2023
3d32784
fix isolation message detection
lucasfernog Jun 16, 2023
ae06dc1
Merge branch 'dev' into feat/ipc-custom-protocol
lucasfernog Jun 19, 2023
53f24b5
update CSP
lucasfernog Jun 19, 2023
4262dfb
Merge remote-tracking branch 'origin/dev' into feat/ipc-custom-protocol
lucasfernog Jun 19, 2023
3bc3cd8
speed up benchmark
lucasfernog Jun 19, 2023
64d2007
impl channel on android [skip ci]
lucasfernog Jun 22, 2023
19addfc
fix mobile response [skip ci]
lucasfernog Jun 22, 2023
b7a4655
impl iOS
lucasfernog Jun 22, 2023
99a2730
load channels on direct IPC messages to mobile plugins
lucasfernog Jun 22, 2023
0dee01d
fix getChannel when it is not defined
lucasfernog Jun 22, 2023
3929578
refactor channel to support Rust message handler and simplify usage
lucasfernog Jun 22, 2023
c8efbdc
change files
lucasfernog Jun 22, 2023
970547b
turn channel data handler into a plugin
lucasfernog Jun 23, 2023
f4c2c56
update InvokeArgs type
lucasfernog Jun 23, 2023
162299b
expose request headers
lucasfernog Jun 23, 2023
12a866f
change api example to return object
lucasfernog Jun 23, 2023
a72f660
fix usage with linux-ipc-protocol feature
lucasfernog Jun 23, 2023
fb6cbc2
handle null payload on isolation script
lucasfernog Jun 23, 2023
e442f79
change if/else blocks to simplify condition
lucasfernog Jun 23, 2023
9992bc8
remove println
lucasfernog Jun 23, 2023
b8a91d8
headers must be owned
lucasfernog Jun 23, 2023
dc5e6d8
send options on ipc.postMessage
lucasfernog Jun 23, 2023
f17bb70
fix tests
lucasfernog Jun 23, 2023
7541893
handle options on isolation pattern
lucasfernog Jun 23, 2023
76e0fe6
allow channel plugin to be executed on remote domains
lucasfernog Jun 24, 2023
f667667
delete unused script
lucasfernog Jun 24, 2023
b83af1b
header
lucasfernog Jun 24, 2023
2242aa2
format
lucasfernog Jun 24, 2023
f4c8f2f
move ipc to connect-src CSP
lucasfernog Jun 24, 2023
11935b6
rebuild example
lucasfernog Jun 24, 2023
cb05f57
feat(cli): update config migration script to add `ipc:` to CSP
lucasfernog Jun 24, 2023
c909987
do not use navigator.userAgent on convertFileSrc
lucasfernog Jun 27, 2023
60ae63b
fix warning [skip ci]
lucasfernog Jul 11, 2023
2bddd93
move declare global
lucasfernog Jul 11, 2023
9ab3b8f
Merge branch 'dev' into feat/ipc-custom-protocol
lucasfernog Jul 11, 2023
f450e30
fix csp
lucasfernog Jul 11, 2023
5b63121
Merge remote-tracking branch 'origin/dev' into feat/ipc-custom-protocol
lucasfernog Jul 17, 2023
0d69873
change channel id to u32
lucasfernog Jul 17, 2023
52e7799
fix linux tests
lucasfernog Jul 17, 2023
3e04d52
Merge remote-tracking branch 'origin/dev' into feat/ipc-custom-protocol
lucasfernog Jul 17, 2023
b6bd17e
Merge remote-tracking branch 'origin/dev' into feat/ipc-custom-protocol
lucasfernog Jul 19, 2023
46e7d58
Merge remote-tracking branch 'origin/dev' into feat/ipc-custom-protocol
lucasfernog Jul 19, 2023
7536e24
rename ChannelDataCache to ChannelDataIpcQueue
lucasfernog Aug 9, 2023
75220d9
use constants for header names
lucasfernog Aug 9, 2023
1586b2c
create isolation message obj with Object.create(null)
lucasfernog Aug 9, 2023
b667799
Update core/tauri/scripts/ipc-protocol.js [skip ci]
lucasfernog Aug 9, 2023
b5b1801
Update core/tauri/scripts/ipc-protocol.js [skip ci]
lucasfernog Aug 9, 2023
9248033
Update tooling/api/src/tauri.ts [skip ci]
lucasfernog Aug 9, 2023
3fdba5f
Update core/tauri/src/ipc/protocol.rs [skip ci]
lucasfernog Aug 9, 2023
2012020
use mime crate
lucasfernog Aug 9, 2023
0c00fe9
Merge remote-tracking branch 'lucasfernog/feat/ipc-custom-protocol' i…
lucasfernog Aug 9, 2023
7e37cfe
no need for fn to be unsafe, document
lucasfernog Aug 9, 2023
b74c31d
Merge remote-tracking branch 'origin/dev' into feat/ipc-custom-protocol
lucasfernog Aug 9, 2023
4d60e94
fix example
lucasfernog Aug 9, 2023
f47e300
remove old sendMessage call
lucasfernog Aug 9, 2023
1e8513a
Update core/tauri/scripts/process-ipc-message-fn.js
lucasfernog Aug 9, 2023
fecca1e
downgrade time
lucasfernog Aug 8, 2023
1336951
move tauri-channel-id to const
lucasfernog Aug 10, 2023
c2b8f10
remove semicolon
lucasfernog Aug 10, 2023
7023920
use mime crate
lucasfernog Aug 10, 2023
2353a63
add comment [skip ci]
lucasfernog Aug 10, 2023
f592964
use mime for last missed literal
chippers Aug 10, 2023
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
5 changes: 5 additions & 0 deletions .changes/channel-rust.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
---
"tauri": patch:enhance
---

Added `Channel::new` allowing communication from a mobile plugin with Rust.
6 changes: 6 additions & 0 deletions .changes/ipc-custom-protocol.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
---
"tauri": patch:enhance
"tauri-utils": patch:enhance
---

Use custom protocols on the IPC implementation to enhance performance.
6 changes: 6 additions & 0 deletions .changes/ipc-refactor.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
---
"tauri": patch:breaking
"tauri-macros": patch:breaking
---

Moved `tauri::api::ipc` to `tauri::ipc` and refactored all types.
5 changes: 5 additions & 0 deletions .changes/linux-ipc-body-feature.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
---
"tauri": patch:breaking
---

Removed the `linux-protocol-headers` feature (now always enabled) and added `linux-ipc-protocol`.
5 changes: 5 additions & 0 deletions .changes/linux-protocol-body-feature.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
---
"tauri-runtime-wry": patch:breaking
---

Removed the `linux-headers` feature (now always enabled) and added `linux-protocol-body`.
6 changes: 6 additions & 0 deletions .changes/migrate-csp.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
---
"tauri-cli": patch:enhance
"@tauri-apps/cli": patch:enhance
---

Update migrate command to update the configuration CSP to include `ipc:` on the `connect-src` directive, needed by the new IPC using custom protocols.
2 changes: 1 addition & 1 deletion .github/workflows/lint-core.yml
Original file line number Diff line number Diff line change
Expand Up @@ -50,7 +50,7 @@ jobs:
clippy:
- { args: '', key: 'empty' }
- {
args: '--features compression,wry,linux-protocol-headers,isolation,custom-protocol,system-tray,test',
args: '--features compression,wry,isolation,custom-protocol,system-tray,test',
key: 'all'
}
- { args: '--features custom-protocol', key: 'custom-protocol' }
Expand Down
7 changes: 6 additions & 1 deletion .github/workflows/test-core.yml
Original file line number Diff line number Diff line change
Expand Up @@ -72,7 +72,7 @@ jobs:
key: no-default
}
- {
args: --features compression,wry,linux-protocol-headers,isolation,custom-protocol,system-tray,test,
args: --features compression,wry,isolation,custom-protocol,system-tray,test,
key: all
}

Expand All @@ -98,6 +98,11 @@ jobs:
workspaces: core -> ../target
save-if: ${{ matrix.features.key == 'all' }}

- name: Downgrade crates with MSRV conflict
# The --precise flag can only be used once per invocation.
run: |
cargo update -p time --precise 0.3.23

- name: test
uses: actions-rs/cargo@v1
with:
Expand Down
2 changes: 1 addition & 1 deletion core/tauri-macros/src/command/wrapper.rs
Original file line number Diff line number Diff line change
Expand Up @@ -211,7 +211,7 @@ pub fn wrapper(attributes: TokenStream, item: TokenStream) -> TokenStream {
use #root::command::private::*;
// prevent warnings when the body is a `compile_error!` or if the command has no arguments
#[allow(unused_variables)]
let #root::Invoke { message: #message, resolver: #resolver } = $invoke;
let #root::ipc::Invoke { message: #message, resolver: #resolver } = $invoke;

#body
}};
Expand Down
2 changes: 1 addition & 1 deletion core/tauri-runtime-wry/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -48,4 +48,4 @@ macos-private-api = [
"tauri-runtime/macos-private-api"
]
objc-exception = [ "wry/objc-exception" ]
linux-headers = [ ]
linux-protocol-body = [ "wry/linux-body", "webkit2gtk/v2_40" ]
35 changes: 18 additions & 17 deletions core/tauri-runtime-wry/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -3085,17 +3085,14 @@ fn create_webview<T: UserEvent>(
webview_attributes,
uri_scheme_protocols,
mut window_builder,
ipc_handler,
label,
ipc_handler,
url,
menu_ids,
#[cfg(target_os = "android")]
on_webview_created,
..
} = pending;
let webview_id_map = context.webview_id_map.clone();
#[cfg(windows)]
let proxy = context.proxy.clone();

let window_event_listeners = WindowEventListeners::default();

Expand All @@ -3108,6 +3105,8 @@ fn create_webview<T: UserEvent>(

#[cfg(windows)]
let window_theme = window_builder.inner.window.preferred_theme;
#[cfg(windows)]
let proxy = context.proxy.clone();

#[cfg(target_os = "macos")]
{
Expand All @@ -3130,7 +3129,7 @@ fn create_webview<T: UserEvent>(
};
let window = window_builder.inner.build(event_loop).unwrap();

webview_id_map.insert(window.id(), window_id);
context.webview_id_map.insert(window.id(), window_id);

if window_builder.center {
let _ = center_window(&window, window.inner_size());
Expand All @@ -3157,17 +3156,18 @@ fn create_webview<T: UserEvent>(
}

#[cfg(windows)]
if let Some(additional_browser_args) = webview_attributes.additional_browser_args {
webview_builder = webview_builder.with_additional_browser_args(&additional_browser_args);
}
{
if let Some(additional_browser_args) = webview_attributes.additional_browser_args {
webview_builder = webview_builder.with_additional_browser_args(&additional_browser_args);
}

#[cfg(windows)]
if let Some(theme) = window_theme {
webview_builder = webview_builder.with_theme(match theme {
WryTheme::Dark => wry::webview::Theme::Dark,
WryTheme::Light => wry::webview::Theme::Light,
_ => wry::webview::Theme::Light,
});
if let Some(theme) = window_theme {
webview_builder = webview_builder.with_theme(match theme {
WryTheme::Dark => wry::webview::Theme::Dark,
WryTheme::Light => wry::webview::Theme::Light,
_ => wry::webview::Theme::Light,
});
}
}

if let Some(handler) = ipc_handler {
Expand All @@ -3178,6 +3178,7 @@ fn create_webview<T: UserEvent>(
handler,
));
}

for (scheme, protocol) in uri_scheme_protocols {
webview_builder = webview_builder.with_custom_protocol(scheme, move |wry_request| {
protocol(&HttpRequestWrapper::from(wry_request).0)
Expand Down Expand Up @@ -3254,7 +3255,7 @@ fn create_webview<T: UserEvent>(
unsafe {
controller.add_GotFocus(
&FocusChangedEventHandler::create(Box::new(move |_, _| {
let _ = proxy_.send_event(Message::Webview(
let _ = proxy.send_event(Message::Webview(
window_id,
WebviewMessage::WebviewEvent(WebviewEvent::Focused(true)),
));
Expand All @@ -3267,7 +3268,7 @@ fn create_webview<T: UserEvent>(
unsafe {
controller.add_LostFocus(
&FocusChangedEventHandler::create(Box::new(move |_, _| {
let _ = proxy.send_event(Message::Webview(
let _ = proxy_.send_event(Message::Webview(
window_id,
WebviewMessage::WebviewEvent(WebviewEvent::Focused(false)),
));
Expand Down
50 changes: 37 additions & 13 deletions core/tauri-utils/src/pattern/isolation.js
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,8 @@
* isolation frame -> main frame = isolation message
*/

;(async function () {
;
(async function () {
/**
* Sends the message to the isolation frame.
* @param {any} message
Expand Down Expand Up @@ -38,34 +39,52 @@
* @return {Promise<{nonce: number[], payload: number[]}>}
*/
async function encrypt(data) {
let algorithm = Object.create(null)
const algorithm = Object.create(null)
algorithm.name = 'AES-GCM'
algorithm.iv = window.crypto.getRandomValues(new Uint8Array(12))

let encoder = new TextEncoder()
let payloadRaw = encoder.encode(__RAW_stringify_ipc_message_fn__(data))
const encoder = new TextEncoder()
const encoded = encoder.encode(__RAW_process_ipc_message_fn__(data).data)

return window.crypto.subtle
.encrypt(algorithm, aesGcmKey, payloadRaw)
.encrypt(algorithm, aesGcmKey, encoded)
.then((payload) => {
let result = Object.create(null)
const result = Object.create(null)
result.nonce = Array.from(new Uint8Array(algorithm.iv))
result.payload = Array.from(new Uint8Array(payload))
return result
})
}

/**
* Detects if a message event is a valid isolation message.
*
* @param {MessageEvent<object>} event - a message event that is expected to be an isolation message
* @return {boolean} - if the event was a valid isolation message
*/
function isIsolationMessage(data) {
if (typeof data === 'object' && typeof data.payload === 'object') {
const keys = data.payload ? Object.keys(data.payload) : []
return (
keys.length > 0 &&
keys.every((key) => key === 'nonce' || key === 'payload')
)
}
return false
}

/**
* Detect if a message event is a valid isolation payload.
*
* @param {MessageEvent<object>} event - a message event that is expected to be an isolation payload
* @return boolean
*/
function isIsolationPayload(event) {
function isIsolationPayload(data) {
return (
typeof event.data === 'object' &&
'callback' in event.data &&
'error' in event.data
typeof data === 'object' &&
'callback' in data &&
'error' in data &&
!isIsolationMessage(data)
)
}

Expand All @@ -74,7 +93,7 @@
* @param {MessageEvent<any>} event
*/
async function payloadHandler(event) {
if (!isIsolationPayload(event)) {
if (!isIsolationPayload(event.data)) {
return
}

Expand All @@ -85,8 +104,13 @@
data = await window.__TAURI_ISOLATION_HOOK__(data)
}

const encrypted = await encrypt(data)
sendMessage(encrypted)
const message = Object.create(null)
message.cmd = data.cmd
message.callback = data.callback
message.error = data.error
message.options = data.options
message.payload = await encrypt(data.payload)
sendMessage(message)
}

window.addEventListener('message', payloadHandler, false)
Expand Down
18 changes: 8 additions & 10 deletions core/tauri-utils/src/pattern/isolation.rs
Original file line number Diff line number Diff line change
Expand Up @@ -96,16 +96,14 @@ impl Keys {
}

/// Decrypts a message using the generated keys.
pub fn decrypt(&self, raw: RawIsolationPayload<'_>) -> Result<String, Error> {
pub fn decrypt(&self, raw: RawIsolationPayload<'_>) -> Result<Vec<u8>, Error> {
let RawIsolationPayload { nonce, payload } = raw;
let nonce: [u8; 12] = nonce.as_ref().try_into()?;
let bytes = self
self
.aes_gcm
.key
.decrypt(Nonce::from_slice(&nonce), payload.as_ref())
.map_err(|_| self::Error::Aes)?;

String::from_utf8(bytes).map_err(Into::into)
.map_err(|_| self::Error::Aes)
}
}

Expand All @@ -116,11 +114,11 @@ pub struct RawIsolationPayload<'a> {
payload: Cow<'a, [u8]>,
}

impl<'a> TryFrom<&'a str> for RawIsolationPayload<'a> {
impl<'a> TryFrom<&'a Vec<u8>> for RawIsolationPayload<'a> {
type Error = Error;

fn try_from(value: &'a str) -> Result<Self, Self::Error> {
serde_json::from_str(value).map_err(Into::into)
fn try_from(value: &'a Vec<u8>) -> Result<Self, Self::Error> {
serde_json::from_slice(value).map_err(Into::into)
}
}

Expand All @@ -141,9 +139,9 @@ pub struct IsolationJavascriptCodegen {
pub struct IsolationJavascriptRuntime<'a> {
/// The key used on the Rust backend and the Isolation Javascript
pub runtime_aes_gcm_key: &'a [u8; 32],
/// The function that stringifies a IPC message.
/// The function that processes the IPC message.
#[raw]
pub stringify_ipc_message_fn: &'a str,
pub process_ipc_message_fn: &'a str,
}

#[cfg(test)]
Expand Down
3 changes: 2 additions & 1 deletion core/tauri/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -61,6 +61,7 @@ reqwest = { version = "0.11", default-features = false, features = [ "json", "st
bytes = { version = "1", features = [ "serde" ] }
raw-window-handle = "0.5"
glob = "0.3"
mime = "0.3"
data-url = { version = "0.2", optional = true }
serialize-to-javascript = "=0.1.1"
infer = { version = "0.9", optional = true }
Expand Down Expand Up @@ -118,7 +119,7 @@ test = [ ]
compression = [ "tauri-macros/compression", "tauri-utils/compression" ]
wry = [ "tauri-runtime-wry" ]
objc-exception = [ "tauri-runtime-wry/objc-exception" ]
linux-protocol-headers = [ "tauri-runtime-wry/linux-headers", "webkit2gtk/v2_36" ]
linux-ipc-protocol = [ "tauri-runtime-wry/linux-protocol-body", "webkit2gtk/v2_40" ]
isolation = [ "tauri-utils/isolation", "tauri-macros/isolation" ]
custom-protocol = [ "tauri-macros/custom-protocol" ]
native-tls = [ "reqwest/native-tls" ]
Expand Down
5 changes: 5 additions & 0 deletions core/tauri/build.rs
Original file line number Diff line number Diff line change
Expand Up @@ -50,6 +50,11 @@ fn main() {
alias("desktop", !mobile);
alias("mobile", mobile);

alias(
"ipc_custom_protocol",
target_os != "android" && (target_os != "linux" || has_feature("linux-ipc-protocol")),
);

let checked_features_out_path = Path::new(&var("OUT_DIR").unwrap()).join("checked_features");
std::fs::write(
checked_features_out_path,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@ class Invoke(
val callback: Long,
val error: Long,
private val sendResponse: (callback: Long, data: PluginResult?) -> Unit,
private val sendChannelData: (channelId: Long, data: PluginResult) -> Unit,
val data: JSObject) {

fun resolve(data: JSObject?) {
Expand Down Expand Up @@ -205,6 +206,6 @@ class Invoke(
fun getChannel(name: String): Channel? {
val channelDef = getString(name, "")
val callback = channelDef.substring(CHANNEL_PREFIX.length).toLongOrNull() ?: return null
return Channel(callback) { res -> sendResponse(callback, PluginResult(res)) }
return Channel(callback) { res -> sendChannelData(callback, PluginResult(res)) }
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -85,15 +85,6 @@ class PluginManager(val activity: AppCompatActivity) {
}
}

@JniMethod
fun postIpcMessage(webView: WebView, pluginId: String, command: String, data: JSObject, callback: Long, error: Long) {
val invoke = Invoke(callback, command, callback, error, { fn, result ->
webView.evaluateJavascript("window['_$fn']($result)", null)
}, data)

dispatchPluginMessage(invoke, pluginId)
}

@JniMethod
fun runCommand(id: Int, pluginId: String, command: String, data: JSObject) {
val successId = 0L
Expand All @@ -107,6 +98,8 @@ class PluginManager(val activity: AppCompatActivity) {
error = result
}
handlePluginResponse(id, success?.toString(), error?.toString())
}, { channelId, payload ->
sendChannelData(channelId, payload.toString())
}, data)

dispatchPluginMessage(invoke, pluginId)
Expand Down Expand Up @@ -140,4 +133,5 @@ class PluginManager(val activity: AppCompatActivity) {
}

private external fun handlePluginResponse(id: Int, success: String?, error: String?)
private external fun sendChannelData(id: Long, data: String)
}
Loading
Loading