From d6cf484d61fd1f5a635e9b05f8599f1cff5c24bb Mon Sep 17 00:00:00 2001 From: Alexander Capehart Date: Tue, 4 Feb 2025 16:15:17 -0700 Subject: [PATCH] musikr: init rust metadata jni library --- build.gradle | 1 + musikr/build.gradle | 21 +- .../musikr/metadata/MetadataExtractor.kt | 5 +- .../metadata/{TagLibJNI.kt => MetadataJNI.kt} | 23 +- musikr/src/main/jni/.gitignore | 1 + musikr/src/main/jni/Cargo.lock | 294 ++++++++++++++++++ musikr/src/main/jni/Cargo.toml | 11 + musikr/src/main/jni/src/lib.rs | 22 ++ 8 files changed, 347 insertions(+), 31 deletions(-) rename musikr/src/main/java/org/oxycblt/musikr/metadata/{TagLibJNI.kt => MetadataJNI.kt} (56%) create mode 100644 musikr/src/main/jni/.gitignore create mode 100644 musikr/src/main/jni/Cargo.lock create mode 100644 musikr/src/main/jni/Cargo.toml create mode 100644 musikr/src/main/jni/src/lib.rs diff --git a/build.gradle b/build.gradle index 7bc5b84a9..a432d3049 100644 --- a/build.gradle +++ b/build.gradle @@ -33,6 +33,7 @@ plugins { id "com.google.devtools.ksp" version '2.0.21-1.0.25' apply false // We use spotless in the root build.gradle to apply to all modules. id "com.diffplug.spotless" version "6.25.0" apply true + id "org.mozilla.rust-android-gradle.rust-android" version "0.9.6" apply false } spotless { diff --git a/musikr/build.gradle b/musikr/build.gradle index 80007d3bf..1f3f5255c 100644 --- a/musikr/build.gradle +++ b/musikr/build.gradle @@ -7,6 +7,7 @@ plugins { id "com.diffplug.spotless" id "kotlin-parcelize" id "org.jetbrains.dokka" + id "org.mozilla.rust-android-gradle.rust-android" } android { @@ -20,11 +21,6 @@ android { testInstrumentationRunner "androidx.test.runner.AndroidJUnitRunner" consumerProguardFiles "consumer-rules.pro" - externalNativeBuild { - cmake { - cppFlags "" - } - } } buildTypes { @@ -34,13 +30,6 @@ android { } } - externalNativeBuild { - cmake { - path "src/main/cpp/CMakeLists.txt" - version "3.22.1" - } - } - compileOptions { coreLibraryDesugaringEnabled true sourceCompatibility JavaVersion.VERSION_17 @@ -57,6 +46,14 @@ android { } } +cargo { + module = "./src/main/jni" + libname = "metadatajni" + targets = ["arm", "arm64", "x86", "x86_64"] + prebuiltToolchains = true + profile = 'debug' +} + dependencies { // Kotlin implementation "org.jetbrains.kotlin:kotlin-stdlib:$kotlin_version" diff --git a/musikr/src/main/java/org/oxycblt/musikr/metadata/MetadataExtractor.kt b/musikr/src/main/java/org/oxycblt/musikr/metadata/MetadataExtractor.kt index 0b0cfc48d..4b9fd9319 100644 --- a/musikr/src/main/java/org/oxycblt/musikr/metadata/MetadataExtractor.kt +++ b/musikr/src/main/java/org/oxycblt/musikr/metadata/MetadataExtractor.kt @@ -19,6 +19,7 @@ package org.oxycblt.musikr.metadata import android.os.ParcelFileDescriptor +import android.util.Log import java.io.FileInputStream import kotlinx.coroutines.Dispatchers import kotlinx.coroutines.withContext @@ -36,6 +37,8 @@ private object MetadataExtractorImpl : MetadataExtractor { override suspend fun extract(deviceFile: DeviceFile, fd: ParcelFileDescriptor) = withContext(Dispatchers.IO) { val fis = FileInputStream(fd.fileDescriptor) - TagLibJNI.open(deviceFile, fis).also { fis.close() } + Log.d("MetadataExtractorImpl", MetadataJNI.rust("bruh")) +// MetadataJNI.open(deviceFile, fis).also { fis.close() } + null } } diff --git a/musikr/src/main/java/org/oxycblt/musikr/metadata/TagLibJNI.kt b/musikr/src/main/java/org/oxycblt/musikr/metadata/MetadataJNI.kt similarity index 56% rename from musikr/src/main/java/org/oxycblt/musikr/metadata/TagLibJNI.kt rename to musikr/src/main/java/org/oxycblt/musikr/metadata/MetadataJNI.kt index d5105f3a8..715b57915 100644 --- a/musikr/src/main/java/org/oxycblt/musikr/metadata/TagLibJNI.kt +++ b/musikr/src/main/java/org/oxycblt/musikr/metadata/MetadataJNI.kt @@ -18,25 +18,12 @@ package org.oxycblt.musikr.metadata -import java.io.FileInputStream -import org.oxycblt.musikr.fs.DeviceFile - -internal object TagLibJNI { +internal object MetadataJNI { init { - System.loadLibrary("tagJNI") + System.loadLibrary("metadatajni") } - /** - * Open a file and extract a tag. - * - * Note: This method is blocking and should be handled as such if calling from a coroutine. - */ - fun open(deviceFile: DeviceFile, fis: FileInputStream): Metadata? { - val inputStream = NativeInputStream(deviceFile, fis) - val tag = openNative(inputStream) - inputStream.close() - return tag - } - - private external fun openNative(inputStream: NativeInputStream): Metadata? + // This is a rust function, Android Studio has no idea how to link to it + @Suppress("KotlinJniMissingFunction") + external fun rust(a: String): String } diff --git a/musikr/src/main/jni/.gitignore b/musikr/src/main/jni/.gitignore new file mode 100644 index 000000000..9f970225a --- /dev/null +++ b/musikr/src/main/jni/.gitignore @@ -0,0 +1 @@ +target/ \ No newline at end of file diff --git a/musikr/src/main/jni/Cargo.lock b/musikr/src/main/jni/Cargo.lock new file mode 100644 index 000000000..c9cce0594 --- /dev/null +++ b/musikr/src/main/jni/Cargo.lock @@ -0,0 +1,294 @@ +# This file is automatically @generated by Cargo. +# It is not intended for manual editing. +version = 4 + +[[package]] +name = "bytes" +version = "1.10.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f61dac84819c6588b558454b194026eb1f09c293b9036ae9b159e74e73ab6cf9" + +[[package]] +name = "cesu8" +version = "1.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6d43a04d8753f35258c91f8ec639f792891f748a1edbd759cf1dcea3382ad83c" + +[[package]] +name = "cfg-if" +version = "1.0.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "baf1de4339761588bc0619e3cbc0120ee582ebb74b53b4efbf79117bd2da40fd" + +[[package]] +name = "combine" +version = "4.6.7" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ba5a308b75df32fe02788e748662718f03fde005016435c444eea572398219fd" +dependencies = [ + "bytes", + "memchr", +] + +[[package]] +name = "jni" +version = "0.21.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1a87aa2bb7d2af34197c04845522473242e1aa17c12f4935d5856491a7fb8c97" +dependencies = [ + "cesu8", + "cfg-if", + "combine", + "jni-sys", + "log", + "thiserror", + "walkdir", + "windows-sys 0.45.0", +] + +[[package]] +name = "jni-sys" +version = "0.3.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8eaf4bc02d17cbdd7ff4c7438cafcdf7fb9a4613313ad11b4f8fefe7d3fa0130" + +[[package]] +name = "log" +version = "0.4.25" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "04cbf5b083de1c7e0222a7a51dbfdba1cbe1c6ab0b15e29fff3f6c077fd9cd9f" + +[[package]] +name = "memchr" +version = "2.7.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "78ca9ab1a0babb1e7d5695e3530886289c18cf2f87ec19a575a0abdce112e3a3" + +[[package]] +name = "metadatajni" +version = "1.0.0" +dependencies = [ + "jni", +] + +[[package]] +name = "proc-macro2" +version = "1.0.93" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "60946a68e5f9d28b0dc1c21bb8a97ee7d018a8b322fa57838ba31cc878e22d99" +dependencies = [ + "unicode-ident", +] + +[[package]] +name = "quote" +version = "1.0.38" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0e4dccaaaf89514f546c693ddc140f729f958c247918a13380cccc6078391acc" +dependencies = [ + "proc-macro2", +] + +[[package]] +name = "same-file" +version = "1.0.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "93fc1dc3aaa9bfed95e02e6eadabb4baf7e3078b0bd1b4d7b6b0b68378900502" +dependencies = [ + "winapi-util", +] + +[[package]] +name = "syn" +version = "2.0.98" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "36147f1a48ae0ec2b5b3bc5b537d267457555a10dc06f3dbc8cb11ba3006d3b1" +dependencies = [ + "proc-macro2", + "quote", + "unicode-ident", +] + +[[package]] +name = "thiserror" +version = "1.0.69" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b6aaf5339b578ea85b50e080feb250a3e8ae8cfcdff9a461c9ec2904bc923f52" +dependencies = [ + "thiserror-impl", +] + +[[package]] +name = "thiserror-impl" +version = "1.0.69" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4fee6c4efc90059e10f81e6d42c60a18f76588c3d74cb83a0b242a2b6c7504c1" +dependencies = [ + "proc-macro2", + "quote", + "syn", +] + +[[package]] +name = "unicode-ident" +version = "1.0.16" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a210d160f08b701c8721ba1c726c11662f877ea6b7094007e1ca9a1041945034" + +[[package]] +name = "walkdir" +version = "2.5.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "29790946404f91d9c5d06f9874efddea1dc06c5efe94541a7d6863108e3a5e4b" +dependencies = [ + "same-file", + "winapi-util", +] + +[[package]] +name = "winapi-util" +version = "0.1.9" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "cf221c93e13a30d793f7645a0e7762c55d169dbb0a49671918a2319d289b10bb" +dependencies = [ + "windows-sys 0.59.0", +] + +[[package]] +name = "windows-sys" +version = "0.45.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "75283be5efb2831d37ea142365f009c02ec203cd29a3ebecbc093d52315b66d0" +dependencies = [ + "windows-targets 0.42.2", +] + +[[package]] +name = "windows-sys" +version = "0.59.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1e38bc4d79ed67fd075bcc251a1c39b32a1776bbe92e5bef1f0bf1f8c531853b" +dependencies = [ + "windows-targets 0.52.6", +] + +[[package]] +name = "windows-targets" +version = "0.42.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8e5180c00cd44c9b1c88adb3693291f1cd93605ded80c250a75d472756b4d071" +dependencies = [ + "windows_aarch64_gnullvm 0.42.2", + "windows_aarch64_msvc 0.42.2", + "windows_i686_gnu 0.42.2", + "windows_i686_msvc 0.42.2", + "windows_x86_64_gnu 0.42.2", + "windows_x86_64_gnullvm 0.42.2", + "windows_x86_64_msvc 0.42.2", +] + +[[package]] +name = "windows-targets" +version = "0.52.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9b724f72796e036ab90c1021d4780d4d3d648aca59e491e6b98e725b84e99973" +dependencies = [ + "windows_aarch64_gnullvm 0.52.6", + "windows_aarch64_msvc 0.52.6", + "windows_i686_gnu 0.52.6", + "windows_i686_gnullvm", + "windows_i686_msvc 0.52.6", + "windows_x86_64_gnu 0.52.6", + "windows_x86_64_gnullvm 0.52.6", + "windows_x86_64_msvc 0.52.6", +] + +[[package]] +name = "windows_aarch64_gnullvm" +version = "0.42.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "597a5118570b68bc08d8d59125332c54f1ba9d9adeedeef5b99b02ba2b0698f8" + +[[package]] +name = "windows_aarch64_gnullvm" +version = "0.52.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "32a4622180e7a0ec044bb555404c800bc9fd9ec262ec147edd5989ccd0c02cd3" + +[[package]] +name = "windows_aarch64_msvc" +version = "0.42.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e08e8864a60f06ef0d0ff4ba04124db8b0fb3be5776a5cd47641e942e58c4d43" + +[[package]] +name = "windows_aarch64_msvc" +version = "0.52.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "09ec2a7bb152e2252b53fa7803150007879548bc709c039df7627cabbd05d469" + +[[package]] +name = "windows_i686_gnu" +version = "0.42.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c61d927d8da41da96a81f029489353e68739737d3beca43145c8afec9a31a84f" + +[[package]] +name = "windows_i686_gnu" +version = "0.52.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8e9b5ad5ab802e97eb8e295ac6720e509ee4c243f69d781394014ebfe8bbfa0b" + +[[package]] +name = "windows_i686_gnullvm" +version = "0.52.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0eee52d38c090b3caa76c563b86c3a4bd71ef1a819287c19d586d7334ae8ed66" + +[[package]] +name = "windows_i686_msvc" +version = "0.42.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "44d840b6ec649f480a41c8d80f9c65108b92d89345dd94027bfe06ac444d1060" + +[[package]] +name = "windows_i686_msvc" +version = "0.52.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "240948bc05c5e7c6dabba28bf89d89ffce3e303022809e73deaefe4f6ec56c66" + +[[package]] +name = "windows_x86_64_gnu" +version = "0.42.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8de912b8b8feb55c064867cf047dda097f92d51efad5b491dfb98f6bbb70cb36" + +[[package]] +name = "windows_x86_64_gnu" +version = "0.52.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "147a5c80aabfbf0c7d901cb5895d1de30ef2907eb21fbbab29ca94c5b08b1a78" + +[[package]] +name = "windows_x86_64_gnullvm" +version = "0.42.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "26d41b46a36d453748aedef1486d5c7a85db22e56aff34643984ea85514e94a3" + +[[package]] +name = "windows_x86_64_gnullvm" +version = "0.52.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "24d5b23dc417412679681396f2b49f3de8c1473deb516bd34410872eff51ed0d" + +[[package]] +name = "windows_x86_64_msvc" +version = "0.42.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9aec5da331524158c6d1a4ac0ab1541149c0b9505fde06423b02f5ef0106b9f0" + +[[package]] +name = "windows_x86_64_msvc" +version = "0.52.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "589f6da84c646204747d1270a2a5661ea66ed1cced2631d546fdfb155959f9ec" diff --git a/musikr/src/main/jni/Cargo.toml b/musikr/src/main/jni/Cargo.toml new file mode 100644 index 000000000..2b6ab756c --- /dev/null +++ b/musikr/src/main/jni/Cargo.toml @@ -0,0 +1,11 @@ +[package] +name = "metadatajni" +version = "1.0.0" +edition = "2021" + +[lib] +crate-type = ["cdylib"] +name = "metadatajni" + +[dependencies] +jni = "0.21.1" diff --git a/musikr/src/main/jni/src/lib.rs b/musikr/src/main/jni/src/lib.rs new file mode 100644 index 000000000..b2e55839b --- /dev/null +++ b/musikr/src/main/jni/src/lib.rs @@ -0,0 +1,22 @@ +use jni::objects::{JClass, JString}; +use jni::sys::jstring; +use jni::JNIEnv; + +#[no_mangle] +pub extern "C" fn Java_org_oxycblt_musikr_metadata_MetadataJNI_rust( + mut env: JNIEnv, + _class: JClass, + input: JString, +) -> jstring { + // Convert the Java string (JString) to a Rust string + let input: String = env.get_string(&input).expect("Couldn't get java string!").into(); + + // Process the input string (this is where your Rust logic would go) + let output = format!("Hello from Rust, {}", input); + + // Convert the Rust string back to a Java string (jstring) + let output = env.new_string(output).expect("Couldn't create java string!"); + + // Return the Java string + output.into_raw() +}