Selaa lähdekoodia

feat(android): with_webview access for jni execution (#5148)

Jeffrey Hutchins 2 vuotta sitten
vanhempi
sitoutus
8ea87e9c9c

+ 6 - 0
.changes/mobile-webview-access.md

@@ -0,0 +1,6 @@
+---
+"tauri-runtime-wry": minor
+"tauri": minor
+---
+
+Support `with_webview` for Android platform alowing execution of JNI code in context. 

+ 10 - 6
core/tauri-runtime-wry/src/lib.rs

@@ -102,9 +102,9 @@ type FileDropHandler = dyn Fn(&Window, WryFileDropEvent) -> bool + 'static;
 #[cfg(all(desktop, feature = "system-tray"))]
 pub use tauri_runtime::TrayId;
 
-#[cfg(desktop)]
+#[cfg(any(desktop, target_os = "android"))]
 mod webview;
-#[cfg(desktop)]
+#[cfg(any(desktop, target_os = "android"))]
 pub use webview::Webview;
 
 #[cfg(all(desktop, feature = "system-tray"))]
@@ -987,7 +987,7 @@ pub struct RawWindowHandle(pub raw_window_handle::RawWindowHandle);
 unsafe impl Send for RawWindowHandle {}
 
 pub enum WindowMessage {
-  #[cfg(desktop)]
+  #[cfg(any(desktop, target_os = "android"))]
   WithWebview(Box<dyn FnOnce(Webview) + Send>),
   AddEventListener(Uuid, Box<dyn Fn(&WindowEvent) + Send>),
   AddMenuEventListener(Uuid, Box<dyn Fn(&MenuEvent) + Send>),
@@ -1133,7 +1133,7 @@ pub struct WryDispatcher<T: UserEvent> {
 unsafe impl<T: UserEvent> Sync for WryDispatcher<T> {}
 
 impl<T: UserEvent> WryDispatcher<T> {
-  #[cfg(desktop)]
+  #[cfg(any(desktop, target_os = "android"))]
   pub fn with_webview<F: FnOnce(Webview) + Send + 'static>(&self, f: F) -> Result<()> {
     send_user_message(
       &self.context,
@@ -2166,7 +2166,7 @@ fn handle_user_message<T: UserEvent>(
         });
         if let Some((Some(window), window_event_listeners, menu_event_listeners)) = w {
           match window_message {
-            #[cfg(desktop)]
+            #[cfg(any(target_os = "android", desktop))]
             WindowMessage::WithWebview(f) => {
               if let WindowHandle::Webview(w) = window {
                 #[cfg(any(
@@ -2189,13 +2189,17 @@ fn handle_user_message<T: UserEvent>(
                     ns_window: w.ns_window(),
                   });
                 }
-
                 #[cfg(windows)]
                 {
                   f(Webview {
                     controller: w.controller(),
                   });
                 }
+                #[cfg(target_os = "android")]
+                {
+                  use wry::webview::WebviewExtAndroid;
+                  f(w.handle())
+                }
               }
             }
 

+ 6 - 0
core/tauri-runtime-wry/src/webview.rs

@@ -34,4 +34,10 @@ mod imp {
   }
 }
 
+#[cfg(target_os = "android")]
+mod imp {
+  use wry::webview::JniHandle;
+  pub type Webview = JniHandle;
+}
+
 pub use imp::*;

+ 25 - 5
core/tauri/src/window.rs

@@ -587,11 +587,14 @@ impl<'de, R: Runtime> CommandArg<'de, R> for Window<R> {
 }
 
 /// The platform webview handle. Accessed with [`Window#method.with_webview`];
-#[cfg(all(desktop, feature = "wry"))]
-#[cfg_attr(doc_cfg, doc(cfg(all(desktop, feature = "wry"))))]
+#[cfg(all(any(desktop, target_os = "android"), feature = "wry"))]
+#[cfg_attr(
+  doc_cfg,
+  doc(cfg(all(any(desktop, target_os = "android"), feature = "wry")))
+)]
 pub struct PlatformWebview(tauri_runtime_wry::Webview);
 
-#[cfg(all(desktop, feature = "wry"))]
+#[cfg(all(any(desktop, target_os = "android"), feature = "wry"))]
 impl PlatformWebview {
   /// Returns [`webkit2gtk::WebView`] handle.
   #[cfg(any(
@@ -650,6 +653,12 @@ impl PlatformWebview {
   pub fn ns_window(&self) -> cocoa::base::id {
     self.0.ns_window
   }
+
+  /// Returns handle for JNI execution.
+  #[cfg(target_os = "android")]
+  pub fn jni_handle(&self) -> tauri_runtime_wry::wry::webview::JniHandle {
+    self.0
+  }
 }
 
 /// APIs specific to the wry runtime.
@@ -693,13 +702,24 @@ impl Window<crate::Wry> {
   ///           let bg_color: cocoa::base::id = msg_send![class!(NSColor), colorWithDeviceRed:0.5 green:0.2 blue:0.4 alpha:1.];
   ///           let () = msg_send![webview.ns_window(), setBackgroundColor: bg_color];
   ///         }
+  ///
+  ///         #[cfg(target_os = "android")]
+  ///         {
+  ///           use jni::objects::JValue;
+  ///           webview.jni_handle().exec(|env, _, webview| {
+  ///             env.call_method(webview, "zoomBy", "(F)V", &[JValue::Float(4.)]).unwrap();
+  ///           })
+  ///         }
   ///       });
   ///       Ok(())
   ///   });
   /// }
   /// ```
-  #[cfg(desktop)]
-  #[cfg_attr(doc_cfg, doc(cfg(all(feature = "wry", desktop))))]
+  #[cfg(any(desktop, target_os = "android"))]
+  #[cfg_attr(
+    doc_cfg,
+    doc(cfg(all(feature = "wry", any(desktop, target_os = "android"))))
+  )]
   pub fn with_webview<F: FnOnce(PlatformWebview) + Send + 'static>(
     &self,
     f: F,