From a71ce91adf36550e9874c5a87a13b651fc266935 Mon Sep 17 00:00:00 2001 From: Andreas Stefl Date: Tue, 14 Oct 2025 20:26:32 +0200 Subject: [PATCH 1/6] draft --- .../reader/background/MetadataLoader.java | 69 ++++--------------- 1 file changed, 13 insertions(+), 56 deletions(-) diff --git a/app/src/main/java/at/tomtasche/reader/background/MetadataLoader.java b/app/src/main/java/at/tomtasche/reader/background/MetadataLoader.java index 8705a52868f5..0e1653b18bb6 100644 --- a/app/src/main/java/at/tomtasche/reader/background/MetadataLoader.java +++ b/app/src/main/java/at/tomtasche/reader/background/MetadataLoader.java @@ -6,8 +6,6 @@ import android.provider.OpenableColumns; import android.webkit.MimeTypeMap; -import com.hzy.libmagic.MagicApi; - import java.io.File; import java.io.FileInputStream; import java.io.FileNotFoundException; @@ -21,30 +19,6 @@ public MetadataLoader(Context context) { super(context, LoaderType.METADATA); } - private boolean initMagicFromAssets() { - InputStream inputStream = null; - try { - inputStream = context.getAssets().open("magic.mgc"); - int length = inputStream.available(); - byte[] buffer = new byte[length]; - if (inputStream.read(buffer) > 0) { - return MagicApi.loadFromBytes(buffer, MagicApi.MAGIC_MIME_TYPE | MagicApi.MAGIC_COMPRESS_TRANSP) == 0; - } - } catch (Throwable e) { - crashManager.log(e); - } finally { - if (inputStream != null) { - try { - inputStream.close(); - } catch (IOException e) { - crashManager.log(e); - } - } - } - - return false; - } - @Override public boolean isSupported(Options options) { return true; @@ -113,22 +87,21 @@ public void loadSync(Options options) { String[] fileSplit = options.filename.split("\\."); String extension = fileSplit.length > 0 ? fileSplit[fileSplit.length - 1] : "N/A"; - String type = null; + String mimetype = null; try { - if (initMagicFromAssets()) { - type = MagicApi.magicFile(cachedFile.getAbsolutePath()); - } + // todo core get mimetype + //type = MagicApi.magicFile(cachedFile.getAbsolutePath()); } catch (Throwable e) { crashManager.log(e); } - if (type == null) { - type = context.getContentResolver().getType(uri); + if (mimetype == null) { + mimetype = context.getContentResolver().getType(uri); } - if (type == null) { + if (mimetype == null) { try { - type = URLConnection.guessContentTypeFromName(filename); + mimetype = URLConnection.guessContentTypeFromName(filename); } catch (Exception e) { // Samsung S7 Edge crashes with java.lang.StringIndexOutOfBoundsException crashManager.log(e); @@ -138,7 +111,7 @@ public void loadSync(Options options) { if (type == null) { try { try (InputStream tempStream = new FileInputStream(cachedFile)) { - type = URLConnection.guessContentTypeFromStream(tempStream); + mimetype = URLConnection.guessContentTypeFromStream(tempStream); } } catch (Exception e) { crashManager.log(e); @@ -146,19 +119,19 @@ public void loadSync(Options options) { } if (type != null) { - extension = MimeTypeMap.getSingleton().getExtensionFromMimeType(type); + extension = MimeTypeMap.getSingleton().getExtensionFromMimeType(mimetype); } else { - type = MimeTypeMap.getSingleton().getMimeTypeFromExtension(options.fileExtension); + mimetype = MimeTypeMap.getSingleton().getMimeTypeFromExtension(options.fileExtension); } if (extension != null) { options.fileExtension = extension; } - if (type != null) { - options.fileType = type; + if (mimetype != null) { + options.fileType = mimetype; } - if ("inode/x-empty".equals(type)) { + if ("inode/x-empty".equals(mimetype)) { throw new FileNotFoundException(); } @@ -183,20 +156,4 @@ public void loadSync(Options options) { callOnError(result, e); } } - - @Override - public void close() { - super.close(); - - backgroundHandler.post(new Runnable() { - @Override - public void run() { - try { - MagicApi.close(); - } catch (Throwable e) { - crashManager.log(e); - } - } - }); - } } From cb1f723afcdab41a3459b99cc2074a9c44df8a85 Mon Sep 17 00:00:00 2001 From: Andreas Stefl Date: Sun, 19 Oct 2025 21:12:21 +0200 Subject: [PATCH 2/6] use odrcore magic --- app/conandeployer.py | 9 +++++++++ app/conanfile.txt | 2 +- app/src/main/cpp/core_wrapper.cpp | 13 +++++++++++++ app/src/main/cpp/core_wrapper.hpp | 4 ++++ .../at/tomtasche/reader/background/CoreWrapper.java | 11 +++++++++++ .../tomtasche/reader/background/MetadataLoader.java | 3 +-- 6 files changed, 39 insertions(+), 3 deletions(-) diff --git a/app/conandeployer.py b/app/conandeployer.py index 1ea75762d8b2..6cc0b50cc30a 100644 --- a/app/conandeployer.py +++ b/app/conandeployer.py @@ -52,3 +52,12 @@ def deploy(graph, output_folder: str, **kwargs): f"{output_folder}/fontconfig", **copytree_kwargs, ) + + if "libmagic" in deps: + dep = deps["libmagic"] + conanfile.output.info(f"Deploying libmagic to {output_folder}") + shutil.copytree( + f"{dep.package_folder}/res", + f"{output_folder}/libmagic", + **copytree_kwargs, + ) diff --git a/app/conanfile.txt b/app/conanfile.txt index 5c79d58a0cf2..eee6915161c4 100644 --- a/app/conanfile.txt +++ b/app/conanfile.txt @@ -1,5 +1,5 @@ [requires] -odrcore/5.0.7 +odrcore/5.1.0 [generators] CMakeToolchain diff --git a/app/src/main/cpp/core_wrapper.cpp b/app/src/main/cpp/core_wrapper.cpp index da5f76816c05..7f643858e70b 100644 --- a/app/src/main/cpp/core_wrapper.cpp +++ b/app/src/main/cpp/core_wrapper.cpp @@ -88,16 +88,29 @@ Java_at_tomtasche_reader_background_CoreWrapper_setGlobalParams(JNIEnv *env, jcl std::string fontconfigDataPath = getStringField(env, paramsClass, params, "fontconfigDataPath"); std::string popplerDataPath = getStringField(env, paramsClass, params, "popplerDataPath"); std::string pdf2htmlexDataPath = getStringField(env, paramsClass, params, "pdf2htmlexDataPath"); + std::string libmagicDatabasePath = getStringField(env, paramsClass, params, "libmagicDatabasePath"); std::string customTmpfilePath = getStringField(env, paramsClass, params, "customTmpfilePath"); odr::GlobalParams::set_odr_core_data_path(odrCoreDataPath); odr::GlobalParams::set_fontconfig_data_path(fontconfigDataPath); odr::GlobalParams::set_poppler_data_path(popplerDataPath); odr::GlobalParams::set_pdf2htmlex_data_path(pdf2htmlexDataPath); + odr::GlobalParams::set_libmagic_database_path(libmagicDatabasePath); tmpfile_hack::set_tmpfile_directory(customTmpfilePath); } +JNIEXPORT jstring JNICALL +Java_at_tomtasche_reader_background_CoreWrapper_mimetypeNative(JNIEnv *env, jclass clazz, jstring path) { + auto logger = std::make_shared(); + + std::string pathCpp = convertString(env, path); + std::string mimetypeCpp = std::string(odr::mimetype(pathCpp)); + jstring mimetype = env->NewStringUTF(mimetypeCpp.c_str()); + + return mimetype; +} + JNIEXPORT jobject JNICALL Java_at_tomtasche_reader_background_CoreWrapper_parseNative(JNIEnv *env, jclass clazz, jobject options) { diff --git a/app/src/main/cpp/core_wrapper.hpp b/app/src/main/cpp/core_wrapper.hpp index 9c29e6175192..8804ba1293a1 100644 --- a/app/src/main/cpp/core_wrapper.hpp +++ b/app/src/main/cpp/core_wrapper.hpp @@ -8,6 +8,10 @@ JNIEXPORT void JNICALL Java_at_tomtasche_reader_background_CoreWrapper_setGlobalParams(JNIEnv *env, jclass clazz, jobject params); +JNIEXPORT jstring JNICALL +Java_at_tomtasche_reader_background_CoreWrapper_mimetypeNative(JNIEnv *env, jclass clazz, + jstring path); + JNIEXPORT jobject JNICALL Java_at_tomtasche_reader_background_CoreWrapper_parseNative(JNIEnv *env, jclass clazz, jobject options); diff --git a/app/src/main/java/at/tomtasche/reader/background/CoreWrapper.java b/app/src/main/java/at/tomtasche/reader/background/CoreWrapper.java index b894ef3f0a62..37cbe6085a91 100644 --- a/app/src/main/java/at/tomtasche/reader/background/CoreWrapper.java +++ b/app/src/main/java/at/tomtasche/reader/background/CoreWrapper.java @@ -18,6 +18,8 @@ public static class GlobalParams { public String fontconfigDataPath; public String popplerDataPath; public String pdf2htmlexDataPath; + public String libmagicDatabasePath; + public String customTmpfilePath; } @@ -29,6 +31,7 @@ public static void initialize(Context context) { File fontconfigDataDirectory = new File(assetsDirectory, "fontconfig"); File popplerDataDirectory = new File(assetsDirectory, "poppler"); File pdf2htmlexDataDirectory = new File(assetsDirectory, "pdf2htmlex"); + File libmagicDataDirectory = new File(assetsDirectory, "libmagic"); AssetExtractor ae = new AssetExtractor(context.getAssets()); ae.setOverwrite(); @@ -36,16 +39,24 @@ public static void initialize(Context context) { ae.extract(assetsDirectory, "core/fontconfig"); ae.extract(assetsDirectory, "core/poppler"); ae.extract(assetsDirectory, "core/pdf2htmlex"); + ae.extract(assetsDirectory, "core/libmagic"); CoreWrapper.GlobalParams globalParams = new CoreWrapper.GlobalParams(); globalParams.coreDataPath = odrCoreDataDirectory.getAbsolutePath(); globalParams.fontconfigDataPath = fontconfigDataDirectory.getAbsolutePath(); globalParams.popplerDataPath = popplerDataDirectory.getAbsolutePath(); globalParams.pdf2htmlexDataPath = pdf2htmlexDataDirectory.getAbsolutePath(); + globalParams.libmagicDatabasePath = new File(libmagicDataDirectory, "magic.mgc").getAbsolutePath(); globalParams.customTmpfilePath = context.getCacheDir().getAbsolutePath(); CoreWrapper.setGlobalParams(globalParams); } + public static String mimetype(String path) { + return mimetypeNative(path); + } + + private static native String mimetypeNative(String path); + public static class CoreOptions { public boolean ooxml; public boolean txt; diff --git a/app/src/main/java/at/tomtasche/reader/background/MetadataLoader.java b/app/src/main/java/at/tomtasche/reader/background/MetadataLoader.java index 0e1653b18bb6..66c9f52ab45b 100644 --- a/app/src/main/java/at/tomtasche/reader/background/MetadataLoader.java +++ b/app/src/main/java/at/tomtasche/reader/background/MetadataLoader.java @@ -89,8 +89,7 @@ public void loadSync(Options options) { String mimetype = null; try { - // todo core get mimetype - //type = MagicApi.magicFile(cachedFile.getAbsolutePath()); + mimetype = CoreWrapper.mimetype(cachedFile.getAbsolutePath()); } catch (Throwable e) { crashManager.log(e); } From e93927ccc4d87717f0a37e07a1bd4c4fb7fdac75 Mon Sep 17 00:00:00 2001 From: Thomas Taschauer <128734+TomTasche@users.noreply.github.com> Date: Sun, 30 Nov 2025 19:47:58 +0100 Subject: [PATCH 3/6] upgrade core --- app/conanfile.txt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/app/conanfile.txt b/app/conanfile.txt index 5c79d58a0cf2..774c45414516 100644 --- a/app/conanfile.txt +++ b/app/conanfile.txt @@ -1,5 +1,5 @@ [requires] -odrcore/5.0.7 +odrcore/5.1.1 [generators] CMakeToolchain From 3ffe93113ac51b6752b12209a3ba5d94aa3094ae Mon Sep 17 00:00:00 2001 From: Thomas Taschauer <128734+TomTasche@users.noreply.github.com> Date: Sun, 30 Nov 2025 19:58:09 +0100 Subject: [PATCH 4/6] upgrade gradle --- build.gradle | 2 +- gradle/wrapper/gradle-wrapper.properties | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/build.gradle b/build.gradle index ab59aa6280f4..efcf249f58d4 100644 --- a/build.gradle +++ b/build.gradle @@ -1,5 +1,5 @@ plugins { - id 'com.android.application' version '8.5.2' apply false + id 'com.android.application' version '8.13.1' apply false id 'com.google.gms.google-services'version '4.4.2' apply false id 'com.google.firebase.crashlytics' version '3.0.2' apply false id 'app.opendocument.conanandroidgradleplugin' version '0.9.6' apply false diff --git a/gradle/wrapper/gradle-wrapper.properties b/gradle/wrapper/gradle-wrapper.properties index 09523c0e5490..37f853b1c84d 100644 --- a/gradle/wrapper/gradle-wrapper.properties +++ b/gradle/wrapper/gradle-wrapper.properties @@ -1,6 +1,6 @@ distributionBase=GRADLE_USER_HOME distributionPath=wrapper/dists -distributionUrl=https\://services.gradle.org/distributions/gradle-8.9-bin.zip +distributionUrl=https\://services.gradle.org/distributions/gradle-8.13-bin.zip networkTimeout=10000 validateDistributionUrl=true zipStoreBase=GRADLE_USER_HOME From 451985226c8212ab74dd2118a6dc34a284fd2429 Mon Sep 17 00:00:00 2001 From: Thomas Taschauer <128734+TomTasche@users.noreply.github.com> Date: Sun, 30 Nov 2025 21:24:07 +0100 Subject: [PATCH 5/6] upgrade sdk version --- app/build.gradle | 4 ++-- app/src/main/res/values-v35/themes.xml | 13 +++++++++++++ 2 files changed, 15 insertions(+), 2 deletions(-) create mode 100644 app/src/main/res/values-v35/themes.xml diff --git a/app/build.gradle b/app/build.gradle index c4a4d69335d8..128268a5cb71 100644 --- a/app/build.gradle +++ b/app/build.gradle @@ -31,8 +31,8 @@ android { defaultConfig { applicationId "at.tomtasche.reader" minSdkVersion 23 - compileSdkVersion 34 - targetSdkVersion 34 + compileSdkVersion 35 + targetSdkVersion 35 testApplicationId "at.tomtasche.reader.test" testInstrumentationRunner "androidx.test.runner.AndroidJUnitRunner" diff --git a/app/src/main/res/values-v35/themes.xml b/app/src/main/res/values-v35/themes.xml new file mode 100644 index 000000000000..9c7918795209 --- /dev/null +++ b/app/src/main/res/values-v35/themes.xml @@ -0,0 +1,13 @@ + + + + + From aadd00f491da737e6cd65e7d7a5fdc549e912fd7 Mon Sep 17 00:00:00 2001 From: Thomas Taschauer <128734+TomTasche@users.noreply.github.com> Date: Mon, 1 Dec 2025 21:12:25 +0100 Subject: [PATCH 6/6] remove old magic dependency --- app/build.gradle | 1 - 1 file changed, 1 deletion(-) diff --git a/app/build.gradle b/app/build.gradle index 128268a5cb71..ffdb42b0588e 100644 --- a/app/build.gradle +++ b/app/build.gradle @@ -149,7 +149,6 @@ dependencies { implementation 'com.google.android.material:material:1.12.0' implementation 'androidx.webkit:webkit:1.11.0' - implementation 'com.github.huzongyao:AndroidMagic:v1.1.2' implementation 'com.viliussutkus89:assetextractor-android:1.3.3' androidTestImplementation 'androidx.test.espresso:espresso-core:3.6.1'