Skip to content

Commit 047fe04

Browse files
authored
Feature/craig/check for downloadmanager before downloading (#839)
* Check for DownloadManager being enabled before downloading file * Update string to make it fit better in snackbar
1 parent 28fff5a commit 047fe04

File tree

6 files changed

+70
-8
lines changed

6 files changed

+70
-8
lines changed

app/src/main/java/com/duckduckgo/app/browser/BrowserTabFragment.kt

Lines changed: 24 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -29,6 +29,7 @@ import android.content.res.Configuration
2929
import android.media.MediaScannerConnection
3030
import android.net.Uri
3131
import android.os.*
32+
import android.provider.Settings
3233
import android.text.Editable
3334
import android.view.*
3435
import android.view.View.*
@@ -63,6 +64,7 @@ import com.duckduckgo.app.brokensite.BrokenSiteActivity
6364
import com.duckduckgo.app.brokensite.BrokenSiteData
6465
import com.duckduckgo.app.browser.BrowserTabViewModel.*
6566
import com.duckduckgo.app.browser.autocomplete.BrowserAutoCompleteSuggestionsAdapter
67+
import com.duckduckgo.app.browser.downloader.DownloadFailReason
6668
import com.duckduckgo.app.browser.downloader.FileDownloadNotificationManager
6769
import com.duckduckgo.app.browser.downloader.FileDownloader
6870
import com.duckduckgo.app.browser.downloader.FileDownloader.FileDownloadListener
@@ -1112,9 +1114,30 @@ class BrowserTabFragment : Fragment(), FindListener, CoroutineScope, DaxDialogLi
11121114
}
11131115
}
11141116

1115-
override fun downloadFailed(message: String) {
1117+
override fun downloadFailed(message: String, downloadFailReason: DownloadFailReason) {
11161118
Timber.w("Failed to download file [$message]")
1119+
11171120
fileDownloadNotificationManager.showDownloadFailedNotification()
1121+
1122+
val snackbar = Snackbar.make(toolbar, R.string.downloadFailed, Snackbar.LENGTH_INDEFINITE)
1123+
if (downloadFailReason == DownloadFailReason.DownloadManagerDisabled) {
1124+
snackbar.setText(message)
1125+
snackbar.setAction(getString(R.string.enable)) {
1126+
showDownloadManagerAppSettings()
1127+
}
1128+
}
1129+
snackbar.show()
1130+
}
1131+
1132+
private fun showDownloadManagerAppSettings() {
1133+
try {
1134+
val intent = Intent(Settings.ACTION_APPLICATION_DETAILS_SETTINGS)
1135+
intent.data = DownloadFailReason.DOWNLOAD_MANAGER_SETTINGS_URI
1136+
startActivity(intent)
1137+
} catch (e: ActivityNotFoundException) {
1138+
Timber.w(e, "Could not open DownloadManager settings")
1139+
Snackbar.make(toolbar, R.string.downloadManagerIncompatible, Snackbar.LENGTH_INDEFINITE).show()
1140+
}
11181141
}
11191142
}
11201143
}

app/src/main/java/com/duckduckgo/app/browser/downloader/DataUriDownloader.kt

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -38,7 +38,7 @@ class DataUriDownloader @Inject constructor(
3838
when (val parsedDataUri = dataUriParser.generate(pending.url)) {
3939
is ParseResult.Invalid -> {
4040
Timber.w("Failed to extract data from data URI")
41-
callback?.downloadFailed("Failed to extract data from data URI")
41+
callback?.downloadFailed("Failed to extract data from data URI", DownloadFailReason.DataUriParseException)
4242
return
4343
}
4444
is ParseResult.ParsedDataUri -> {
@@ -50,7 +50,7 @@ class DataUriDownloader @Inject constructor(
5050
}
5151
} catch (e: IOException) {
5252
Timber.e(e, "Failed to save data uri")
53-
callback?.downloadFailed("Failed to download data uri")
53+
callback?.downloadFailed("Failed to download data uri", DownloadFailReason.DataUriParseException)
5454
}
5555
}
5656

app/src/main/java/com/duckduckgo/app/browser/downloader/FileDownloadNotificationManager.kt

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -70,7 +70,6 @@ class FileDownloadNotificationManager @Inject constructor(
7070

7171
fun showDownloadFailedNotification() {
7272
applicationContext.runOnUiThread {
73-
applicationContext.longToast(getString(R.string.downloadFailed))
7473

7574
val notification = NotificationCompat.Builder(applicationContext, ChannelType.FILE_DOWNLOADED.id)
7675
.setContentTitle(applicationContext.getString(R.string.downloadFailed))

app/src/main/java/com/duckduckgo/app/browser/downloader/FileDownloader.kt

Lines changed: 16 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,7 @@
1616

1717
package com.duckduckgo.app.browser.downloader
1818

19+
import android.net.Uri
1920
import android.os.Environment
2021
import android.webkit.URLUtil
2122
import androidx.annotation.WorkerThread
@@ -32,9 +33,9 @@ class FileDownloader @Inject constructor(
3233
@WorkerThread
3334
fun download(pending: PendingFileDownload, callback: FileDownloadListener) {
3435
when {
35-
pending.isNetworkUrl -> networkFileDownloader.download(pending)
36+
pending.isNetworkUrl -> networkFileDownloader.download(pending, callback)
3637
pending.isDataUrl -> dataUriDownloader.download(pending, callback)
37-
else -> callback.downloadFailed("Not supported")
38+
else -> callback.downloadFailed("Not supported", DownloadFailReason.UnsupportedUrlType)
3839
}
3940
}
4041

@@ -50,7 +51,7 @@ class FileDownloader @Inject constructor(
5051
interface FileDownloadListener {
5152
fun downloadStarted()
5253
fun downloadFinished(file: File, mimeType: String?)
53-
fun downloadFailed(message: String)
54+
fun downloadFailed(message: String, downloadFailReason: DownloadFailReason)
5455
}
5556
}
5657

@@ -63,3 +64,15 @@ fun FileDownloader.PendingFileDownload.guessFileName(): String {
6364
val FileDownloader.PendingFileDownload.isDataUrl get() = URLUtil.isDataUrl(url)
6465

6566
val FileDownloader.PendingFileDownload.isNetworkUrl get() = URLUtil.isNetworkUrl(url)
67+
68+
sealed class DownloadFailReason {
69+
70+
object DownloadManagerDisabled : DownloadFailReason()
71+
object UnsupportedUrlType : DownloadFailReason()
72+
object Other : DownloadFailReason()
73+
object DataUriParseException : DownloadFailReason()
74+
75+
companion object {
76+
val DOWNLOAD_MANAGER_SETTINGS_URI: Uri = Uri.parse("package:com.android.providers.downloads")
77+
}
78+
}

app/src/main/java/com/duckduckgo/app/browser/downloader/NetworkFileDownloader.kt

Lines changed: 22 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -18,14 +18,22 @@ package com.duckduckgo.app.browser.downloader
1818

1919
import android.app.DownloadManager
2020
import android.content.Context
21+
import android.content.pm.PackageManager.*
2122
import android.webkit.CookieManager
2223
import androidx.core.net.toUri
24+
import com.duckduckgo.app.browser.R
2325
import com.duckduckgo.app.browser.downloader.FileDownloader.PendingFileDownload
2426
import javax.inject.Inject
2527

2628
class NetworkFileDownloader @Inject constructor(private val context: Context) {
2729

28-
fun download(pendingDownload: PendingFileDownload) {
30+
fun download(pendingDownload: PendingFileDownload, callback: FileDownloader.FileDownloadListener) {
31+
32+
if (!downloadManagerAvailable()) {
33+
callback.downloadFailed(context.getString(R.string.downloadManagerDisabled), DownloadFailReason.DownloadManagerDisabled)
34+
return
35+
}
36+
2937
val guessedFileName = pendingDownload.guessFileName()
3038

3139
val request = DownloadManager.Request(pendingDownload.url.toUri()).apply {
@@ -39,4 +47,17 @@ class NetworkFileDownloader @Inject constructor(private val context: Context) {
3947
val manager = context.getSystemService(Context.DOWNLOAD_SERVICE) as DownloadManager?
4048
manager?.enqueue(request)
4149
}
50+
51+
private fun downloadManagerAvailable(): Boolean {
52+
return when (context.packageManager.getApplicationEnabledSetting(DOWNLOAD_MANAGER_PACKAGE)) {
53+
COMPONENT_ENABLED_STATE_DISABLED -> false
54+
COMPONENT_ENABLED_STATE_DISABLED_USER -> false
55+
COMPONENT_ENABLED_STATE_DISABLED_UNTIL_USED -> false
56+
else -> true
57+
}
58+
}
59+
60+
companion object {
61+
private const val DOWNLOAD_MANAGER_PACKAGE = "com.android.providers.downloads"
62+
}
4263
}

app/src/main/res/values/string-untranslated.xml

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -69,4 +69,10 @@
6969
<string name="fireproofWebsiteEmptyListHint">No websites fireproofed yet</string>
7070
<string name="fireproofWebsiteFeatureDescription">Websites rely on cookies to keep you signed in. When you Fireproof a site, cookies won\'t be erased and you\'ll stay signed in, even after using the Fire Button.</string>
7171
<string name="fireproofWebsiteOverflowContentDescription">More options for fireproof website %s</string>
72+
73+
<!-- Download Manager problems -->
74+
<string name="downloadManagerDisabled">Download Manager is disabled</string>
75+
<string name="downloadManagerIncompatible">Download Manager not available on this device</string>
76+
<string name="enable">Enable</string>
77+
7278
</resources>

0 commit comments

Comments
 (0)