From bef4ef51bc2c633b88db121c2087a38dddb7d6bf Mon Sep 17 00:00:00 2001 From: Lucas Fernandes Nogueira Date: Mon, 13 Feb 2023 05:22:03 -0800 Subject: [PATCH] feat(android): enable minify on release, add proguard rules (#6257) --- .changes/enable-minify.md | 6 ++++ .changes/inject-proguard.md | 5 ++++ core/tauri/build.rs | 9 ++++++ core/tauri/mobile/android/build.gradle.kts | 4 +-- core/tauri/mobile/android/consumer-rules.pro | 0 core/tauri/mobile/android/proguard-rules.pro | 26 ++++------------- .../src/main/java/app/tauri/JniMethod.kt | 4 +++ .../java/app/tauri/plugin/PluginManager.kt | 5 ++++ .../main/java/app/tauri/plugin/TauriPlugin.kt | 4 +++ core/tauri/mobile/proguard-tauri.pro | 29 +++++++++++++++++++ examples/api/src-tauri/Cargo.lock | 14 +++++---- .../android/consumer-rules.pro | 0 .../java/com/plugin/test/ExamplePlugin.kt | 2 ++ .../mobile/android/app/build.gradle.kts | 7 +++-- .../plugin/android/consumer-rules.pro | 0 .../plugin/android/src/main/ExamplePlugin.kt | 2 ++ 16 files changed, 87 insertions(+), 30 deletions(-) create mode 100644 .changes/enable-minify.md create mode 100644 .changes/inject-proguard.md delete mode 100644 core/tauri/mobile/android/consumer-rules.pro create mode 100644 core/tauri/mobile/android/src/main/java/app/tauri/JniMethod.kt create mode 100644 core/tauri/mobile/android/src/main/java/app/tauri/plugin/TauriPlugin.kt create mode 100644 core/tauri/mobile/proguard-tauri.pro delete mode 100644 examples/api/src-tauri/tauri-plugin-sample/android/consumer-rules.pro delete mode 100644 tooling/cli/templates/plugin/android/consumer-rules.pro diff --git a/.changes/enable-minify.md b/.changes/enable-minify.md new file mode 100644 index 000000000..271799d65 --- /dev/null +++ b/.changes/enable-minify.md @@ -0,0 +1,6 @@ +--- +"cli.rs": patch +"cli.js": patch +--- + +Change the Android template to enable minification on release and pull ProGuard rules from proguard-tauri.pro. diff --git a/.changes/inject-proguard.md b/.changes/inject-proguard.md new file mode 100644 index 000000000..489ce1ea6 --- /dev/null +++ b/.changes/inject-proguard.md @@ -0,0 +1,5 @@ +--- +"tauri": patch +--- + +Inject `proguard-tauri.pro` file in the Android project. diff --git a/core/tauri/build.rs b/core/tauri/build.rs index 4f463177a..a1c9abf66 100644 --- a/core/tauri/build.rs +++ b/core/tauri/build.rs @@ -154,6 +154,15 @@ fn main() { &[], ) .expect("failed to copy tauri-api Android project"); + let tauri_proguard = include_str!("./mobile/proguard-tauri.pro").replace( + "$PACKAGE", + &var("WRY_ANDROID_PACKAGE").expect("missing `WRY_ANDROID_PACKAGE` environment variable"), + ); + std::fs::write( + project_dir.join("app").join("proguard-tauri.pro"), + tauri_proguard, + ) + .expect("failed to write proguard-tauri.pro"); } let lib_path = PathBuf::from(std::env::var_os("CARGO_MANIFEST_DIR").unwrap()).join("mobile/android"); diff --git a/core/tauri/mobile/android/build.gradle.kts b/core/tauri/mobile/android/build.gradle.kts index 3ed1b0dc3..8eec61537 100644 --- a/core/tauri/mobile/android/build.gradle.kts +++ b/core/tauri/mobile/android/build.gradle.kts @@ -12,7 +12,7 @@ android { targetSdk = 33 testInstrumentationRunner = "androidx.test.runner.AndroidJUnitRunner" - consumerProguardFiles("consumer-rules.pro") + consumerProguardFiles("proguard-rules.pro") } buildTypes { @@ -41,4 +41,4 @@ dependencies { testImplementation("junit:junit:4.13.2") androidTestImplementation("androidx.test.ext:junit:1.1.5") androidTestImplementation("androidx.test.espresso:espresso-core:3.5.1") -} \ No newline at end of file +} diff --git a/core/tauri/mobile/android/consumer-rules.pro b/core/tauri/mobile/android/consumer-rules.pro deleted file mode 100644 index e69de29bb..000000000 diff --git a/core/tauri/mobile/android/proguard-rules.pro b/core/tauri/mobile/android/proguard-rules.pro index 481bb4348..ae5b4cb0d 100644 --- a/core/tauri/mobile/android/proguard-rules.pro +++ b/core/tauri/mobile/android/proguard-rules.pro @@ -1,21 +1,7 @@ -# Add project specific ProGuard rules here. -# You can control the set of applied configuration files using the -# proguardFiles setting in build.gradle. -# -# For more details, see -# http://developer.android.com/guide/developing/tools/proguard.html +-keep class app.tauri.** { + @app.tauri.JniMethod public ; +} -# If your project uses WebView with JS, uncomment the following -# and specify the fully qualified class name to the JavaScript interface -# class: -#-keepclassmembers class fqcn.of.javascript.interface.for.webview { -# public *; -#} - -# Uncomment this to preserve the line number information for -# debugging stack traces. -#-keepattributes SourceFile,LineNumberTable - -# If you keep the line number information, uncomment this to -# hide the original source file name. -#-renamesourcefileattribute SourceFile \ No newline at end of file +-keep class app.tauri.JSArray,app.tauri.JSObject { + public (...); +} diff --git a/core/tauri/mobile/android/src/main/java/app/tauri/JniMethod.kt b/core/tauri/mobile/android/src/main/java/app/tauri/JniMethod.kt new file mode 100644 index 000000000..86cd69979 --- /dev/null +++ b/core/tauri/mobile/android/src/main/java/app/tauri/JniMethod.kt @@ -0,0 +1,4 @@ +package app.tauri + +@Retention(AnnotationRetention.RUNTIME) +internal annotation class JniMethod() { } diff --git a/core/tauri/mobile/android/src/main/java/app/tauri/plugin/PluginManager.kt b/core/tauri/mobile/android/src/main/java/app/tauri/plugin/PluginManager.kt index fd4ae92be..78fa29d95 100644 --- a/core/tauri/mobile/android/src/main/java/app/tauri/plugin/PluginManager.kt +++ b/core/tauri/mobile/android/src/main/java/app/tauri/plugin/PluginManager.kt @@ -1,11 +1,13 @@ package app.tauri.plugin import android.webkit.WebView +import app.tauri.JniMethod import app.tauri.Logger class PluginManager { private val plugins: HashMap = HashMap() + @JniMethod fun onWebViewCreated(webView: WebView) { for ((_, plugin) in plugins) { if (!plugin.loaded) { @@ -14,6 +16,7 @@ class PluginManager { } } + @JniMethod fun load(webView: WebView?, name: String, plugin: Plugin) { val handle = PluginHandle(plugin) plugins[name] = handle @@ -22,6 +25,7 @@ class PluginManager { } } + @JniMethod 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( @@ -34,6 +38,7 @@ class PluginManager { dispatchPluginMessage(invoke, pluginId, methodName) } + @JniMethod fun runPluginMethod(id: Int, pluginId: String, methodName: String, data: JSObject) { val invoke = Invoke({ successResult, errorResult -> handlePluginResponse(id, successResult?.toString(), errorResult?.toString()) diff --git a/core/tauri/mobile/android/src/main/java/app/tauri/plugin/TauriPlugin.kt b/core/tauri/mobile/android/src/main/java/app/tauri/plugin/TauriPlugin.kt new file mode 100644 index 000000000..c5943e6a9 --- /dev/null +++ b/core/tauri/mobile/android/src/main/java/app/tauri/plugin/TauriPlugin.kt @@ -0,0 +1,4 @@ +package app.tauri.plugin + +@Retention(AnnotationRetention.RUNTIME) +annotation class TauriPlugin() { } diff --git a/core/tauri/mobile/proguard-tauri.pro b/core/tauri/mobile/proguard-tauri.pro new file mode 100644 index 000000000..631dfa416 --- /dev/null +++ b/core/tauri/mobile/proguard-tauri.pro @@ -0,0 +1,29 @@ +# THIS IS AN AUTOGENERATED FILE. DO NOT EDIT THIS FILE DIRECTLY. + +-keep class $PACKAGE.TauriActivity { + getAppClass(...); + getVersion(); +} + +-keep class $PACKAGE.RustWebView { + public (...); + loadUrlMainThread(...); +} + +-keep class $PACKAGE.Ipc { + public (...); + @android.webkit.JavascriptInterface public ; +} + +-keep class $PACKAGE.RustWebChromeClient,$PACKAGE.RustWebViewClient { + public (...); +} + +-keep class $PACKAGE.MainActivity { + public getPluginManager(); +} + +-keep @app.tauri.plugin.TauriPlugin public class * { + @app.tauri.plugin.PluginMethod public ; + public (...); +} diff --git a/examples/api/src-tauri/Cargo.lock b/examples/api/src-tauri/Cargo.lock index 4e6512935..7c91bc626 100644 --- a/examples/api/src-tauri/Cargo.lock +++ b/examples/api/src-tauri/Cargo.lock @@ -2932,8 +2932,9 @@ dependencies = [ [[package]] name = "tao" -version = "0.17.0" -source = "git+https://github.com/tauri-apps/tao?branch=dev#8971d731b02ec61a1665351c9bae11f5e4058dc4" +version = "0.18.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e1d16138f5d521fcde40580e1a34df784b063dd9ac05c7cbe344bf01f02a23be" dependencies = [ "bitflags", "cairo-rs", @@ -2980,8 +2981,9 @@ dependencies = [ [[package]] name = "tao-macros" -version = "0.1.0" -source = "git+https://github.com/tauri-apps/tao?branch=dev#8971d731b02ec61a1665351c9bae11f5e4058dc4" +version = "0.1.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3b27a4bcc5eb524658234589bdffc7e7bfb996dbae6ce9393bfd39cb4159b445" dependencies = [ "proc-macro2", "quote", @@ -4108,8 +4110,8 @@ dependencies = [ [[package]] name = "wry" -version = "0.26.0" -source = "git+https://github.com/tauri-apps/wry?branch=dev#9613a08312645bbad80de6b91c5ba33656cf6a5e" +version = "0.27.0" +source = "git+https://github.com/tauri-apps/wry?branch=dev#fc113d6e85ca5cd899c1f9c8c28a1e3c13612698" dependencies = [ "base64 0.13.1", "block", diff --git a/examples/api/src-tauri/tauri-plugin-sample/android/consumer-rules.pro b/examples/api/src-tauri/tauri-plugin-sample/android/consumer-rules.pro deleted file mode 100644 index e69de29bb..000000000 diff --git a/examples/api/src-tauri/tauri-plugin-sample/android/src/main/java/com/plugin/test/ExamplePlugin.kt b/examples/api/src-tauri/tauri-plugin-sample/android/src/main/java/com/plugin/test/ExamplePlugin.kt index 37d2769ce..2d8f3f3aa 100644 --- a/examples/api/src-tauri/tauri-plugin-sample/android/src/main/java/com/plugin/test/ExamplePlugin.kt +++ b/examples/api/src-tauri/tauri-plugin-sample/android/src/main/java/com/plugin/test/ExamplePlugin.kt @@ -5,7 +5,9 @@ import app.tauri.plugin.JSObject import app.tauri.plugin.Plugin import app.tauri.plugin.Invoke import app.tauri.plugin.PluginMethod +import app.tauri.plugin.TauriPlugin +@TauriPlugin class ExamplePlugin(private val activity: Activity): Plugin() { private val implementation = Example() diff --git a/tooling/cli/templates/mobile/android/app/build.gradle.kts b/tooling/cli/templates/mobile/android/app/build.gradle.kts index 4c19738dc..42df4573b 100644 --- a/tooling/cli/templates/mobile/android/app/build.gradle.kts +++ b/tooling/cli/templates/mobile/android/app/build.gradle.kts @@ -36,8 +36,11 @@ android { } } getByName("release") { - isMinifyEnabled = false - proguardFiles(getDefaultProguardFile("proguard-android.txt"), "proguard-rules.pro") + isMinifyEnabled = true + val proguards = fileTree(".") { + include("*.pro") + } + proguardFiles(*proguards.toList().toTypedArray()) } } flavorDimensions.add("abi") diff --git a/tooling/cli/templates/plugin/android/consumer-rules.pro b/tooling/cli/templates/plugin/android/consumer-rules.pro deleted file mode 100644 index e69de29bb..000000000 diff --git a/tooling/cli/templates/plugin/android/src/main/ExamplePlugin.kt b/tooling/cli/templates/plugin/android/src/main/ExamplePlugin.kt index b35138124..cc3a321a2 100644 --- a/tooling/cli/templates/plugin/android/src/main/ExamplePlugin.kt +++ b/tooling/cli/templates/plugin/android/src/main/ExamplePlugin.kt @@ -5,7 +5,9 @@ import app.tauri.plugin.JSObject import app.tauri.plugin.Plugin import app.tauri.plugin.Invoke import app.tauri.plugin.PluginMethod +import app.tauri.plugin.TauriPlugin +@TauriPlugin class ExamplePlugin(private val activity: Activity): Plugin() { private val implementation = Example()