Skip to content

Commit c4a0775

Browse files
authored
Merge pull request #457 from opendocument-app/remove-file-mode
Remove file mode
2 parents e75c0bb + 1b400c9 commit c4a0775

File tree

7 files changed

+68
-257
lines changed

7 files changed

+68
-257
lines changed

app/src/androidTest/java/at/tomtasche/reader/test/CoreTest.java

Lines changed: 44 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -8,8 +8,10 @@
88
import androidx.test.platform.app.InstrumentationRegistry;
99

1010
import org.junit.After;
11+
import org.junit.AfterClass;
1112
import org.junit.Assert;
1213
import org.junit.Before;
14+
import org.junit.BeforeClass;
1315
import org.junit.Test;
1416
import org.junit.runner.RunWith;
1517

@@ -24,14 +26,49 @@
2426
@LargeTest
2527
@RunWith(AndroidJUnit4.class)
2628
public class CoreTest {
29+
private static Thread serverThread;
2730
private File m_testFile;
2831
private File m_passwordTestFile;
2932
private File m_spreadsheetTestFile;
3033

31-
@Before
32-
public void initializeCore() {
34+
@BeforeClass
35+
public static void startServer() throws InterruptedException {
3336
Context appCtx = InstrumentationRegistry.getInstrumentation().getTargetContext();
3437
CoreWrapper.initialize(appCtx);
38+
39+
// Create server cache directory
40+
File serverCacheDir = new File(appCtx.getCacheDir(), "core/server");
41+
if (!serverCacheDir.isDirectory()) {
42+
serverCacheDir.mkdirs();
43+
}
44+
CoreWrapper.createServer(serverCacheDir.getAbsolutePath());
45+
46+
// Start server in background thread
47+
serverThread = new Thread(() -> {
48+
try {
49+
CoreWrapper.listenServer(29665);
50+
} catch (Exception e) {
51+
e.printStackTrace();
52+
}
53+
});
54+
serverThread.setDaemon(true);
55+
serverThread.start();
56+
57+
// Give server time to start
58+
Thread.sleep(1000);
59+
}
60+
61+
@AfterClass
62+
public static void stopServer() {
63+
CoreWrapper.stopServer();
64+
if (serverThread != null) {
65+
serverThread.interrupt();
66+
}
67+
}
68+
69+
@Before
70+
public void initializeCore() {
71+
// Server is already initialized in @BeforeClass
3572
}
3673

3774
@Before
@@ -89,7 +126,7 @@ public void test() {
89126
coreOptions.editable = true;
90127
coreOptions.cachePath = cachePath.getPath();
91128

92-
CoreWrapper.CoreResult coreResult = CoreWrapper.parse(coreOptions);
129+
CoreWrapper.CoreResult coreResult = CoreWrapper.hostFile("test", coreOptions);
93130
Assert.assertEquals(0, coreResult.errorCode);
94131

95132
File resultFile = new File(cacheDir, "result");
@@ -113,7 +150,7 @@ public void testPasswordProtectedDocumentWithoutPassword() {
113150
coreOptions.editable = false;
114151
coreOptions.cachePath = cachePath.getPath();
115152

116-
CoreWrapper.CoreResult coreResult = CoreWrapper.parse(coreOptions);
153+
CoreWrapper.CoreResult coreResult = CoreWrapper.hostFile("password-test-no-pw", coreOptions);
117154
Assert.assertEquals(-2, coreResult.errorCode);
118155
}
119156

@@ -130,7 +167,7 @@ public void testPasswordProtectedDocumentWithWrongPassword() {
130167
coreOptions.editable = false;
131168
coreOptions.cachePath = cachePath.getPath();
132169

133-
CoreWrapper.CoreResult coreResult = CoreWrapper.parse(coreOptions);
170+
CoreWrapper.CoreResult coreResult = CoreWrapper.hostFile("password-test-wrong-pw", coreOptions);
134171
Assert.assertEquals(-2, coreResult.errorCode);
135172
}
136173

@@ -147,7 +184,7 @@ public void testPasswordProtectedDocumentWithCorrectPassword() {
147184
coreOptions.editable = false;
148185
coreOptions.cachePath = cachePath.getPath();
149186

150-
CoreWrapper.CoreResult coreResult = CoreWrapper.parse(coreOptions);
187+
CoreWrapper.CoreResult coreResult = CoreWrapper.hostFile("password-test-correct-pw", coreOptions);
151188
Assert.assertEquals(0, coreResult.errorCode);
152189
}
153190

@@ -163,7 +200,7 @@ public void testSpreadsheetSheetNames() {
163200
coreOptions.editable = false;
164201
coreOptions.cachePath = cachePath.getPath();
165202

166-
CoreWrapper.CoreResult coreResult = CoreWrapper.parse(coreOptions);
203+
CoreWrapper.CoreResult coreResult = CoreWrapper.hostFile("spreadsheet-test", coreOptions);
167204
Assert.assertEquals("CoreWrapper should successfully parse the ODS file", 0, coreResult.errorCode);
168205

169206
// Verify we have exactly 3 sheets

app/src/main/cpp/core_wrapper.cpp

Lines changed: 0 additions & 156 deletions
Original file line numberDiff line numberDiff line change
@@ -111,162 +111,6 @@ Java_at_tomtasche_reader_background_CoreWrapper_mimetypeNative(JNIEnv *env, jcla
111111
return mimetype;
112112
}
113113

114-
JNIEXPORT jobject JNICALL
115-
Java_at_tomtasche_reader_background_CoreWrapper_parseNative(JNIEnv *env, jclass clazz,
116-
jobject options) {
117-
std::error_code ec;
118-
auto logger = std::make_shared<AndroidLogger>();
119-
120-
jclass resultClass = env->FindClass("at/tomtasche/reader/background/CoreWrapper$CoreResult");
121-
jmethodID resultConstructor = env->GetMethodID(resultClass, "<init>", "()V");
122-
jobject result = env->NewObject(resultClass, resultConstructor);
123-
124-
jfieldID errorField = env->GetFieldID(resultClass, "errorCode", "I");
125-
126-
jclass optionsClass = env->GetObjectClass(options);
127-
std::string inputPathCpp = getStringField(env, optionsClass, options, "inputPath");
128-
129-
try {
130-
std::optional<std::string> passwordCpp;
131-
jfieldID passwordField = env->GetFieldID(optionsClass, "password", "Ljava/lang/String;");
132-
auto password = (jstring) env->GetObjectField(options, passwordField);
133-
if (password != nullptr) {
134-
passwordCpp = convertString(env, password);
135-
}
136-
137-
jfieldID editableField = env->GetFieldID(optionsClass, "editable", "Z");
138-
jboolean editable = env->GetBooleanField(options, editableField);
139-
140-
std::string outputPathCpp = getStringField(env, optionsClass, options, "outputPath");
141-
std::string cachePathCpp = getStringField(env, optionsClass, options, "cachePath");
142-
143-
jclass listClass = env->FindClass("java/util/List");
144-
jmethodID addMethod = env->GetMethodID(listClass, "add", "(Ljava/lang/Object;)Z");
145-
146-
jfieldID pageNamesField = env->GetFieldID(resultClass, "pageNames", "Ljava/util/List;");
147-
auto pageNames = (jobject) env->GetObjectField(result, pageNamesField);
148-
149-
jfieldID pagePathsField = env->GetFieldID(resultClass, "pagePaths", "Ljava/util/List;");
150-
auto pagePaths = (jobject) env->GetObjectField(result, pagePathsField);
151-
152-
jfieldID ooxmlField = env->GetFieldID(optionsClass, "ooxml", "Z");
153-
jboolean ooxml = env->GetBooleanField(options, ooxmlField);
154-
155-
jfieldID txtField = env->GetFieldID(optionsClass, "txt", "Z");
156-
jboolean txt = env->GetBooleanField(options, txtField);
157-
158-
jfieldID pdfField = env->GetFieldID(optionsClass, "pdf", "Z");
159-
jboolean pdf = env->GetBooleanField(options, pdfField);
160-
161-
jfieldID pagingField = env->GetFieldID(optionsClass, "paging", "Z");
162-
jboolean paging = env->GetBooleanField(options, pagingField);
163-
164-
try {
165-
odr::FileType fileType;
166-
try {
167-
const auto types = odr::list_file_types(inputPathCpp, *logger);
168-
if (types.empty()) {
169-
env->SetIntField(result, errorField, -5);
170-
return result;
171-
}
172-
173-
fileType = types.back();
174-
} catch (odr::UnsupportedFileType &e) {
175-
fileType = e.file_type;
176-
}
177-
178-
std::string extensionCpp = odr::file_type_to_string(fileType);
179-
jstring extension = env->NewStringUTF(extensionCpp.c_str());
180-
jfieldID extensionField = env->GetFieldID(resultClass, "extension",
181-
"Ljava/lang/String;");
182-
env->SetObjectField(result, extensionField, extension);
183-
184-
__android_log_print(ANDROID_LOG_VERBOSE, "smn", "Open %s", inputPathCpp.c_str());
185-
186-
auto file = odr::open(inputPathCpp, *logger);
187-
188-
if (file.password_encrypted()) {
189-
if (!passwordCpp.has_value()) {
190-
env->SetIntField(result, errorField, -2);
191-
return result;
192-
}
193-
try {
194-
file = file.decrypt(passwordCpp.value());
195-
} catch (...) {
196-
env->SetIntField(result, errorField, -2);
197-
return result;
198-
}
199-
}
200-
201-
// .doc-files are not real documents in core
202-
if (file.is_document_file() && fileType != odr::FileType::legacy_word_document) {
203-
// TODO this will cause a second load
204-
s_document = file.as_document_file().document();
205-
}
206-
207-
extensionCpp = odr::file_type_to_string(file.file_type());
208-
extension = env->NewStringUTF(extensionCpp.c_str());
209-
env->SetObjectField(result, extensionField, extension);
210-
211-
odr::HtmlConfig htmlConfig;
212-
htmlConfig.editable = editable;
213-
htmlConfig.text_document_margin = paging;
214-
215-
__android_log_print(ANDROID_LOG_VERBOSE, "smn", "Translate to HTML");
216-
217-
std::filesystem::remove_all(cachePathCpp, ec);
218-
std::filesystem::create_directories(cachePathCpp);
219-
odr::HtmlService service = odr::html::translate(file, cachePathCpp, htmlConfig, logger);
220-
odr::Html html = service.bring_offline(outputPathCpp);
221-
std::filesystem::remove_all(cachePathCpp);
222-
223-
for (const odr::HtmlPage &page: html.pages()) {
224-
// Filter out unwanted views based on document type
225-
if (file.is_document_file() && (
226-
(((file.as_document_file().document_type() ==
227-
odr::DocumentType::presentation) ||
228-
(file.as_document_file().document_type() ==
229-
odr::DocumentType::drawing)) &&
230-
(page.name != "document")) ||
231-
((file.as_document_file().document_type() ==
232-
odr::DocumentType::spreadsheet) &&
233-
(page.name == "document")))) {
234-
continue;
235-
}
236-
237-
jstring pageName = env->NewStringUTF(page.name.c_str());
238-
env->CallBooleanMethod(pageNames, addMethod, pageName);
239-
240-
jstring pagePath = env->NewStringUTF(page.path.c_str());
241-
env->CallBooleanMethod(pagePaths, addMethod, pagePath);
242-
}
243-
} catch (const odr::UnknownFileType &e) {
244-
__android_log_print(ANDROID_LOG_ERROR, "smn", "Unknown file type: %s", e.what());
245-
env->SetIntField(result, errorField, -5);
246-
return result;
247-
} catch (const odr::UnsupportedFileType &e) {
248-
__android_log_print(ANDROID_LOG_ERROR, "smn", "Unsupported file type: %s", e.what());
249-
env->SetIntField(result, errorField, -5);
250-
return result;
251-
} catch (const std::exception &e) {
252-
__android_log_print(ANDROID_LOG_ERROR, "smn", "Unhandled C++ exception: %s", e.what());
253-
env->SetIntField(result, errorField, -4);
254-
return result;
255-
} catch (...) {
256-
__android_log_print(ANDROID_LOG_ERROR, "smn",
257-
"Unhandled C++ exception without further information");
258-
env->SetIntField(result, errorField, -4);
259-
return result;
260-
}
261-
} catch (...) {
262-
env->SetIntField(result, errorField, -3);
263-
return result;
264-
}
265-
266-
env->SetIntField(result, errorField, 0);
267-
return result;
268-
}
269-
270114
JNIEXPORT jobject JNICALL
271115
Java_at_tomtasche_reader_background_CoreWrapper_backtranslateNative(JNIEnv *env, jclass clazz,
272116
jobject options,

app/src/main/cpp/core_wrapper.hpp

Lines changed: 0 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -12,10 +12,6 @@ JNIEXPORT jstring JNICALL
1212
Java_at_tomtasche_reader_background_CoreWrapper_mimetypeNative(JNIEnv *env, jclass clazz,
1313
jstring path);
1414

15-
JNIEXPORT jobject JNICALL
16-
Java_at_tomtasche_reader_background_CoreWrapper_parseNative(JNIEnv *env, jclass clazz,
17-
jobject options);
18-
1915
JNIEXPORT jobject JNICALL
2016
Java_at_tomtasche_reader_background_CoreWrapper_backtranslateNative(JNIEnv *env, jclass clazz,
2117
jobject options,

app/src/main/java/at/tomtasche/reader/background/CoreLoader.java

Lines changed: 21 additions & 55 deletions
Original file line numberDiff line numberDiff line change
@@ -19,38 +19,34 @@ public class CoreLoader extends FileLoader {
1919
private CoreWrapper.CoreOptions lastCoreOptions;
2020

2121
private final boolean doOoxml;
22-
private final boolean doHttp;
2322

2423
private Thread httpThread;
2524

26-
public CoreLoader(Context context, ConfigManager configManager, boolean doOoxml, boolean doHttp) {
25+
public CoreLoader(Context context, ConfigManager configManager, boolean doOoxml) {
2726
super(context, LoaderType.CORE);
2827

2928
this.configManager = configManager;
3029
this.doOoxml = doOoxml;
31-
this.doHttp = doHttp;
3230

3331
CoreWrapper.initialize(context);
3432
}
3533

3634
@Override
3735
public void initialize(FileLoaderListener listener, Handler mainHandler, Handler backgroundHandler, AnalyticsManager analyticsManager, CrashManager crashManager) {
38-
if (doHttp) {
39-
File serverCacheDir = new File(context.getCacheDir(), "core/server");
40-
if (!serverCacheDir.isDirectory() && !serverCacheDir.mkdirs()) {
41-
Log.e("CoreLoader", "Failed to create cache directory for CoreWrapper server: " + serverCacheDir.getAbsolutePath());
42-
}
43-
CoreWrapper.createServer(serverCacheDir.getAbsolutePath());
44-
45-
httpThread = new Thread(() -> {
46-
try {
47-
CoreWrapper.listenServer(29665);
48-
} catch (Throwable e) {
49-
crashManager.log(e);
50-
}
51-
});
52-
httpThread.start();
36+
File serverCacheDir = new File(context.getCacheDir(), "core/server");
37+
if (!serverCacheDir.isDirectory() && !serverCacheDir.mkdirs()) {
38+
Log.e("CoreLoader", "Failed to create cache directory for CoreWrapper server: " + serverCacheDir.getAbsolutePath());
5339
}
40+
CoreWrapper.createServer(serverCacheDir.getAbsolutePath());
41+
42+
httpThread = new Thread(() -> {
43+
try {
44+
CoreWrapper.listenServer(29665);
45+
} catch (Throwable e) {
46+
crashManager.log(e);
47+
}
48+
});
49+
httpThread.start();
5450

5551
super.initialize(listener, mainHandler, backgroundHandler, analyticsManager, crashManager);
5652
}
@@ -113,45 +109,15 @@ private void translate(Options options, Result result) throws Exception {
113109

114110
lastCoreOptions = coreOptions;
115111

116-
if (doHttp) {
117-
CoreWrapper.CoreResult coreResult = CoreWrapper.hostFile("odr", coreOptions);
118-
119-
if (coreResult.exception != null) {
120-
throw coreResult.exception;
121-
}
122-
123-
for (int i = 0; i < coreResult.pagePaths.size(); i++) {
124-
result.partTitles.add(coreResult.pageNames.get(i));
125-
result.partUris.add(Uri.parse(coreResult.pagePaths.get(i)));
126-
}
127-
} else {
128-
CoreWrapper.CoreResult coreResult = CoreWrapper.parse(coreOptions);
129-
130-
String coreExtension = coreResult.extension;
131-
if (coreResult.exception == null && "pdf".equals(coreExtension)) {
132-
// some PDFs do not cause an error in the core
133-
// https://github.com/opendocument-app/OpenDocument.droid/issues/348#issuecomment-2446888981
134-
throw new CoreWrapper.CoreCouldNotTranslateException();
135-
} else if (!"unnamed".equals(coreExtension)) {
136-
// "unnamed" refers to default of Meta::typeToString
137-
options.fileExtension = coreExtension;
138-
139-
String fileType = MimeTypeMap.getSingleton().getMimeTypeFromExtension(coreExtension);
140-
if (fileType != null) {
141-
options.fileType = fileType;
142-
}
143-
}
112+
CoreWrapper.CoreResult coreResult = CoreWrapper.hostFile("odr", coreOptions);
144113

145-
if (coreResult.exception != null) {
146-
throw coreResult.exception;
147-
}
148-
149-
for (int i = 0; i < coreResult.pagePaths.size(); i++) {
150-
File entryFile = new File(coreResult.pagePaths.get(i));
114+
if (coreResult.exception != null) {
115+
throw coreResult.exception;
116+
}
151117

152-
result.partTitles.add(coreResult.pageNames.get(i));
153-
result.partUris.add(Uri.fromFile(entryFile));
154-
}
118+
for (int i = 0; i < coreResult.pagePaths.size(); i++) {
119+
result.partTitles.add(coreResult.pageNames.get(i));
120+
result.partUris.add(Uri.parse(coreResult.pagePaths.get(i)));
155121
}
156122
}
157123

0 commit comments

Comments
 (0)