@@ -13,6 +13,8 @@ use crate::{
13
13
14
14
#[ cfg( mobile) ]
15
15
use std:: sync:: atomic:: { AtomicI32 , Ordering } ;
16
+ #[ cfg( mobile) ]
17
+ use tokio:: sync:: oneshot;
16
18
17
19
use serde:: { de:: DeserializeOwned , Serialize } ;
18
20
@@ -279,6 +281,38 @@ impl<R: Runtime, C: DeserializeOwned> PluginApi<R, C> {
279
281
}
280
282
281
283
impl < R : Runtime > PluginHandle < R > {
284
+ /// Executes the given mobile command.
285
+ /// This is an async optimized variant of run_mobile_plugin
286
+ pub async fn run_mobile_plugin_async < T : DeserializeOwned > (
287
+ & self ,
288
+ command : impl AsRef < str > ,
289
+ payload : impl Serialize ,
290
+ ) -> Result < T , PluginInvokeError > {
291
+ let ( tx, rx) = oneshot:: channel ( ) ;
292
+ // the closure is an FnOnce but on Android we need to clone it (error handling)
293
+ let tx = std:: sync:: Arc :: new ( std:: sync:: Mutex :: new ( Some ( tx) ) ) ;
294
+ run_command (
295
+ self . name ,
296
+ & self . handle ,
297
+ command,
298
+ serde_json:: to_value ( payload) . map_err ( PluginInvokeError :: CannotSerializePayload ) ?,
299
+ move |response| {
300
+ tx. lock ( ) . unwrap ( ) . take ( ) . unwrap ( ) . send ( response) . unwrap ( ) ;
301
+ } ,
302
+ ) ?;
303
+
304
+ let response = rx. await . unwrap ( ) ;
305
+
306
+ match response {
307
+ Ok ( r) => serde_json:: from_value ( r) . map_err ( PluginInvokeError :: CannotDeserializeResponse ) ,
308
+ Err ( r) => Err (
309
+ serde_json:: from_value :: < ErrorResponse > ( r)
310
+ . map ( Into :: into)
311
+ . map_err ( PluginInvokeError :: CannotDeserializeResponse ) ?,
312
+ ) ,
313
+ }
314
+ }
315
+
282
316
/// Executes the given mobile command.
283
317
pub fn run_mobile_plugin < T : DeserializeOwned > (
284
318
& self ,
0 commit comments