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
10 changes: 10 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -68,3 +68,13 @@ fastlane/report.xml
.idea/

app/CMakeUserPresets.json

venv/

infra/scw-transfer/.terraform/
infra/scw-transfer/.terraform.lock.hcl
infra/scw-transfer/secret.auto.tfvars

# Terraform state files
*.tfstate
*.tfstate.backup
11 changes: 0 additions & 11 deletions app/build.gradle
Original file line number Diff line number Diff line change
Expand Up @@ -2,8 +2,6 @@ import org.apache.tools.ant.filters.ReplaceTokens

plugins {
id 'com.android.application'
id 'com.google.gms.google-services'
id 'com.google.firebase.crashlytics'
id 'app.opendocument.conanandroidgradleplugin'
}

Expand Down Expand Up @@ -93,8 +91,6 @@ android {
minifyEnabled true
shrinkResources true
proguardFiles getDefaultProguardFile('proguard-android-optimize.txt'), 'proguard-rules.txt'

firebaseCrashlytics.nativeSymbolUploadEnabled true
ndk.debugSymbolLevel = "full"
}
}
Expand Down Expand Up @@ -135,13 +131,6 @@ android {
}

dependencies {
implementation platform('com.google.firebase:firebase-bom:34.1.0')
implementation 'com.google.firebase:firebase-storage'
implementation 'com.google.firebase:firebase-auth'
implementation 'com.google.firebase:firebase-crashlytics-ndk'
implementation 'com.google.firebase:firebase-analytics'
implementation 'com.google.firebase:firebase-config'

implementation 'com.google.android.gms:play-services-ads:24.3.0'
implementation 'com.google.android.play:review:2.0.2'
implementation 'com.google.android.ump:user-messaging-platform:3.1.0'
Expand Down
65 changes: 0 additions & 65 deletions app/src/lite/google-services.json

This file was deleted.

Original file line number Diff line number Diff line change
Expand Up @@ -6,13 +6,12 @@
import android.os.Parcel;
import android.os.Parcelable;

import com.google.firebase.analytics.FirebaseAnalytics;

import java.io.File;
import java.util.LinkedList;
import java.util.List;

import at.tomtasche.reader.nonfree.AnalyticsManager;
import at.tomtasche.reader.nonfree.AnalyticsConstants;
import at.tomtasche.reader.nonfree.CrashManager;

public abstract class FileLoader {
Expand Down Expand Up @@ -86,7 +85,7 @@ void callOnSuccess(Result result) {
mainHandler.post(new Runnable() {
@Override
public void run() {
analyticsManager.report("loader_success_" + type, FirebaseAnalytics.Param.CONTENT_TYPE, result.options.fileType, FirebaseAnalytics.Param.CONTENT, result.options.fileExtension);
analyticsManager.report("loader_success_" + type, AnalyticsConstants.PARAM_CONTENT_TYPE, result.options.fileType, AnalyticsConstants.PARAM_CONTENT, result.options.fileExtension);

FileLoaderListener strongReferenceListener = listener;
if (strongReferenceListener != null) {
Expand All @@ -103,7 +102,7 @@ void callOnError(Result result, Throwable t) {
mainHandler.post(new Runnable() {
@Override
public void run() {
analyticsManager.report("loader_error_" + type, FirebaseAnalytics.Param.CONTENT_TYPE, result.options.fileType, FirebaseAnalytics.Param.CONTENT, result.options.fileExtension);
analyticsManager.report("loader_error_" + type, AnalyticsConstants.PARAM_CONTENT_TYPE, result.options.fileType, AnalyticsConstants.PARAM_CONTENT, result.options.fileExtension);

FileLoaderListener strongReferenceListener = listener;
if (strongReferenceListener != null) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -11,12 +11,11 @@

import com.google.android.gms.common.ConnectionResult;
import com.google.android.gms.common.GoogleApiAvailability;
import com.google.firebase.analytics.FirebaseAnalytics;

import java.io.File;
import java.io.OutputStream;

import at.tomtasche.reader.R;
import at.tomtasche.reader.nonfree.AnalyticsConstants;
import at.tomtasche.reader.nonfree.AnalyticsManager;
import at.tomtasche.reader.nonfree.ConfigManager;
import at.tomtasche.reader.nonfree.CrashManager;
Expand Down Expand Up @@ -134,12 +133,12 @@ public void onSuccess(FileLoader.Result result) {
if (result.loaderType == FileLoader.LoaderType.METADATA) {
if (!coreLoader.isSupported(options)) {
crashManager.log("we do not expect this file to be an ODF: " + options.originalUri.toString());
analyticsManager.report("load_odf_error_expected", FirebaseAnalytics.Param.CONTENT_TYPE, options.fileType);
analyticsManager.report("load_odf_error_expected", AnalyticsConstants.PARAM_CONTENT_TYPE, options.fileType);
}

loadWithType(FileLoader.LoaderType.CORE, options);
} else {
analyticsManager.report("load_success", FirebaseAnalytics.Param.CONTENT_TYPE, options.fileType, FirebaseAnalytics.Param.CONTENT, result.loaderType.toString());
analyticsManager.report("load_success", AnalyticsConstants.PARAM_CONTENT_TYPE, options.fileType, AnalyticsConstants.PARAM_CONTENT, result.loaderType.toString());

if (currentListener != null) {
currentListener.onLoadSuccess(result);
Expand Down Expand Up @@ -167,7 +166,7 @@ public void onError(FileLoader.Result result, Throwable error) {
}

if (result.loaderType == FileLoader.LoaderType.CORE) {
analyticsManager.report("load_odf_error", FirebaseAnalytics.Param.CONTENT_TYPE, options.fileType);
analyticsManager.report("load_odf_error", AnalyticsConstants.PARAM_CONTENT_TYPE, options.fileType);

if (rawLoader.isSupported(options)) {
loadWithType(FileLoader.LoaderType.RAW, options);
Expand All @@ -192,7 +191,7 @@ public void onError(FileLoader.Result result, Throwable error) {

// MetadataLoader failed, so there's no point in trying to parse or upload the file

analyticsManager.report("load_error", FirebaseAnalytics.Param.CONTENT_TYPE, options.fileType, FirebaseAnalytics.Param.CONTENT, result.loaderType.toString());
analyticsManager.report("load_error", AnalyticsConstants.PARAM_CONTENT_TYPE, options.fileType, AnalyticsConstants.PARAM_CONTENT, result.loaderType.toString());

if (currentListener != null) {
currentListener.onError(result, error);
Expand Down Expand Up @@ -238,7 +237,7 @@ private void saveSync(FileLoader.Result lastResult, Uri outFile, String htmlDiff
}
});
} catch (Throwable e) {
analyticsManager.report("save_error", FirebaseAnalytics.Param.CONTENT_TYPE, lastResult.options.fileType);
analyticsManager.report("save_error", AnalyticsConstants.PARAM_CONTENT_TYPE, lastResult.options.fileType);
crashManager.log(e, lastResult.options.originalUri);

if (currentListener != null) {
Expand Down Expand Up @@ -287,4 +286,4 @@ public interface LoaderListener {
void onUnsupported(FileLoader.Result result);
void onSaveError();
}
}
}
128 changes: 49 additions & 79 deletions app/src/main/java/at/tomtasche/reader/background/OnlineLoader.java
Original file line number Diff line number Diff line change
Expand Up @@ -3,21 +3,12 @@
import android.content.Context;
import android.net.Uri;
import android.os.Build;
import android.os.Handler;

import androidx.annotation.RequiresApi;

import com.google.android.gms.tasks.Task;
import com.google.android.gms.tasks.Tasks;
import com.google.firebase.auth.AuthResult;
import com.google.firebase.auth.FirebaseAuth;
import com.google.firebase.storage.FirebaseStorage;
import com.google.firebase.storage.StorageMetadata;
import com.google.firebase.storage.StorageReference;
import com.google.firebase.storage.UploadTask;

import java.io.File;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.io.OutputStreamWriter;
import java.io.PrintWriter;
Expand All @@ -26,14 +17,11 @@
import java.net.URL;
import java.net.URLEncoder;
import java.nio.file.Files;
import java.util.UUID;
import java.util.concurrent.ExecutionException;

import at.tomtasche.reader.nonfree.AnalyticsManager;
import at.tomtasche.reader.nonfree.CrashManager;

public class OnlineLoader extends FileLoader {

private static final String TRANSFER_BASE_URL = "https://transfer.opendocument.app/";

// https://help.joomlatools.com/article/169-google-viewer
// https://developer.mozilla.org/en-US/docs/Web/HTTP/Basics_of_HTTP/MIME_types/Complete_list_of_MIME_types
private static final String[] MIME_WHITELIST = {"text/", "image/", "video/", "audio/",
Expand Down Expand Up @@ -76,26 +64,11 @@ public class OnlineLoader extends FileLoader {

private final CoreLoader coreLoader;

private StorageReference storage;
private FirebaseAuth auth;

public OnlineLoader(Context context, CoreLoader coreLoader) {
super(context, LoaderType.ONLINE);
this.coreLoader = coreLoader;
}

@Override
public void initialize(FileLoaderListener listener, Handler mainHandler, Handler backgroundHandler, AnalyticsManager analyticsManager, CrashManager crashManager) {
super.initialize(listener, mainHandler, backgroundHandler, analyticsManager, crashManager);

try {
storage = FirebaseStorage.getInstance().getReference();
auth = FirebaseAuth.getInstance();
} catch (Throwable e) {
crashManager.log(e);
}
}

@Override
public boolean isSupported(Options options) {
String fileType = options.fileType;
Expand Down Expand Up @@ -129,7 +102,7 @@ public void loadSync(Options options) {
("text/rtf".equals(options.fileType) || "application/vnd.wordperfect".equals(options.fileType) || coreLoader.isSupported(options) || "application/vnd.ms-excel".equals(options.fileType) || "application/msword".equals(options.fileType) || "application/vnd.ms-powerpoint".equals(options.fileType) || options.fileType.startsWith("application/vnd.openxmlformats-officedocument.") || options.fileType.equals("application/pdf"))) {
viewerUri = doOnlineConvert(options);
} else {
viewerUri = doFirebaseConvert(options);
viewerUri = doTransferUpload(options);
}

result.partTitles.add(null);
Expand Down Expand Up @@ -175,66 +148,63 @@ private Uri doOnlineConvert(Options options) throws IOException {
return Uri.parse(basePath + redirectUrl);
}

private Uri doFirebaseConvert(Options options) throws ExecutionException, InterruptedException, UnsupportedEncodingException {
if (auth == null || storage == null) {
throw new RuntimeException("firebase not initialized");
}
private Uri doTransferUpload(Options options) throws IOException {
File binaryFile = AndroidFileCache.getCacheFile(context, options.cacheUri);
String filename = options.filename;
String encodedFilename = URLEncoder.encode(filename, StreamUtil.ENCODING);

Task<AuthResult> authenticationTask = null;
String currentUserId = null;
if (auth.getCurrentUser() != null) {
currentUserId = auth.getCurrentUser().getUid();
} else {
authenticationTask = auth.signInAnonymously();
HttpURLConnection connection = (HttpURLConnection) new URL(TRANSFER_BASE_URL + encodedFilename).openConnection();
connection.setRequestMethod("PUT");
connection.setDoOutput(true);
connection.setInstanceFollowRedirects(false);

try (OutputStream outputStream = connection.getOutputStream()) {
Files.copy(binaryFile.toPath(), outputStream);
outputStream.flush();
}

if (authenticationTask != null) {
Tasks.await(authenticationTask);
int responseCode = connection.getResponseCode();
if (responseCode >= 200 && responseCode < 300) {
String downloadUrl = readBody(connection);
if (downloadUrl == null || downloadUrl.isEmpty()) {
throw new IOException("server couldn't handle request");
}

currentUserId = authenticationTask.getResult().getUser().getUid();
return buildViewerUri(options, downloadUrl.trim());
} else {
String error = readError(connection);
throw new IOException("server couldn't handle request: " + responseCode + " " + error);
}
}

StorageMetadata.Builder metadataBuilder = new StorageMetadata.Builder();
if (!"N/A".equals(options.fileType)) {
metadataBuilder.setContentType(options.fileType);
private Uri buildViewerUri(Options options, String downloadUrl) throws UnsupportedEncodingException {
if (coreLoader.isSupported(options)) {
// ODF does not seem to be supported by google docs viewer
return Uri.parse(MICROSOFT_VIEWER_URL + downloadUrl);
} else {
return Uri.parse(GOOGLE_VIEWER_URL + URLEncoder.encode(downloadUrl, StreamUtil.ENCODING));
}
}

String filePath = currentUserId + "/" + UUID.randomUUID() + "." + options.fileExtension;
StorageReference reference = storage.child("uploads/" + filePath);
UploadTask uploadTask = reference.putFile(options.cacheUri, metadataBuilder.build());
Tasks.await(uploadTask);

if (uploadTask.isSuccessful()) {
Uri viewerUri;
if (coreLoader.isSupported(options)) {
// ODF does not seem to be supported by google docs viewer
String downloadUrl = "https://us-central1-admob-app-id-9025061963.cloudfunctions.net/download?filePath=" + filePath;
private String readBody(HttpURLConnection connection) throws IOException {
InputStream inputStream = connection.getInputStream();
if (inputStream == null) {
return null;
}

viewerUri = Uri.parse(MICROSOFT_VIEWER_URL + downloadUrl);
} else {
Task<Uri> urlTask = reference.getDownloadUrl();
Tasks.await(urlTask);
String downloadUrl = urlTask.getResult().toString();
return StreamUtil.readFully(inputStream);
}

viewerUri = Uri.parse(GOOGLE_VIEWER_URL + URLEncoder.encode(downloadUrl, StreamUtil.ENCODING));
private String readError(HttpURLConnection connection) {
try {
InputStream errorStream = connection.getErrorStream();
if (errorStream == null) {
return null;
}

return viewerUri;
} else {
throw new RuntimeException("server couldn't handle request");
return StreamUtil.readFully(errorStream);
} catch (Throwable t) {
return null;
}
}

@Override
public void close() {
super.close();

backgroundHandler.post(new Runnable() {
@Override
public void run() {
auth = null;
storage = null;
}
});
}
}
Loading
Loading