From 704768f952b53727d25cb5d6ecac2bad595f99e2 Mon Sep 17 00:00:00 2001 From: Emily Dixon Date: Wed, 12 Jun 2024 11:47:49 -0700 Subject: [PATCH] Fixes some progress-reporting bugs --- .../vod/demo/UploadNotificationService.kt | 16 +++-- .../upload/viewmodel/UploadListViewModel.kt | 16 +++-- .../com/mux/video/upload/api/MuxUpload.kt | 70 ++++++++++--------- .../mux/video/upload/internal/UploadInfo.kt | 5 +- 4 files changed, 61 insertions(+), 46 deletions(-) diff --git a/app/src/main/java/com/mux/video/vod/demo/UploadNotificationService.kt b/app/src/main/java/com/mux/video/vod/demo/UploadNotificationService.kt index cc6c7428..2fcf5bbf 100644 --- a/app/src/main/java/com/mux/video/vod/demo/UploadNotificationService.kt +++ b/app/src/main/java/com/mux/video/vod/demo/UploadNotificationService.kt @@ -66,6 +66,8 @@ class UploadNotificationService : Service() { // can be commanded to start arbitrary number of times if (uploadListListener == null) { + notify(MuxUploadManager.allUploadJobs()) + val lis = UploadListListener() this.uploadListListener = lis MuxUploadManager.addUploadsUpdatedListener(lis) @@ -169,12 +171,14 @@ class UploadNotificationService : Service() { } } - private fun updateCurrentUploads(uploads: List) { -// this.uploadsByFile.values.forEach { it.clearListeners() } -// uploads.forEach { -// this.uploadsByFile[it.videoFile.path] = it -// it.setStatusListener(UploadStatusListener()) -// } + private fun updateCurrentUploads(incomingUploads: List) { + // listen to status of new uploads + incomingUploads + .filter { !this.uploadsByFile.containsKey(it.videoFile.path) } + .forEach { + this.uploadsByFile[it.videoFile.path] = it + it.setStatusListener(UploadStatusListener()) + } } private inner class UploadListListener : UploadEventListener> { diff --git a/app/src/main/java/com/mux/video/vod/demo/upload/viewmodel/UploadListViewModel.kt b/app/src/main/java/com/mux/video/vod/demo/upload/viewmodel/UploadListViewModel.kt index 9e755ce4..2a02e69e 100644 --- a/app/src/main/java/com/mux/video/vod/demo/upload/viewmodel/UploadListViewModel.kt +++ b/app/src/main/java/com/mux/video/vod/demo/upload/viewmodel/UploadListViewModel.kt @@ -1,6 +1,7 @@ package com.mux.video.vod.demo.upload.viewmodel import android.app.Application +import android.util.Log import androidx.lifecycle.AndroidViewModel import androidx.lifecycle.LiveData import androidx.lifecycle.MutableLiveData @@ -22,9 +23,8 @@ class UploadListViewModel(app: Application) : AndroidViewModel(app) { private val listUpdateListener: UploadEventListener> by lazy { UploadEventListener { newUploads -> - uploadMap.forEach { entry -> entry.value.clearListeners() } - - newUploads.forEach { uploadMap[it.videoFile] = it } + //uploadMap.forEach { entry -> entry.value.clearListeners() } + observeUploads(newUploads) updateUiData(uploadMap.values.toList()) } } @@ -50,11 +50,13 @@ class UploadListViewModel(app: Application) : AndroidViewModel(app) { } private fun observeUploads(recentUploads: List) { - recentUploads.forEach { upload -> - upload.setProgressListener { + recentUploads + .filter { !this.uploadMap.containsKey(it.videoFile) } + .forEach { upload -> + upload.setStatusListener { + updateUiData(uploadMap.values.toList()) + } uploadMap[upload.videoFile] = upload - updateUiData(uploadMap.values.toList()) - } } // recentUploads.forEach } diff --git a/library/src/main/java/com/mux/video/upload/api/MuxUpload.kt b/library/src/main/java/com/mux/video/upload/api/MuxUpload.kt index 983aee10..b2653048 100644 --- a/library/src/main/java/com/mux/video/upload/api/MuxUpload.kt +++ b/library/src/main/java/com/mux/video/upload/api/MuxUpload.kt @@ -94,8 +94,9 @@ class MuxUpload private constructor( private val logger get() = MuxUploadSdk.logger init { - // Catch Events if an upload was already in progress - observeUpload(uploadInfo) + // Catch state if an upload was already in progress + // no need to observe: the Flow will have the most-recent values when queried + uploadInfo.statusFlow?.value?.let { status -> this.lastKnownStatus = status } } /** @@ -202,8 +203,16 @@ class MuxUpload private constructor( */ @MainThread fun setProgressListener(listener: UploadEventListener?) { + if (listener == null) { + observerJob?.cancel("clearing listeners") + observerJob = null + } else { + observeUpload(uploadInfo) + } + progressListener = listener lastKnownProgress?.let { listener?.onEvent(it) } + observeUpload(uploadInfo) } /** @@ -235,14 +244,15 @@ class MuxUpload private constructor( */ @MainThread fun setStatusListener(listener: UploadEventListener?) { - statusListener = listener - listener?.onEvent(currentStatus) if (listener == null) { observerJob?.cancel("clearing listeners") observerJob = null } else { observeUpload(uploadInfo) } + + statusListener = listener + listener?.onEvent(currentStatus) } /** @@ -257,38 +267,34 @@ class MuxUpload private constructor( statusListener = null } - private fun newObserveProgressJob(upload: UploadInfo): Job { + private fun newObserveProgressJob(upload: UploadInfo): Job? { // Job that collects and notifies state updates on the main thread (suspending on main is safe) - return callbackScope.launch { - upload.statusFlow?.let { flow -> - launch { - flow - .collect { status -> - // Update the status of our upload - lastKnownStatus = status - Log.d("Upload", "status $status") - - // Notify the old listeners - when (status) { - is UploadStatus.Uploading -> { progressListener?.onEvent(status.uploadProgress) } - is UploadStatus.UploadPaused -> { progressListener?.onEvent(status.uploadProgress) } - is UploadStatus.UploadSuccess -> { - _successful = true - progressListener?.onEvent(status.uploadProgress) - resultListener?.onEvent(Result.success(status.uploadProgress)) - } - is UploadStatus.UploadFailed -> { - progressListener?.onEvent(status.uploadProgress) // Make sure we're most up-to-date - if (status.exception !is CancellationException) { - _error = status.exception - resultListener?.onEvent(Result.failure(status.exception)) - } + return upload.statusFlow?.let { flow -> + callbackScope.launch { + flow.collect { status -> + // Update the status of our upload + lastKnownStatus = status + + // Notify the old listeners + when (status) { + is UploadStatus.Uploading -> { progressListener?.onEvent(status.uploadProgress) } + is UploadStatus.UploadPaused -> { progressListener?.onEvent(status.uploadProgress) } + is UploadStatus.UploadSuccess -> { + _successful = true + progressListener?.onEvent(status.uploadProgress) + resultListener?.onEvent(Result.success(status.uploadProgress)) + } + is UploadStatus.UploadFailed -> { + progressListener?.onEvent(status.uploadProgress) // Make sure we're most up-to-date + if (status.exception !is CancellationException) { + _error = status.exception + resultListener?.onEvent(Result.failure(status.exception)) } - else -> { } // no relevant info } - - statusListener?.onEvent(status) + else -> { } // no relevant info } + + statusListener?.onEvent(status) } } } diff --git a/library/src/main/java/com/mux/video/upload/internal/UploadInfo.kt b/library/src/main/java/com/mux/video/upload/internal/UploadInfo.kt index a0d31406..7e6d70cf 100644 --- a/library/src/main/java/com/mux/video/upload/internal/UploadInfo.kt +++ b/library/src/main/java/com/mux/video/upload/internal/UploadInfo.kt @@ -28,7 +28,10 @@ internal data class UploadInfo( @JvmSynthetic internal val uploadJob: Deferred>?, @JvmSynthetic internal val statusFlow: StateFlow?, ) { - fun isRunning(): Boolean = uploadJob?.isActive ?: false + fun isRunning(): Boolean = /*uploadJob?.isActive*/ + statusFlow?.value?.let { + it is UploadStatus.Uploading || it is UploadStatus.Started || it is UploadStatus.Preparing + } ?: false } /**