From 9183de4f9d3129e7cba332eebca2afc846f727d0 Mon Sep 17 00:00:00 2001 From: Lucas Fernandes Nogueira Date: Mon, 5 Sep 2022 16:01:53 -0300 Subject: [PATCH] feat(android): implement webview_version (#687) --- .changes/android-webview-version.md | 5 +++ src/lib.rs | 3 ++ .../android/kotlin/PermissionHelper.kt | 2 +- .../android/kotlin/RustWebChromeClient.kt | 4 +- src/webview/android/kotlin/RustWebView.kt | 2 + src/webview/android/kotlin/TauriActivity.kt | 39 ++++++++++++++++++- src/webview/android/main_pipe.rs | 15 ++++++- src/webview/android/mod.rs | 5 ++- 8 files changed, 69 insertions(+), 6 deletions(-) create mode 100644 .changes/android-webview-version.md diff --git a/.changes/android-webview-version.md b/.changes/android-webview-version.md new file mode 100644 index 000000000..6773868c3 --- /dev/null +++ b/.changes/android-webview-version.md @@ -0,0 +1,5 @@ +--- +"wry": patch +--- + +Implement `webview_version` on Android. diff --git a/src/lib.rs b/src/lib.rs index 1bb8e1fd7..85eaa7804 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -177,4 +177,7 @@ pub enum Error { InvalidMethod(#[from] InvalidMethod), #[error("Infallible error, something went really wrong: {0}")] Infallible(#[from] std::convert::Infallible), + #[cfg(target_os = "android")] + #[error(transparent)] + JniError(#[from] tao::platform::android::ndk_glue::jni::errors::Error), } diff --git a/src/webview/android/kotlin/PermissionHelper.kt b/src/webview/android/kotlin/PermissionHelper.kt index 07bce9750..f66ef1d0c 100644 --- a/src/webview/android/kotlin/PermissionHelper.kt +++ b/src/webview/android/kotlin/PermissionHelper.kt @@ -78,7 +78,7 @@ object PermissionHelper { var requestedPermissions: Array? = null try { val pm = context.packageManager - val packageInfo = if (Build.VERSION.SDK_INT >= 33) { + val packageInfo = if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.TIRAMISU) { pm.getPackageInfo(context.packageName, PackageManager.PackageInfoFlags.of(PackageManager.GET_PERMISSIONS.toLong())) } else { @Suppress("DEPRECATION") diff --git a/src/webview/android/kotlin/RustWebChromeClient.kt b/src/webview/android/kotlin/RustWebChromeClient.kt index 293f84580..30be14a56 100644 --- a/src/webview/android/kotlin/RustWebChromeClient.kt +++ b/src/webview/android/kotlin/RustWebChromeClient.kt @@ -97,9 +97,9 @@ class RustWebChromeClient(appActivity: AppCompatActivity) : WebChromeClient() { super.onHideCustomView() } + @SuppressLint("ObsoleteSdkInt") override fun onPermissionRequest(request: PermissionRequest) { - // val isRequestPermissionRequired = Build.VERSION.SDK_INT >= Build.VERSION_CODES.M - val isRequestPermissionRequired = true + val isRequestPermissionRequired = Build.VERSION.SDK_INT >= Build.VERSION_CODES.M val permissionList: MutableList = ArrayList() if (listOf(*request.resources).contains("android.webkit.resource.VIDEO_CAPTURE")) { permissionList.add(Manifest.permission.CAMERA) diff --git a/src/webview/android/kotlin/RustWebView.kt b/src/webview/android/kotlin/RustWebView.kt index f3f38d696..e393808a1 100644 --- a/src/webview/android/kotlin/RustWebView.kt +++ b/src/webview/android/kotlin/RustWebView.kt @@ -4,8 +4,10 @@ package {{app-domain-reversed}}.{{app-name-snake-case}} +import android.annotation.SuppressLint import android.webkit.* import android.content.Context +import android.os.Build class RustWebView(context: Context): WebView(context) { init { diff --git a/src/webview/android/kotlin/TauriActivity.kt b/src/webview/android/kotlin/TauriActivity.kt index 74633bd43..4be727cfb 100644 --- a/src/webview/android/kotlin/TauriActivity.kt +++ b/src/webview/android/kotlin/TauriActivity.kt @@ -4,11 +4,48 @@ package {{app-domain-reversed}}.{{app-name-snake-case}} +import android.annotation.SuppressLint +import android.os.Build import android.os.Bundle +import android.webkit.WebView import androidx.appcompat.app.AppCompatActivity abstract class TauriActivity : AppCompatActivity() { - override fun onCreate(savedInstanceState: Bundle?) { + + val version: String + @SuppressLint("WebViewApiAvailability", "ObsoleteSdkInt") + get() { + // Check getCurrentWebViewPackage() directly if above Android 8 + if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) { + return WebView.getCurrentWebViewPackage()?.versionName ?: "" + } + + // Otherwise manually check WebView versions + var webViewPackage = "com.google.android.webview" + if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.N) { + webViewPackage = "com.android.chrome" + } + try { + @Suppress("DEPRECATION") + val info = packageManager.getPackageInfo(webViewPackage, 0) + return info.versionName + } catch (ex: Exception) { + Logger.warn("Unable to get package info for '$webViewPackage'$ex"); + } + + try { + @Suppress("DEPRECATION") + val info = packageManager.getPackageInfo("com.android.webview", 0); + return info.versionName + } catch (ex: Exception) { + Logger.warn("Unable to get package info for 'com.android.webview'$ex"); + } + + // Could not detect any webview, return empty string + return ""; + } + + override fun onCreate(savedInstanceState: Bundle?) { super.onCreate(savedInstanceState) create(this) } diff --git a/src/webview/android/main_pipe.rs b/src/webview/android/main_pipe.rs index ac6b137f0..4ebb3f28d 100644 --- a/src/webview/android/main_pipe.rs +++ b/src/webview/android/main_pipe.rs @@ -2,7 +2,7 @@ // SPDX-License-Identifier: Apache-2.0 // SPDX-License-Identifier: MIT -use crate::webview::RGBA; +use crate::{webview::RGBA, Error}; use crossbeam_channel::*; use once_cell::sync::Lazy; use std::os::unix::prelude::*; @@ -149,6 +149,18 @@ impl MainPipe<'_> { set_background_color(env, webview.as_obj(), background_color)?; } } + WebViewMessage::GetWebViewVersion(tx) => { + match env + .call_method(activity, "getVersion", "()Ljava/lang/String;", &[]) + .and_then(|v| v.l()) + .and_then(|s| env.get_string(s.into())) + { + Ok(version) => { + tx.send(Ok(version.to_string_lossy().into())).unwrap(); + } + Err(e) => tx.send(Err(e.into())).unwrap(), + } + } } } Ok(()) @@ -181,6 +193,7 @@ pub enum WebViewMessage { CreateWebView(CreateWebViewAttributes), Eval(String), SetBackgroundColor(RGBA), + GetWebViewVersion(Sender>), } #[derive(Debug)] diff --git a/src/webview/android/mod.rs b/src/webview/android/mod.rs index 792130500..ee1f4692d 100644 --- a/src/webview/android/mod.rs +++ b/src/webview/android/mod.rs @@ -8,6 +8,7 @@ use crate::{ http::{header::HeaderValue, Request as HttpRequest, Response as HttpResponse}, Result, }; +use crossbeam_channel::*; use html5ever::{interface::QualName, namespace_url, ns, tendril::TendrilSink, LocalName}; use kuchiki::NodeRef; use once_cell::sync::OnceCell; @@ -242,7 +243,9 @@ impl InnerWebView { } pub fn platform_webview_version() -> Result { - todo!() + let (tx, rx) = bounded(1); + MainPipe::send(WebViewMessage::GetWebViewVersion(tx)); + rx.recv().unwrap() } fn with_html_head(document: &mut NodeRef, f: F) {