From 07b85289dd7c9575f59f8b935fe0256b6e861f86 Mon Sep 17 00:00:00 2001 From: Prateek Jain Date: Thu, 26 Dec 2019 18:12:30 +0530 Subject: [PATCH 01/10] Showing confirmation dialog to user to confirm download --- .../app/browser/BrowserTabFragment.kt | 7 +++ .../browser/DownloadConfirmationFragment.kt | 44 +++++++++++++ .../app/browser/downloader/FileDownloader.kt | 6 +- .../downloader/NetworkFileDownloader.kt | 20 +++++- .../main/res/layout/download_confirmation.xml | 63 +++++++++++++++++++ app/src/main/res/values/strings.xml | 2 + 6 files changed, 138 insertions(+), 4 deletions(-) create mode 100644 app/src/main/java/com/duckduckgo/app/browser/DownloadConfirmationFragment.kt create mode 100644 app/src/main/res/layout/download_confirmation.xml diff --git a/app/src/main/java/com/duckduckgo/app/browser/BrowserTabFragment.kt b/app/src/main/java/com/duckduckgo/app/browser/BrowserTabFragment.kt index a1f998ac4adc..9984ff802c35 100644 --- a/app/src/main/java/com/duckduckgo/app/browser/BrowserTabFragment.kt +++ b/app/src/main/java/com/duckduckgo/app/browser/BrowserTabFragment.kt @@ -62,6 +62,7 @@ import com.duckduckgo.app.browser.autocomplete.BrowserAutoCompleteSuggestionsAda import com.duckduckgo.app.browser.downloader.FileDownloadNotificationManager import com.duckduckgo.app.browser.downloader.FileDownloader import com.duckduckgo.app.browser.downloader.FileDownloader.PendingFileDownload +import com.duckduckgo.app.browser.downloader.NetworkFileDownloader.UserDownloadAction import com.duckduckgo.app.browser.filechooser.FileChooserIntentBuilder import com.duckduckgo.app.browser.model.BasicAuthenticationCredentials import com.duckduckgo.app.browser.model.BasicAuthenticationRequest @@ -1010,6 +1011,11 @@ class BrowserTabFragment : Fragment(), FindListener, CoroutineScope { pendingFileDownload = null thread { fileDownloader.download(pendingDownload, object : FileDownloader.FileDownloadListener { + override fun confirmDownload(fileName: String, userDownloadAction: UserDownloadAction) { + val downloadConfirmationFragment = DownloadConfirmationFragment(fileName, userDownloadAction) + downloadConfirmationFragment.show(fragmentManager!!, DOWNLAOD_CONFIRM_TAG) + } + override fun downloadStarted() { fileDownloadNotificationManager.showDownloadInProgressNotification() } @@ -1090,6 +1096,7 @@ class BrowserTabFragment : Fragment(), FindListener, CoroutineScope { private const val URL_BUNDLE_KEY = "url" private const val AUTHENTICATION_DIALOG_TAG = "AUTH_DIALOG_TAG" + private const val DOWNLAOD_CONFIRM_TAG = "DOWNLAOD_CONFIRM_TAG" private const val DAX_DIALOG_DIALOG_TAG = "DAX_DIALOG_TAG" private const val MIN_PROGRESS = 10 diff --git a/app/src/main/java/com/duckduckgo/app/browser/DownloadConfirmationFragment.kt b/app/src/main/java/com/duckduckgo/app/browser/DownloadConfirmationFragment.kt new file mode 100644 index 000000000000..04890db941c3 --- /dev/null +++ b/app/src/main/java/com/duckduckgo/app/browser/DownloadConfirmationFragment.kt @@ -0,0 +1,44 @@ +/* + * Copyright (c) 2019 DuckDuckGo + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package com.duckduckgo.app.browser + +import android.annotation.SuppressLint +import android.app.Dialog +import android.view.LayoutInflater +import com.duckduckgo.app.browser.downloader.NetworkFileDownloader +import com.google.android.material.bottomsheet.BottomSheetDialogFragment +import kotlinx.android.synthetic.main.download_confirmation.view.* + +class DownloadConfirmationFragment(private val fileName: String, private val userDownloadAction: NetworkFileDownloader.UserDownloadAction) : BottomSheetDialogFragment() { + + @SuppressLint("RestrictedApi") + override fun setupDialog(dialog: Dialog, style: Int) { + super.setupDialog(dialog, style) + val view = LayoutInflater.from(context).inflate(R.layout.download_confirmation, null) + dialog.setContentView(view) + + view.download_message.text = getString(R.string.download_filename, fileName) + view.continue_download.setOnClickListener { + userDownloadAction.accept() + dismiss() + } + view.cancel.setOnClickListener { + userDownloadAction.cancel() + dismiss() + } + } +} \ No newline at end of file diff --git a/app/src/main/java/com/duckduckgo/app/browser/downloader/FileDownloader.kt b/app/src/main/java/com/duckduckgo/app/browser/downloader/FileDownloader.kt index a2157c8d1f09..2c67b0bde8d3 100644 --- a/app/src/main/java/com/duckduckgo/app/browser/downloader/FileDownloader.kt +++ b/app/src/main/java/com/duckduckgo/app/browser/downloader/FileDownloader.kt @@ -19,6 +19,7 @@ package com.duckduckgo.app.browser.downloader import android.os.Environment import android.webkit.URLUtil import androidx.annotation.WorkerThread +import com.duckduckgo.app.browser.downloader.NetworkFileDownloader.UserDownloadAction import java.io.File import javax.inject.Inject @@ -28,14 +29,14 @@ class FileDownloader @Inject constructor( ) { @WorkerThread - fun download(pending: PendingFileDownload?, callback: FileDownloadListener?) { + fun download(pending: PendingFileDownload?, callback: FileDownloadListener) { if (pending == null) { return } when { - URLUtil.isNetworkUrl(pending.url) -> networkDownloader.download(pending) + URLUtil.isNetworkUrl(pending.url) -> networkDownloader.download(pending, callback) URLUtil.isDataUrl(pending.url) -> dataUriDownloader.download(pending, callback) else -> callback?.downloadFailed("Not supported") } @@ -50,6 +51,7 @@ class FileDownloader @Inject constructor( ) interface FileDownloadListener { + fun confirmDownload(fileName: String, userDownloadAction: UserDownloadAction) fun downloadStarted() fun downloadFinished(file: File, mimeType: String?) fun downloadFailed(message: String) diff --git a/app/src/main/java/com/duckduckgo/app/browser/downloader/NetworkFileDownloader.kt b/app/src/main/java/com/duckduckgo/app/browser/downloader/NetworkFileDownloader.kt index 4c4c6d0caaba..e40973ebb379 100644 --- a/app/src/main/java/com/duckduckgo/app/browser/downloader/NetworkFileDownloader.kt +++ b/app/src/main/java/com/duckduckgo/app/browser/downloader/NetworkFileDownloader.kt @@ -21,14 +21,26 @@ import android.content.Context import android.webkit.CookieManager import android.webkit.URLUtil import androidx.core.net.toUri +import com.duckduckgo.app.browser.downloader.FileDownloader.FileDownloadListener import timber.log.Timber import javax.inject.Inject class NetworkFileDownloader @Inject constructor(private val context: Context) { - fun download(pendingDownload: FileDownloader.PendingFileDownload) { + fun download(pendingDownload: FileDownloader.PendingFileDownload, callback: FileDownloadListener) { val guessedFileName = guessFileName(pendingDownload) + callback.confirmDownload(guessedFileName, object : UserDownloadAction { + override fun accept() { + initiateDownload(pendingDownload, guessedFileName) + } + override fun cancel() { + Timber.i("Cancelled download for url ${pendingDownload.url}") + } + }) + } + + private fun initiateDownload(pendingDownload: FileDownloader.PendingFileDownload, guessedFileName: String?) { val request = DownloadManager.Request(pendingDownload.url.toUri()).apply { allowScanningByMediaScanner() addRequestHeader("Cookie", CookieManager.getInstance().getCookie(pendingDownload.url)) @@ -39,10 +51,14 @@ class NetworkFileDownloader @Inject constructor(private val context: Context) { manager?.enqueue(request) } - private fun guessFileName(pending: FileDownloader.PendingFileDownload): String? { + private fun guessFileName(pending: FileDownloader.PendingFileDownload): String { val guessedFileName = URLUtil.guessFileName(pending.url, pending.contentDisposition, pending.mimeType) Timber.i("Guessed filename of $guessedFileName for url ${pending.url}") return guessedFileName } + interface UserDownloadAction { + fun accept() + fun cancel() + } } \ No newline at end of file diff --git a/app/src/main/res/layout/download_confirmation.xml b/app/src/main/res/layout/download_confirmation.xml new file mode 100644 index 000000000000..719823325e8e --- /dev/null +++ b/app/src/main/res/layout/download_confirmation.xml @@ -0,0 +1,63 @@ + + + + + + + + + + +