Skip to content

Commit 6652803

Browse files
committed
wip
Signed-off-by: alperozturk96 <alper_ozturk@proton.me>
1 parent d7a2544 commit 6652803

2 files changed

Lines changed: 31 additions & 40 deletions

File tree

app/src/main/java/com/owncloud/android/ui/activity/EditorWebView.java

Lines changed: 6 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -14,9 +14,7 @@
1414
import android.graphics.drawable.Drawable;
1515
import android.graphics.drawable.LayerDrawable;
1616
import android.net.Uri;
17-
import android.os.Bundle;
1817
import android.os.Handler;
19-
import android.os.PersistableBundle;
2018
import android.view.View;
2119
import android.webkit.JavascriptInterface;
2220
import android.webkit.ValueCallback;
@@ -44,8 +42,6 @@
4442

4543
import javax.inject.Inject;
4644

47-
import androidx.annotation.Nullable;
48-
4945
public abstract class EditorWebView extends ExternalSiteWebView {
5046
public static final int REQUEST_LOCAL_FILE = 101;
5147
public ValueCallback<Uri[]> uploadMessage;
@@ -55,8 +51,6 @@ public abstract class EditorWebView extends ExternalSiteWebView {
5551

5652
RichdocumentsWebviewBinding binding;
5753

58-
private RichDocumentDownloader richDocumentDownloader;
59-
6054
@Inject SyncedFolderProvider syncedFolderProvider;
6155

6256
protected void loadUrl(String url) {
@@ -132,12 +126,6 @@ protected void bindView() {
132126
binding = RichdocumentsWebviewBinding.inflate(getLayoutInflater());
133127
}
134128

135-
@Override
136-
public void onCreate(@Nullable Bundle savedInstanceState, @Nullable PersistableBundle persistentState) {
137-
super.onCreate(savedInstanceState, persistentState);
138-
richDocumentDownloader = new RichDocumentDownloader(this);
139-
}
140-
141129
@Override
142130
protected void postOnCreate() {
143131
super.postOnCreate();
@@ -296,8 +284,12 @@ protected void setThumbnailView(final User user) {
296284
}
297285

298286
protected void downloadFile(Uri uri, String filename) {
299-
String userAgent = getWebView().getSettings().getUserAgentString();
300-
richDocumentDownloader.download(uri, filename, userAgent);
287+
// downloadAs is invoked from the WebView JavaScript bridge thread, but WebView methods
288+
// (getSettings) must run on the main thread, so read the user agent there.
289+
runOnUiThread(() -> {
290+
String userAgent = getWebView().getSettings().getUserAgentString();
291+
new RichDocumentDownloader(this).download(uri, filename, userAgent);
292+
});
301293
}
302294

303295
public void setLoadingSnackbar(Snackbar loadingSnackbar) {

app/src/main/java/com/owncloud/android/utils/RichDocumentDownloader.kt

Lines changed: 25 additions & 26 deletions
Original file line numberDiff line numberDiff line change
@@ -32,9 +32,10 @@ class RichDocumentDownloader(private val activity: AppCompatActivity) {
3232
fun download(uri: Uri, filename: String?, userAgent: String?) {
3333
activity.lifecycleScope.launch(Dispatchers.IO) {
3434
runCatching {
35+
// if filename not provided get filename from header
3536
if (filename == null) {
3637
val url = uri.toString()
37-
downloadWithOkHttp(url, filename, userAgent)
38+
downloadWithOkHttp(url, userAgent)
3839
} else {
3940
downloadWithDownloadManager(uri, filename)
4041
}
@@ -45,24 +46,18 @@ class RichDocumentDownloader(private val activity: AppCompatActivity) {
4546
}
4647

4748
private suspend fun downloadWithDownloadManager(url: Uri, filename: String) = withContext(Dispatchers.Main) {
48-
val downloadManager = activity.getSystemService(Context.DOWNLOAD_SERVICE) as DownloadManager?
49-
50-
if (downloadManager == null) {
51-
showMessage(false)
52-
return@withContext
53-
}
54-
55-
val request = DownloadManager.Request(url)
56-
request.allowScanningByMediaScanner()
57-
request.setNotificationVisibility(DownloadManager.Request.VISIBILITY_VISIBLE_NOTIFY_COMPLETED)
58-
59-
// change the name file and your current activity.
60-
request.setDestinationInExternalPublicDir(Environment.DIRECTORY_DOWNLOADS, filename)
61-
62-
downloadManager.enqueue(request)
49+
val downloadManager = activity.getSystemService(Context.DOWNLOAD_SERVICE) as? DownloadManager
50+
?: return@withContext showMessage(false)
51+
52+
DownloadManager.Request(url).apply {
53+
@Suppress("DEPRECATION")
54+
allowScanningByMediaScanner()
55+
setNotificationVisibility(DownloadManager.Request.VISIBILITY_VISIBLE_NOTIFY_COMPLETED)
56+
setDestinationInExternalPublicDir(Environment.DIRECTORY_DOWNLOADS, filename)
57+
}.let(downloadManager::enqueue)
6358
}
6459

65-
private fun downloadWithOkHttp(url: String, filename: String?, userAgent: String?) {
60+
private fun downloadWithOkHttp(url: String, userAgent: String?) {
6661
val requestBuilder = Request.Builder().url(url).get()
6762

6863
CookieManager.getInstance().getCookie(url)?.let { requestBuilder.header(COOKIE_HEADER, it) }
@@ -76,18 +71,20 @@ class RichDocumentDownloader(private val activity: AppCompatActivity) {
7671
return
7772
}
7873

79-
val resolvedName = resolveFileName(filename, response.header(CONTENT_DISPOSITION_HEADER))
74+
val disposition = response.header(CONTENT_DISPOSITION_HEADER)
75+
val resolvedName = resolveFileName(disposition)
8076
val result = saveToDownloads(body, resolvedName)
8177
showMessage(result)
8278
}
8379
}
8480

8581
private fun showMessage(success: Boolean) {
8682
activity.runOnUiThread {
87-
val message = if (success)
83+
val message = if (success) {
8884
R.string.downloader_download_succeeded_ticker
89-
else
85+
} else {
9086
R.string.failed_to_download
87+
}
9188

9289
DisplayUtils.showSnackMessage(activity, message)
9390
}
@@ -106,23 +103,22 @@ class RichDocumentDownloader(private val activity: AppCompatActivity) {
106103
}
107104
}
108105

109-
private fun resolveFileName(provided: String?, disposition: String?): String = provided?.takeIf { it.isNotBlank() }
110-
?: extractFilenameFromDisposition(disposition)
111-
?: randomFilename()
106+
private fun resolveFileName(disposition: String?): String =
107+
extractFilenameFromDisposition(disposition) ?: randomFilename()
112108

113109
private fun extractFilenameFromDisposition(disposition: String?): String? {
114110
if (disposition.isNullOrBlank()) return null
115111
return extractExtendedFilename(disposition) ?: extractPlainFilename(disposition)
116112
}
117113

118114
private fun extractExtendedFilename(disposition: String): String? {
119-
val regex = """filename\*\s*=\s*[^']*''([^;]+)""".toRegex(RegexOption.IGNORE_CASE)
115+
val regex = EXTENDED_FILENAME_REGEX.toRegex(RegexOption.IGNORE_CASE)
120116
val value = regex.find(disposition)?.groupValues?.get(1)?.trim() ?: return null
121-
return runCatching { URLDecoder.decode(value, "UTF-8") }.getOrNull()
117+
return runCatching { URLDecoder.decode(value, EXTENDED_FILENAME_ENCODER) }.getOrNull()
122118
}
123119

124120
private fun extractPlainFilename(disposition: String): String? {
125-
val regex = """filename\s*=\s*"?([^";]+)"?""".toRegex(RegexOption.IGNORE_CASE)
121+
val regex = PLAIN_FILENAME_REGEX.toRegex(RegexOption.IGNORE_CASE)
126122
return regex.find(disposition)?.groupValues?.get(1)?.trim()
127123
}
128124

@@ -136,5 +132,8 @@ class RichDocumentDownloader(private val activity: AppCompatActivity) {
136132
private const val DEFAULT_MIME_TYPE = "application/octet-stream"
137133
private const val TEMP_PREFIX = "richdocument_download"
138134
private const val RANDOM_NAME_LENGTH = 8
135+
private const val EXTENDED_FILENAME_REGEX = """filename\*\s*=\s*[^']*''([^;]+)"""
136+
private const val PLAIN_FILENAME_REGEX = """filename\s*=\s*"?([^";]+)"?"""
137+
private const val EXTENDED_FILENAME_ENCODER = "UTF-8"
139138
}
140139
}

0 commit comments

Comments
 (0)