diff --git a/.gitmodules b/.gitmodules index 552a758f6..b4b8a2838 100644 --- a/.gitmodules +++ b/.gitmodules @@ -1,3 +1,7 @@ [submodule "media"] path = media url = https://github.com/OxygenCobalt/media.git +[submodule "taglib"] + path = ktaglib/src/main/cpp/taglib + url = https://github.com/taglib/taglib.git + tag = v2.0.2 diff --git a/app/build.gradle b/app/build.gradle index 92fd84951..797514eeb 100644 --- a/app/build.gradle +++ b/app/build.gradle @@ -137,6 +137,9 @@ dependencies { implementation project(":media-lib-decoder-ffmpeg") coreLibraryDesugaring "com.android.tools:desugar_jdk_libs:2.1.3" + // Taglib + implementation project(":ktaglib") + // Image loading implementation 'io.coil-kt.coil3:coil-core:3.0.2' diff --git a/build.gradle b/build.gradle index cf3c05b03..5f4731e48 100644 --- a/build.gradle +++ b/build.gradle @@ -17,6 +17,7 @@ plugins { id "org.jetbrains.kotlin.android" version "$kotlin_version" apply false id "com.google.devtools.ksp" version '2.0.21-1.0.25' apply false id "com.diffplug.spotless" version "6.25.0" apply false + id 'com.android.library' version '8.7.2' apply false } tasks.register('clean', Delete) { diff --git a/ktaglib/.gitignore b/ktaglib/.gitignore new file mode 100644 index 000000000..42afabfd2 --- /dev/null +++ b/ktaglib/.gitignore @@ -0,0 +1 @@ +/build \ No newline at end of file diff --git a/ktaglib/build.gradle b/ktaglib/build.gradle new file mode 100644 index 000000000..72a311487 --- /dev/null +++ b/ktaglib/build.gradle @@ -0,0 +1,52 @@ +plugins { + id 'com.android.library' + id 'org.jetbrains.kotlin.android' +} + +android { + namespace 'com.example.ktaglib' + compileSdk 34 + ndkVersion "26.3.11579264" + + defaultConfig { + minSdk 24 + + testInstrumentationRunner "androidx.test.runner.AndroidJUnitRunner" + consumerProguardFiles "consumer-rules.pro" + externalNativeBuild { + cmake { + cppFlags "" + } + } + } + + buildTypes { + release { + minifyEnabled false + proguardFiles getDefaultProguardFile('proguard-android-optimize.txt'), 'proguard-rules.pro' + } + } + externalNativeBuild { + cmake { + path "src/main/cpp/CMakeLists.txt" + version "3.22.1" + } + } + compileOptions { + sourceCompatibility JavaVersion.VERSION_11 + targetCompatibility JavaVersion.VERSION_11 + } + kotlinOptions { + jvmTarget = '11' + } +} + +dependencies { + + implementation 'androidx.core:core-ktx:1.15.0' + implementation 'androidx.appcompat:appcompat:1.7.0' + implementation 'com.google.android.material:material:1.12.0' + testImplementation 'junit:junit:4.13.2' + androidTestImplementation 'androidx.test.ext:junit:1.2.1' + androidTestImplementation 'androidx.test.espresso:espresso-core:3.6.1' +} \ No newline at end of file diff --git a/ktaglib/consumer-rules.pro b/ktaglib/consumer-rules.pro new file mode 100644 index 000000000..e69de29bb diff --git a/ktaglib/proguard-rules.pro b/ktaglib/proguard-rules.pro new file mode 100644 index 000000000..481bb4348 --- /dev/null +++ b/ktaglib/proguard-rules.pro @@ -0,0 +1,21 @@ +# 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 + +# 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 diff --git a/ktaglib/src/main/AndroidManifest.xml b/ktaglib/src/main/AndroidManifest.xml new file mode 100644 index 000000000..a5918e68a --- /dev/null +++ b/ktaglib/src/main/AndroidManifest.xml @@ -0,0 +1,4 @@ + + + + \ No newline at end of file diff --git a/ktaglib/src/main/cpp/CMakeLists.txt b/ktaglib/src/main/cpp/CMakeLists.txt new file mode 100644 index 000000000..42230ee26 --- /dev/null +++ b/ktaglib/src/main/cpp/CMakeLists.txt @@ -0,0 +1,57 @@ +# For more information about using CMake with Android Studio, read the +# documentation: https://d.android.com/studio/projects/add-native-code.html. +# For more examples on how to use CMake, see https://github.com/android/ndk-samples. + +# Sets the minimum CMake version required for this project. +cmake_minimum_required(VERSION 3.22.1) + +# Declares the project name. The project name can be accessed via ${ PROJECT_NAME}, +# Since this is the top level CMakeLists.txt, the project name is also accessible +# with ${CMAKE_PROJECT_NAME} (both CMake variables are in-sync within the top level +# build script scope). +project("ktaglib") + +# Creates and names a library, sets it as either STATIC +# or SHARED, and provides the relative paths to its source code. +# You can define multiple libraries, and CMake builds them for you. +# Gradle automatically packages shared libraries with your APK. +# +# In this top level CMakeLists.txt, ${CMAKE_PROJECT_NAME} is used to define +# the target library name; in the sub-module's CMakeLists.txt, ${PROJECT_NAME} +# is preferred for the same purpose. +# +# In order to load a library into your app from Java/Kotlin, you must call +# System.loadLibrary() and pass the name of the library defined here; +# for GameActivity/NativeActivity derived applications, the same library name must be +# used in the AndroidManifest.xml file. +set(taglib_location "${CMAKE_CURRENT_SOURCE_DIR}/taglib") +set(taglib_pkg "${taglib_location}/android-libs/${ANDROID_ABI}") +set(taglib_lib "${taglib_pkg}/lib") +set(taglib_include "${taglib_pkg}/include") + +set(taglib_file_name libtag.a) +set(taglib_file_path ${taglib_lib}/${taglib_file_name}) +set(taglib_lib_name, "taglib") +add_library( + "taglib" + STATIC + IMPORTED) +set_target_properties( + "taglib" PROPERTIES + IMPORTED_LOCATION + ${taglib_file_path} + INTERFACE_INCLUDE_DIRECTORIES + ${taglib_include}) + +add_library(${CMAKE_PROJECT_NAME} SHARED + # List C/C++ source files with relative paths to this CMakeLists.txt. + ktaglib.cpp) + +# Specifies libraries CMake should link to your target library. You +# can link libraries from various origins, such as libraries defined in this +# build script, prebuilt third-party libraries, or Android system libraries. +target_link_libraries(${CMAKE_PROJECT_NAME} + # List libraries link to the target library + android + log + taglib) \ No newline at end of file diff --git a/ktaglib/src/main/cpp/android.toolchain.cmake b/ktaglib/src/main/cpp/android.toolchain.cmake new file mode 100644 index 000000000..53123fef9 --- /dev/null +++ b/ktaglib/src/main/cpp/android.toolchain.cmake @@ -0,0 +1,15 @@ +# Define the minimum CMake version and project name +cmake_minimum_required(VERSION 3.22.1) + +# Set the Android NDK path +option(ANDROID_NDK_PATH "Path to Android NDK Install. Should be same version specified in gradle." REQUIRED) + +# Specify the target Android API level +set(ANDROID_PLATFORM android-24) + +# Define the toolchain +set(CMAKE_SYSTEM_NAME Android) +set(CMAKE_ANDROID_ARCH_ABI ${ANDROID_ABI}) +set(CMAKE_ANDROID_NDK ${ANDROID_NDK_PATH}) +set(CMAKE_ANDROID_STL_TYPE c++_static) +set(CMAKE_ANDROID_NDK_TOOLCHAIN_VERSION clang) \ No newline at end of file diff --git a/ktaglib/src/main/cpp/build_taglib.sh b/ktaglib/src/main/cpp/build_taglib.sh new file mode 100644 index 000000000..bfefd4f45 --- /dev/null +++ b/ktaglib/src/main/cpp/build_taglib.sh @@ -0,0 +1,36 @@ +set -e +TAGLIB_SRC_DIR=$(pwd)/taglib +TAGLIB_DST_DIR=$(pwd)/taglib/build +TAGLIB_PKG_DIR=$(pwd)/taglib/pkg +NDK_TOOLCHAIN=$(pwd)/android.toolchain.cmake +NDK_PATH=$1 +echo "Taglib source is at $TAGLIB_SRC_DIR" +echo "Taglib build is at $TAGLIB_DST_DIR" +echo "Taglib package is at $TAGLIB_PKG_DIR" +echo "NDK toolchain is at $NDK_TOOLCHAIN" +echo "NDK path is at $NDK_PATH" + +X86_ARCH=x86 +X86_64_ARCH=x86_64 +ARMV7_ARCH=armeabi-v7a +ARMV8_ARCH=arm64-v8a + +build_for_arch() { + local ARCH=$1 + local DST_DIR=$TAGLIB_DST_DIR/$ARCH + local PKG_DIR=$TAGLIB_PKG_DIR/$ARCH + + pushd $TAGLIB_SRC_DIR + cmake -B $DST_DIR -DANDROID_NDK_PATH=${NDK_PATH} -DCMAKE_TOOLCHAIN_FILE=${NDK_TOOLCHAIN} \ + -DANDROID_ABI=$ARCH -DBUILD_SHARED_LIBS=OFF -DVISIBILITY_HIDDEN=ON -DBUILD_TESTING=OFF \ + -DBUILD_EXAMPLES=OFF -DBUILD_BINDINGS=OFF -DWITH_ZLIB=OFF -DCMAKE_BUILD_TYPE=Release + cmake --build $DST_DIR --config Release + popd + + cmake --install $DST_DIR --config Release --prefix $PKG_DIR --strip +} + +build_for_arch $X86_ARCH +build_for_arch $X86_64_ARCH +build_for_arch $ARMV7_ARCH +build_for_arch $ARMV8_ARCH \ No newline at end of file diff --git a/ktaglib/src/main/cpp/ktaglib.cpp b/ktaglib/src/main/cpp/ktaglib.cpp new file mode 100644 index 000000000..75b61ea2e --- /dev/null +++ b/ktaglib/src/main/cpp/ktaglib.cpp @@ -0,0 +1,12 @@ +#include +#include + +#include "taglib/tag.h" + +extern "C" JNIEXPORT jstring JNICALL +Java_com_example_ktaglib_NativeLib_stringFromJNI( + JNIEnv* env, + jobject /* this */) { + std::string hello = "Hello from C++"; + return env->NewStringUTF(hello.c_str()); +} \ No newline at end of file diff --git a/ktaglib/src/main/cpp/taglib b/ktaglib/src/main/cpp/taglib new file mode 160000 index 000000000..225c73e18 --- /dev/null +++ b/ktaglib/src/main/cpp/taglib @@ -0,0 +1 @@ +Subproject commit 225c73e1816c3200c67703557972586e287fa665 diff --git a/ktaglib/src/main/java/com/example/ktaglib/KTagLib.kt b/ktaglib/src/main/java/com/example/ktaglib/KTagLib.kt new file mode 100644 index 000000000..388d4ef9a --- /dev/null +++ b/ktaglib/src/main/java/com/example/ktaglib/KTagLib.kt @@ -0,0 +1,14 @@ +package com.example.ktaglib + +object KTagLib { + // Used to load the 'ktaglib' library on application startup. + init { + System.loadLibrary("ktaglib") + } + + /** + * A native method that is implemented by the 'ktaglib' native library, + * which is packaged with this application. + */ + external fun stringFromJNI(): String +}b \ No newline at end of file diff --git a/settings.gradle b/settings.gradle index 61caa7aa7..4dfc02e2e 100644 --- a/settings.gradle +++ b/settings.gradle @@ -19,4 +19,5 @@ gradle.ext.androidxMediaProjectName = 'media-' apply from: file("media/core_settings.gradle") rootProject.name = "Auxio" -include ':app' \ No newline at end of file +include ':app' +include ':ktaglib'