Skip to content

Commit

Permalink
Closes mozilla-mobile#5284: Adds progress bar to download notification
Browse files Browse the repository at this point in the history
  • Loading branch information
sblatz committed Dec 11, 2019
1 parent b99ba71 commit 25aad45
Show file tree
Hide file tree
Showing 3 changed files with 38 additions and 5 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -51,6 +51,8 @@ import java.io.FileOutputStream
import java.io.IOException
import java.io.InputStream
import java.io.OutputStream
import java.util.Timer
import java.util.TimerTask
import kotlin.random.Random

/**
Expand All @@ -62,6 +64,8 @@ import kotlin.random.Random
@Suppress("TooManyFunctions", "LargeClass")
abstract class AbstractFetchDownloadService : Service() {

private var notificationTimer = Timer()

protected abstract val httpClient: Client
@VisibleForTesting
internal val broadcastManager by lazy { LocalBroadcastManager.getInstance(this) }
Expand Down Expand Up @@ -211,6 +215,7 @@ abstract class AbstractFetchDownloadService : Service() {

val notification = try {
performDownload(currentDownloadJobState.state)
notificationTimer.cancel()
when (currentDownloadJobState.status) {
DownloadJobStatus.PAUSED -> {
DownloadNotification.createPausedDownloadNotification(context, currentDownloadJobState.state)
Expand Down Expand Up @@ -257,10 +262,29 @@ abstract class AbstractFetchDownloadService : Service() {
context.registerReceiver(broadcastReceiver, filter)
}

private fun displayOngoingDownloadNotification(download: DownloadState) {
/***
* Android rate limits notifications being sent, so we must send them on a delay so that
* notifications are not dropped
*/
private fun beginOngoingNotificationProgressUpdates(downloadID: Long) {
notificationTimer = Timer()
val downloadJobState = downloadJobs[downloadID] ?: return
val download = downloadJobState.state

val timerTask = object : TimerTask() {
override fun run() {
displayOngoingDownloadNotification(download, downloadJobState.currentBytesCopied)
}
}

notificationTimer.scheduleAtFixedRate(timerTask, 0, PROGRESS_UPDATE_INTERVAL)
}

private fun displayOngoingDownloadNotification(download: DownloadState, bytesCopied: Long) {
val ongoingDownloadNotification = DownloadNotification.createOngoingDownloadNotification(
context,
download
download,
bytesCopied
)

NotificationManagerCompat.from(context).notify(
Expand Down Expand Up @@ -295,7 +319,7 @@ abstract class AbstractFetchDownloadService : Service() {
val newDownloadState = download.withResponse(response.headers, inStream)
downloadJobs[download.id]?.state = newDownloadState

displayOngoingDownloadNotification(newDownloadState)
beginOngoingNotificationProgressUpdates(newDownloadState.id)

useFileStream(newDownloadState, isResumingDownload) { outStream ->
copyInChunks(downloadJobs[download.id]!!, inStream, outStream)
Expand Down Expand Up @@ -445,6 +469,7 @@ abstract class AbstractFetchDownloadService : Service() {
private const val CHUNK_SIZE = 4 * 1024
private const val PARTIAL_CONTENT_STATUS = 206
private const val OK_STATUS = 200
private const val PROGRESS_UPDATE_INTERVAL = 500L

const val EXTRA_DOWNLOAD = "mozilla.components.feature.downloads.extras.DOWNLOAD"
const val EXTRA_DOWNLOAD_STATUS = "mozilla.components.feature.downloads.extras.DOWNLOAD_STATUS"
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -36,17 +36,22 @@ internal object DownloadNotification {
/**
* Build the notification to be displayed while the download service is active.
*/
fun createOngoingDownloadNotification(context: Context, downloadState: DownloadState): Notification {
fun createOngoingDownloadNotification(
context: Context,
downloadState: DownloadState,
bytesCopied: Long
): Notification {
val channelId = ensureChannelExists(context)
val fileSizeText = (downloadState.contentLength?.toMegabyteString() ?: "")
val useIndeterminateProgressBar = downloadState.contentLength == null

return NotificationCompat.Builder(context, channelId)
.setSmallIcon(R.drawable.mozac_feature_download_ic_ongoing_download)
.setContentTitle(downloadState.fileName)
.setContentText(fileSizeText)
.setColor(ContextCompat.getColor(context, R.color.mozac_feature_downloads_notification))
.setCategory(NotificationCompat.CATEGORY_PROGRESS)
.setProgress(1, 0, true)
.setProgress(downloadState.contentLength?.toInt() ?: 0, bytesCopied.toInt(), useIndeterminateProgressBar)
.setOngoing(true)
.addAction(getPauseAction(context, downloadState.id))
.addAction(getCancelAction(context, downloadState.id))
Expand Down
3 changes: 3 additions & 0 deletions docs/changelog.md
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,9 @@ permalink: /changelog/
* [Gecko](https://github.com/mozilla-mobile/android-components/blob/master/buildSrc/src/main/java/Gecko.kt)
* [Configuration](https://github.com/mozilla-mobile/android-components/blob/master/buildSrc/src/main/java/Config.kt)

* **feature-downloads**
* Adds progress bar to ongoing `DownloadNotification`

* **browser-engine-gecko**, **browser-engine-gecko-beta**, **browser-engine-gecko-nightly**
* **Merge day!**
* `browser-engine-gecko`: GeckoView 71.0
Expand Down

0 comments on commit 25aad45

Please sign in to comment.