Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
5 changes: 2 additions & 3 deletions app/build.gradle
Original file line number Diff line number Diff line change
Expand Up @@ -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"
Expand Down Expand Up @@ -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'
Expand Down
9 changes: 9 additions & 0 deletions app/conandeployer.py
Original file line number Diff line number Diff line change
Expand Up @@ -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,
)
2 changes: 1 addition & 1 deletion app/conanfile.txt
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
[requires]
odrcore/5.0.7
odrcore/5.1.1

[generators]
CMakeToolchain
Expand Down
13 changes: 13 additions & 0 deletions app/src/main/cpp/core_wrapper.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -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<AndroidLogger>();

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) {
Expand Down
4 changes: 4 additions & 0 deletions app/src/main/cpp/core_wrapper.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -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);
Expand Down
11 changes: 11 additions & 0 deletions app/src/main/java/at/tomtasche/reader/background/CoreWrapper.java
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,8 @@ public static class GlobalParams {
public String fontconfigDataPath;
public String popplerDataPath;
public String pdf2htmlexDataPath;
public String libmagicDatabasePath;

public String customTmpfilePath;
}

Expand All @@ -29,23 +31,32 @@ 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();
ae.extract(assetsDirectory, "core/odrcore");
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;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -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;
Expand All @@ -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;
Expand Down Expand Up @@ -113,22 +87,20 @@ 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());
}
mimetype = CoreWrapper.mimetype(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);
Expand All @@ -138,27 +110,27 @@ 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);
}
}

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();
}

Expand All @@ -183,20 +155,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);
}
}
});
}
}
13 changes: 13 additions & 0 deletions app/src/main/res/values-v35/themes.xml
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
<?xml version="1.0" encoding="utf-8"?>
<resources>

<style name="MainTheme" parent="Theme.AppCompat.Light">
<item name="colorPrimary">#ffffff</item>
<item name="colorPrimaryDark">#6b6b6b</item>
<item name="colorAccent">#b5b5b5</item>
<item name="android:textColorPrimary">#6b6b6b</item>
<item name="android:textColorSecondary">#b5b5b5</item>
<item name="android:forceDarkAllowed">true</item>
<item name="android:windowOptOutEdgeToEdgeEnforcement">true</item>
</style>
</resources>
2 changes: 1 addition & 1 deletion build.gradle
Original file line number Diff line number Diff line change
@@ -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
Expand Down
2 changes: 1 addition & 1 deletion gradle/wrapper/gradle-wrapper.properties
Original file line number Diff line number Diff line change
@@ -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
Expand Down
Loading