Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Fixed: Downloads were not automatically starting showing progress when reopening the app(If downloads paused due to any network error). #4130

Draft
wants to merge 8 commits into
base: main
Choose a base branch
from
Original file line number Diff line number Diff line change
Expand Up @@ -148,6 +148,10 @@
},
{
context?.let { context ->
if (isNotConnected) {
noInternetSnackbar()
return@let

Check warning on line 153 in app/src/main/java/org/kiwix/kiwixmobile/nav/destination/library/OnlineLibraryFragment.kt

View check run for this annotation

Codecov / codecov/patch

app/src/main/java/org/kiwix/kiwixmobile/nav/destination/library/OnlineLibraryFragment.kt#L152-L153

Added lines #L152 - L153 were not covered by tests
}
downloader.pauseResumeDownload(
it.downloadId,
it.downloadState.toReadableState(context).contains(getString(string.paused_state))
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -54,7 +54,8 @@ data class DownloadRoomEntity(
val size: String,
val name: String?,
val favIcon: String,
val tags: String? = null
val tags: String? = null,
var pausedByUser: Boolean = false
) {
constructor(downloadUrl: String, downloadId: Long, book: Book, file: String?) : this(
file = file,
Expand Down Expand Up @@ -99,7 +100,8 @@ data class DownloadRoomEntity(
totalSizeOfDownload = download.totalSizeOfDownload,
status = download.state,
error = download.error,
progress = download.progress
progress = download.progress,
pausedByUser = download.pausedByUser
)
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -44,7 +44,7 @@
NotesRoomEntity::class,
DownloadRoomEntity::class
],
version = 5,
version = 6,
exportSchema = false
)
@TypeConverters(HistoryRoomDaoCoverts::class, ZimSourceRoomConverter::class)
Expand All @@ -62,7 +62,13 @@
?: Room.databaseBuilder(context, KiwixRoomDatabase::class.java, "KiwixRoom.db")
// We have already database name called kiwix.db in order to avoid complexity we named
// as kiwixRoom.db
.addMigrations(MIGRATION_1_2, MIGRATION_2_3, MIGRATION_3_4, MIGRATION_4_5)
.addMigrations(
MIGRATION_1_2,
MIGRATION_2_3,
MIGRATION_3_4,
MIGRATION_4_5,
MIGRATION_5_6
)
.build().also { db = it }
}
}
Expand Down Expand Up @@ -202,6 +208,15 @@
}
}

@Suppress("MagicNumber")
private val MIGRATION_5_6 = object : Migration(5, 6) {
override fun migrate(database: SupportSQLiteDatabase) {
database.execSQL(
"ALTER TABLE DownloadRoomEntity ADD COLUMN pausedByUser INTEGER NOT NULL DEFAULT 0"

Check warning on line 215 in core/src/main/java/org/kiwix/kiwixmobile/core/data/KiwixRoomDatabase.kt

View check run for this annotation

Codecov / codecov/patch

core/src/main/java/org/kiwix/kiwixmobile/core/data/KiwixRoomDatabase.kt#L214-L215

Added lines #L214 - L215 were not covered by tests
)
}

Check warning on line 217 in core/src/main/java/org/kiwix/kiwixmobile/core/data/KiwixRoomDatabase.kt

View check run for this annotation

Codecov / codecov/patch

core/src/main/java/org/kiwix/kiwixmobile/core/data/KiwixRoomDatabase.kt#L217

Added line #L217 was not covered by tests
}

fun destroyInstance() {
db = null
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -32,6 +32,7 @@
import org.kiwix.kiwixmobile.core.downloader.downloadManager.DownloadNotificationManager.Companion.ACTION_QUERY_DOWNLOAD_STATUS
import org.kiwix.kiwixmobile.core.downloader.downloadManager.DownloadNotificationManager.Companion.ACTION_RESUME
import org.kiwix.kiwixmobile.core.extensions.isServiceRunning
import org.kiwix.kiwixmobile.core.utils.NetworkUtils
import org.kiwix.kiwixmobile.core.utils.files.Log
import java.util.concurrent.TimeUnit
import javax.inject.Inject
Expand Down Expand Up @@ -65,8 +66,8 @@
if (downloadRoomDao.downloads().blockingFirst().isNotEmpty()) {
// Check if there are active downloads and the service is not running.
// If so, start the DownloadMonitorService to properly track download progress.
if (shouldStartService()) {
startService()
if (shouldStartDownloadMonitorService()) {
startDownloadMonitorService()
} else {
// Do nothing; it is for fixing the error when "if" is used as an expression.
}
Expand All @@ -89,32 +90,85 @@
* Determines if the DownloadMonitorService should be started.
* Checks if there are active downloads and if the service is not already running.
*/
private fun shouldStartService(): Boolean =
private fun shouldStartDownloadMonitorService(): Boolean =
getActiveDownloads().isNotEmpty() &&
!context.isServiceRunning(DownloadMonitorService::class.java)

private fun getActiveDownloads(): List<DownloadRoomEntity> =
downloadRoomDao.downloadRoomEntity().blockingFirst().filter {
it.status != Status.PAUSED && it.status != Status.CANCELLED
}
downloadRoomDao.downloadRoomEntity().blockingFirst().filter(::isActiveDownload)

/**
* Determines if a given download is considered active.
*
* @param download The DownloadRoomEntity to evaluate.
* @return True if the download is active, false otherwise.
*/
private fun isActiveDownload(download: DownloadRoomEntity): Boolean =
(download.status != Status.PAUSED || isPausedAndRetryable(download)) &&
download.status != Status.CANCELLED

/**
* Checks if a paused download is eligible for retry based on its error status and network conditions.
*
* @param download The DownloadRoomEntity to evaluate.
* @return True if the paused download is retryable, false otherwise.
*/
private fun isPausedAndRetryable(download: DownloadRoomEntity): Boolean {
return download.status == Status.PAUSED &&
(
isQueuedForWiFiAndConnected(download) ||
isQueuedForNetwork(download) ||
download.error == Error.WAITING_TO_RETRY ||
download.error == Error.PAUSED_UNKNOWN
) &&
NetworkUtils.isNetworkAvailable(context) &&
!download.pausedByUser
}

/**
* Checks if the download is queued for Wi-Fi and the device is connected to Wi-Fi.
*
* @param download The DownloadRoomEntity to evaluate.
* @return True if the download is queued for Wi-Fi and connected, false otherwise.
*/
private fun isQueuedForWiFiAndConnected(download: DownloadRoomEntity): Boolean =
download.error == Error.QUEUED_FOR_WIFI && NetworkUtils.isWiFi(context)

/**
* Checks if the download is waiting for a network connection and the network is now available.
*
* @param download The DownloadRoomEntity to evaluate.
* @return True if the download is waiting for a network and connected, false otherwise.
*/
private fun isQueuedForNetwork(download: DownloadRoomEntity): Boolean =
download.error == Error.WAITING_FOR_NETWORK && NetworkUtils.isNetworkAvailable(context)

override fun downloadCompleteOrCancelled(intent: Intent) {
synchronized(lock) {
intent.extras?.let {
val downloadId = it.getLong(DownloadManager.EXTRA_DOWNLOAD_ID, -1L)
if (downloadId != -1L) {
context.startService(
getDownloadMonitorIntent(
ACTION_QUERY_DOWNLOAD_STATUS,
downloadId.toInt()
val downloadId = it.getLong(DownloadManager.EXTRA_DOWNLOAD_ID, DEFAULT_INT_VALUE.toLong())
if (downloadId != DEFAULT_INT_VALUE.toLong()) {
try {
context.startService(
getDownloadMonitorIntent(
ACTION_QUERY_DOWNLOAD_STATUS,
downloadId.toInt()
)
)
)
} catch (ignore: Exception) {

Check warning on line 158 in core/src/main/java/org/kiwix/kiwixmobile/core/downloader/downloadManager/DownloadManagerMonitor.kt

View check run for this annotation

Codecov / codecov/patch

core/src/main/java/org/kiwix/kiwixmobile/core/downloader/downloadManager/DownloadManagerMonitor.kt#L158

Added line #L158 was not covered by tests
// Catching exception if application is not in foreground.
// Since we can not start the foreground services from background.
Log.e(
"DOWNLOAD_MONITOR",
"Couldn't start download service. Original exception = $ignore"

Check warning on line 163 in core/src/main/java/org/kiwix/kiwixmobile/core/downloader/downloadManager/DownloadManagerMonitor.kt

View check run for this annotation

Codecov / codecov/patch

core/src/main/java/org/kiwix/kiwixmobile/core/downloader/downloadManager/DownloadManagerMonitor.kt#L161-L163

Added lines #L161 - L163 were not covered by tests
)
}
}
}
}
}

private fun startService() {
private fun startDownloadMonitorService() {
context.startService(Intent(context, DownloadMonitorService::class.java))
}

Expand Down
Loading
Loading