Removed the fetch library and its code from project.

* Fixed the Downloading for Authentication URL.
This commit is contained in:
MohitMaliFtechiz 2024-08-02 11:54:48 +05:30
parent 775fab14bc
commit 88d828e5ce
14 changed files with 64 additions and 792 deletions

View File

@ -329,8 +329,6 @@ object Libs {
const val barista: String = "com.adevinta.android:barista:" + Versions.barista
const val fetch: String = "com.github.tonyofrancis:fetch:" + Versions.fetch
/**
* https://github.com/ReactiveX/RxJava
*/

View File

@ -94,8 +94,6 @@ object Versions {
const val barista: String = "4.3.0"
const val fetch: String = "3.1.6"
const val rxjava: String = "2.2.21"
const val webkit: String = "1.7.0"

View File

@ -201,7 +201,6 @@ class AllProjectConfigurer {
implementation(Libs.collection_ktx)
implementation(Libs.butterknife)
kapt(Libs.butterknife_compiler)
implementation(Libs.fetch)
implementation(Libs.rxandroid)
implementation(Libs.rxjava)
implementation(Libs.preference_ktx)

View File

@ -248,120 +248,6 @@
],
"relations": []
},
{
"id": "8:8093454424037540087",
"lastPropertyId": "24:4272820830206771469",
"name": "FetchDownloadEntity",
"properties": [
{
"id": "1:7366957113003324901",
"name": "id",
"type": 6,
"flags": 1
},
{
"id": "3:3174500111130052488",
"name": "bookId",
"type": 9
},
{
"id": "4:3949362784963767166",
"name": "title",
"type": 9
},
{
"id": "5:812546090900770347",
"name": "description",
"type": 9
},
{
"id": "6:3129463483413863468",
"name": "language",
"type": 9
},
{
"id": "7:3402286918039853548",
"name": "creator",
"type": 9
},
{
"id": "8:4732753967507809221",
"name": "publisher",
"type": 9
},
{
"id": "9:3239042532048399134",
"name": "date",
"type": 9
},
{
"id": "10:1136584919149973914",
"name": "url",
"type": 9
},
{
"id": "11:4252749008345744598",
"name": "articleCount",
"type": 9
},
{
"id": "12:8625493380854102341",
"name": "mediaCount",
"type": 9
},
{
"id": "13:2787210837560254021",
"name": "size",
"type": 9
},
{
"id": "14:2052022387195277817",
"name": "name",
"type": 9
},
{
"id": "15:1976493094677983679",
"name": "favIcon",
"type": 9
},
{
"id": "16:217454020763036675",
"name": "etaInMilliSeconds",
"type": 6
},
{
"id": "17:1136630637198901642",
"name": "bytesDownloaded",
"type": 6
},
{
"id": "18:8939019296899137627",
"name": "totalSizeOfDownload",
"type": 6
},
{
"id": "21:5555873126720275555",
"name": "file",
"type": 9
},
{
"id": "22:2724607601244650879",
"name": "downloadId",
"type": 6
},
{
"id": "23:5485468735259326535",
"name": "progress",
"type": 5
},
{
"id": "24:4272820830206771469",
"name": "tags",
"type": 9
}
],
"relations": []
},
{
"id": "10:3205842982118792800",
"lastPropertyId": "9:5286545520416917562",
@ -416,7 +302,8 @@
"retiredEntityUids": [
349148274283701276,
7257718270326155947,
7394649290555378565
7394649290555378565,
8093454424037540087
],
"retiredIndexUids": [
1293695782925933448,
@ -470,7 +357,28 @@
4335394620556092321,
1899740026144478138,
3378789699620971394,
6867355950440828062
6867355950440828062,
7366957113003324901,
3174500111130052488,
3949362784963767166,
812546090900770347,
3129463483413863468,
3402286918039853548,
4732753967507809221,
3239042532048399134,
1136584919149973914,
4252749008345744598,
8625493380854102341,
2787210837560254021,
2052022387195277817,
1976493094677983679,
217454020763036675,
1136630637198901642,
8939019296899137627,
5555873126720275555,
2724607601244650879,
5485468735259326535,
4272820830206771469
],
"retiredRelationUids": [],
"version": 1

View File

@ -339,16 +339,6 @@
"name": "totalSizeOfDownload",
"type": 6
},
{
"id": "19:3378789699620971394",
"name": "status",
"type": 5
},
{
"id": "20:6867355950440828062",
"name": "error",
"type": 5
},
{
"id": "21:5555873126720275555",
"name": "file",
@ -478,7 +468,9 @@
8819082642546094709,
7233601933599801875,
4335394620556092321,
1899740026144478138
1899740026144478138,
3378789699620971394,
6867355950440828062
],
"retiredRelationUids": [],
"version": 1

View File

@ -1,107 +0,0 @@
/*
* Kiwix Android
* Copyright (c) 2019 Kiwix <android.kiwix.org>
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*
*/
package org.kiwix.kiwixmobile.core.dao
import io.objectbox.Box
import org.kiwix.kiwixmobile.core.dao.entities.FetchDownloadEntity
import org.kiwix.kiwixmobile.core.entity.LibraryNetworkEntity.Book
import org.kiwix.kiwixmobile.core.utils.SharedPreferenceUtil
import javax.inject.Inject
class FetchDownloadDao @Inject constructor(
private val box: Box<FetchDownloadEntity>,
private val newBookDao: NewBookDao,
private val sharedPreferenceUtil: SharedPreferenceUtil
) {
// fun downloads(): Flowable<List<DownloadModel>> =
// box.asFlowable()
// .distinctUntilChanged()
// .doOnNext(::moveCompletedToBooksOnDiskDao)
// .map { it.map(::DownloadModel) }
// fun allDownloads() = Single.fromCallable { box.all.map(::DownloadModel) }
// private fun moveCompletedToBooksOnDiskDao(downloadEntities: List<FetchDownloadEntity>) {
// downloadEntities.filter { it.status == COMPLETED }.takeIf { it.isNotEmpty() }?.let {
// box.store.callInTx {
// box.remove(it)
// newBookDao.insert(it.map(::BookOnDisk))
// }
// }
// }
// fun update(download: Download) {
// box.store.callInTx {
// getEntityFor(download.id)?.let { dbEntity ->
// dbEntity.updateWith(download)
// .takeIf { updatedEntity -> updatedEntity != dbEntity }
// ?.let(box::put)
// }
// }
// }
// fun getEntityFor(downloadId: Int) =
// box.query {
// equal(FetchDownloadEntity_.downloadId, downloadId)
// }.find().getOrNull(0)
// fun getEntityForFileName(fileName: String) =
// box.query {
// endsWith(
// FetchDownloadEntity_.file, fileName,
// QueryBuilder.StringOrder.CASE_INSENSITIVE
// )
// }.findFirst()
fun insert(downloadId: Long, book: Book, filePath: String?) {
box.put(FetchDownloadEntity(downloadId, book, filePath))
}
// fun delete(downloadId: Long) {
// // remove the previous file from storage since we have cancelled the download.
// getEntityFor(downloadId.toInt())?.file?.let {
// File(it).deleteFile()
// }
// box.query {
// equal(FetchDownloadEntity_.downloadId, downloadId)
// }.remove()
// }
// fun addIfDoesNotExist(
// url: String,
// book: Book,
// downloadRequester: DownloadRequester
// ) {
// box.store.callInTx {
// if (doesNotAlreadyExist(book)) {
// val downloadRequest = DownloadRequest(url, book.title)
// insert(
// downloadRequester.enqueue(downloadRequest),
// book = book,
// filePath = downloadRequest.getDestinationFile(sharedPreferenceUtil).path
// )
// }
// }
// }
// private fun doesNotAlreadyExist(book: Book) =
// box.query {
// equal(FetchDownloadEntity_.bookId, book.id, QueryBuilder.StringOrder.CASE_INSENSITIVE)
// }.count() == 0L
}

View File

@ -1,98 +0,0 @@
/*
* Kiwix Android
* Copyright (c) 2019 Kiwix <android.kiwix.org>
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*
*/
package org.kiwix.kiwixmobile.core.dao.entities
import com.tonyodev.fetch2.Download
import io.objectbox.annotation.Entity
import io.objectbox.annotation.Id
import org.kiwix.kiwixmobile.core.entity.LibraryNetworkEntity.Book
@Entity
data class FetchDownloadEntity(
@Id var id: Long = 0,
var downloadId: Long,
val file: String? = null,
val etaInMilliSeconds: Long = -1L,
val bytesDownloaded: Long = -1L,
val totalSizeOfDownload: Long = -1L,
// @Convert(converter = StatusConverter::class, dbType = Int::class)
// val status: Status = Status.NONE,
// @Convert(converter = ErrorConverter::class, dbType = Int::class)
// val error: Error = Error.NONE,
val progress: Int = -1,
val bookId: String,
val title: String,
val description: String?,
val language: String,
val creator: String,
val publisher: String,
val date: String,
val url: String?,
val articleCount: String?,
val mediaCount: String?,
val size: String,
val name: String?,
val favIcon: String,
val tags: String? = null
) {
constructor(downloadId: Long, book: Book, file: String?) : this(
file = file,
downloadId = downloadId,
bookId = book.id,
title = book.title,
description = book.description,
language = book.language,
creator = book.creator,
publisher = book.publisher,
date = book.date,
url = book.url,
articleCount = book.articleCount,
mediaCount = book.mediaCount,
size = book.size,
name = book.bookName,
favIcon = book.favicon,
tags = book.tags
)
fun toBook() = Book().apply {
id = bookId
title = this@FetchDownloadEntity.title
description = this@FetchDownloadEntity.description
language = this@FetchDownloadEntity.language
creator = this@FetchDownloadEntity.creator
publisher = this@FetchDownloadEntity.publisher
date = this@FetchDownloadEntity.date
url = this@FetchDownloadEntity.url
articleCount = this@FetchDownloadEntity.articleCount
mediaCount = this@FetchDownloadEntity.mediaCount
size = this@FetchDownloadEntity.size
bookName = name
favicon = favIcon
tags = this@FetchDownloadEntity.tags
}
fun updateWith(download: Download) = copy(
file = download.file,
etaInMilliSeconds = download.etaInMilliSeconds,
bytesDownloaded = download.downloaded,
totalSizeOfDownload = download.total,
// status = download.status,
// error = download.error,
progress = download.progress
)
}

View File

@ -30,7 +30,6 @@ import kotlinx.coroutines.sync.Mutex
import org.kiwix.kiwixmobile.core.CoreApp
import org.kiwix.kiwixmobile.core.StorageObserver
import org.kiwix.kiwixmobile.core.dao.DownloadRoomDao
import org.kiwix.kiwixmobile.core.dao.FetchDownloadDao
import org.kiwix.kiwixmobile.core.dao.HistoryDao
import org.kiwix.kiwixmobile.core.dao.HistoryRoomDao
import org.kiwix.kiwixmobile.core.dao.LibkiwixBookmarks
@ -97,7 +96,6 @@ interface CoreComponent {
fun application(): Application
fun bookUtils(): BookUtils
fun dataSource(): DataSource
fun fetchDownloadDao(): FetchDownloadDao
fun newBookDao(): NewBookDao
fun historyDao(): HistoryDao
fun noteDao(): NewNoteDao

View File

@ -22,7 +22,6 @@ import dagger.Module
import dagger.Provides
import io.objectbox.BoxStore
import io.objectbox.kotlin.boxFor
import org.kiwix.kiwixmobile.core.dao.FetchDownloadDao
import org.kiwix.kiwixmobile.core.dao.FlowBuilder
import org.kiwix.kiwixmobile.core.dao.HistoryDao
import org.kiwix.kiwixmobile.core.dao.NewBookDao
@ -32,7 +31,6 @@ import org.kiwix.kiwixmobile.core.dao.NewNoteDao
import org.kiwix.kiwixmobile.core.dao.NewRecentSearchDao
import org.kiwix.kiwixmobile.core.dao.entities.MyObjectBox
import org.kiwix.kiwixmobile.core.data.KiwixRoomDatabase
import org.kiwix.kiwixmobile.core.utils.SharedPreferenceUtil
import javax.inject.Singleton
@Module
@ -70,13 +68,6 @@ open class DatabaseModule {
flowBuilder: FlowBuilder
): NewRecentSearchDao = NewRecentSearchDao(boxStore.boxFor(), flowBuilder)
@Provides @Singleton fun providesFetchDownloadDao(
boxStore: BoxStore,
newBookDao: NewBookDao,
sharedPreferenceUtil: SharedPreferenceUtil
): FetchDownloadDao =
FetchDownloadDao(boxStore.boxFor(), newBookDao, sharedPreferenceUtil)
@Singleton
@Provides
fun provideYourDatabase(

View File

@ -20,18 +20,9 @@ package org.kiwix.kiwixmobile.core.di.modules
import android.app.DownloadManager
import android.app.NotificationManager
import android.content.Context
import com.tonyodev.fetch2.Fetch
import com.tonyodev.fetch2.Fetch.Impl
import com.tonyodev.fetch2.FetchConfiguration
import com.tonyodev.fetch2.FetchNotificationManager
import com.tonyodev.fetch2okhttp.OkHttpDownloader
import dagger.Module
import dagger.Provides
import okhttp3.OkHttpClient
import org.kiwix.kiwixmobile.core.BuildConfig
import org.kiwix.kiwixmobile.core.dao.DownloadRoomDao
import org.kiwix.kiwixmobile.core.dao.FetchDownloadDao
import org.kiwix.kiwixmobile.core.data.remote.BasicAuthInterceptor
import org.kiwix.kiwixmobile.core.data.remote.KiwixService
import org.kiwix.kiwixmobile.core.downloader.DownloadRequester
import org.kiwix.kiwixmobile.core.downloader.Downloader
@ -41,11 +32,7 @@ import org.kiwix.kiwixmobile.core.downloader.downloadManager.DownloadManagerMoni
import org.kiwix.kiwixmobile.core.downloader.downloadManager.DownloadManagerRequester
import org.kiwix.kiwixmobile.core.downloader.downloadManager.DownloadNotificationActionsBroadcastReceiver
import org.kiwix.kiwixmobile.core.downloader.downloadManager.DownloadNotificationManager
import org.kiwix.kiwixmobile.core.downloader.fetch.FetchDownloadNotificationManager
import org.kiwix.kiwixmobile.core.utils.CONNECT_TIME_OUT
import org.kiwix.kiwixmobile.core.utils.READ_TIME_OUT
import org.kiwix.kiwixmobile.core.utils.SharedPreferenceUtil
import java.util.concurrent.TimeUnit
import javax.inject.Singleton
@Module
@ -60,49 +47,6 @@ object DownloaderModule {
): Downloader =
DownloaderImpl(downloadRequester, downloadRoomDao, kiwixService, sharedPreferenceUtil)
// @Provides
// @Singleton
// fun providesDownloadRequester(fetch: Fetch, sharedPreferenceUtil: SharedPreferenceUtil):
// DownloadRequester = FetchDownloadRequester(fetch, sharedPreferenceUtil)
@Provides
@Singleton
fun provideFetch(fetchConfiguration: FetchConfiguration): Fetch =
Fetch.getInstance(fetchConfiguration)
@Provides
@Singleton
fun provideFetchConfiguration(
context: Context,
okHttpDownloader: OkHttpDownloader,
fetchNotificationManager: FetchNotificationManager
): FetchConfiguration =
FetchConfiguration.Builder(context).apply {
setDownloadConcurrentLimit(5)
enableLogging(BuildConfig.DEBUG)
enableRetryOnNetworkGain(true)
setHttpDownloader(okHttpDownloader)
preAllocateFileOnCreation(false)
setNotificationManager(fetchNotificationManager)
}.build().also(Impl::setDefaultInstanceConfiguration)
@Provides
@Singleton
fun provideOkHttpDownloader() = OkHttpDownloader(
OkHttpClient.Builder()
.connectTimeout(CONNECT_TIME_OUT, TimeUnit.MINUTES)
.readTimeout(READ_TIME_OUT, TimeUnit.MINUTES)
.addInterceptor(BasicAuthInterceptor())
.followRedirects(true)
.followSslRedirects(true)
.build()
)
@Provides
@Singleton
fun provideFetchDownloadNotificationManager(context: Context, fetchDownloadDao: FetchDownloadDao):
FetchNotificationManager = FetchDownloadNotificationManager(context, fetchDownloadDao)
@Provides
@Singleton
fun providesDownloadRequester(

View File

@ -22,9 +22,13 @@ import android.app.DownloadManager
import android.app.DownloadManager.Request
import android.app.DownloadManager.Request.VISIBILITY_HIDDEN
import android.net.Uri
import androidx.core.net.toUri
import kotlinx.coroutines.CoroutineScope
import kotlinx.coroutines.Dispatchers
import kotlinx.coroutines.launch
import org.kiwix.kiwixmobile.core.data.remote.isAuthenticationUrl
import org.kiwix.kiwixmobile.core.data.remote.removeAuthenticationFromUrl
import org.kiwix.kiwixmobile.core.data.remote.secretKey
import org.kiwix.kiwixmobile.core.downloader.DownloadRequester
import org.kiwix.kiwixmobile.core.downloader.model.DownloadRequest
import org.kiwix.kiwixmobile.core.utils.SharedPreferenceUtil
@ -89,7 +93,27 @@ class DownloadManagerRequester @Inject constructor(
fun DownloadRequest.toDownloadManagerRequest(
sharedPreferenceUtil: SharedPreferenceUtil
) =
): DownloadManager.Request {
return if (urlString.isAuthenticationUrl) {
// return the request with "Authorization" header if the url is a Authentication url.
DownloadManager.Request(urlString.removeAuthenticationFromUrl.toUri()).apply {
setDestinationUri(Uri.fromFile(getDestinationFile(sharedPreferenceUtil)))
setAllowedNetworkTypes(
if (sharedPreferenceUtil.prefWifiOnly)
Request.NETWORK_WIFI
else
Request.NETWORK_MOBILE
)
setAllowedOverMetered(true)
setNotificationVisibility(VISIBILITY_HIDDEN) // hide the default notification.
val userNameAndPassword = System.getenv(urlString.secretKey) ?: ""
val userName = userNameAndPassword.substringBefore(":", "")
val password = userNameAndPassword.substringAfter(":", "")
val credentials = okhttp3.Credentials.basic(userName, password)
addRequestHeader("Authorization", credentials)
}
} else {
// return the request for normal urls.
DownloadManager.Request(uri).apply {
setDestinationUri(Uri.fromFile(getDestinationFile(sharedPreferenceUtil)))
setAllowedNetworkTypes(
@ -101,3 +125,5 @@ fun DownloadRequest.toDownloadManagerRequest(
setAllowedOverMetered(true)
setNotificationVisibility(VISIBILITY_HIDDEN) // hide the default notification.
}
}
}

View File

@ -1,119 +0,0 @@
/*
* Kiwix Android
* Copyright (c) 2019 Kiwix <android.kiwix.org>
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*
*/
package org.kiwix.kiwixmobile.core.downloader.fetch
import android.annotation.SuppressLint
import com.tonyodev.fetch2.Download
import com.tonyodev.fetch2.Error
import com.tonyodev.fetch2.Fetch
import com.tonyodev.fetch2.FetchListener
import com.tonyodev.fetch2core.DownloadBlock
import io.reactivex.schedulers.Schedulers
import io.reactivex.subjects.PublishSubject
import org.kiwix.kiwixmobile.core.dao.FetchDownloadDao
import org.kiwix.kiwixmobile.core.downloader.DownloadMonitor
import javax.inject.Inject
@SuppressLint("CheckResult")
class FetchDownloadMonitor @Inject constructor(fetch: Fetch, fetchDownloadDao: FetchDownloadDao) :
DownloadMonitor {
private val updater = PublishSubject.create<() -> Unit>()
private val fetchListener = object : FetchListener {
override fun onAdded(download: Download) {}
override fun onCancelled(download: Download) {
delete(download)
}
override fun onCompleted(download: Download) {
update(download)
}
override fun onDeleted(download: Download) {
delete(download)
}
override fun onDownloadBlockUpdated(
download: Download,
downloadBlock: DownloadBlock,
totalBlocks: Int
) {
update(download)
}
override fun onError(download: Download, error: Error, throwable: Throwable?) {
update(download)
}
override fun onPaused(download: Download) {
update(download)
}
override fun onProgress(
download: Download,
etaInMilliSeconds: Long,
downloadedBytesPerSecond: Long
) {
update(download)
}
override fun onQueued(download: Download, waitingOnNetwork: Boolean) {
update(download)
}
override fun onRemoved(download: Download) {
delete(download)
}
override fun onResumed(download: Download) {
update(download)
}
override fun onStarted(
download: Download,
downloadBlocks: List<DownloadBlock>,
totalBlocks: Int
) {
update(download)
}
override fun onWaitingNetwork(download: Download) {
update(download)
}
private fun update(download: Download) {
// updater.onNext { fetchDownloadDao.update(download) }
}
private fun delete(download: Download) {
// updater.onNext { download.delete(download.id.toLong()) }
}
}
init {
fetch.addListener(fetchListener, true)
updater.subscribeOn(Schedulers.io()).observeOn(Schedulers.io()).subscribe(
{ it.invoke() },
Throwable::printStackTrace
)
}
override fun init() {
// empty method to so class does not get reported unused
}
}

View File

@ -1,193 +0,0 @@
/*
* Kiwix Android
* Copyright (c) 2019 Kiwix <android.kiwix.org>
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*
*/
package org.kiwix.kiwixmobile.core.downloader.fetch
import android.annotation.SuppressLint
import android.app.NotificationChannel
import android.app.NotificationManager
import android.app.PendingIntent
import android.app.PendingIntent.FLAG_IMMUTABLE
import android.app.PendingIntent.FLAG_UPDATE_CURRENT
import android.app.PendingIntent.getActivity
import android.content.Context
import android.content.Intent
import android.os.Build
import android.os.Build.VERSION_CODES
import androidx.annotation.RequiresApi
import androidx.core.app.NotificationCompat
import com.tonyodev.fetch2.ACTION_TYPE_CANCEL
import com.tonyodev.fetch2.ACTION_TYPE_DELETE
import com.tonyodev.fetch2.ACTION_TYPE_INVALID
import com.tonyodev.fetch2.ACTION_TYPE_PAUSE
import com.tonyodev.fetch2.ACTION_TYPE_RESUME
import com.tonyodev.fetch2.ACTION_TYPE_RETRY
import com.tonyodev.fetch2.DefaultFetchNotificationManager
import com.tonyodev.fetch2.DownloadNotification
import com.tonyodev.fetch2.EXTRA_ACTION_TYPE
import com.tonyodev.fetch2.EXTRA_DOWNLOAD_ID
import com.tonyodev.fetch2.EXTRA_GROUP_ACTION
import com.tonyodev.fetch2.EXTRA_NAMESPACE
import com.tonyodev.fetch2.EXTRA_NOTIFICATION_GROUP_ID
import com.tonyodev.fetch2.EXTRA_NOTIFICATION_ID
import com.tonyodev.fetch2.Fetch
import com.tonyodev.fetch2.util.DEFAULT_NOTIFICATION_TIMEOUT_AFTER_RESET
import org.kiwix.kiwixmobile.core.Intents
import org.kiwix.kiwixmobile.core.R
import org.kiwix.kiwixmobile.core.R.string
import org.kiwix.kiwixmobile.core.dao.FetchDownloadDao
import org.kiwix.kiwixmobile.core.downloader.downloadManager.DOWNLOAD_NOTIFICATION_TITLE
import org.kiwix.kiwixmobile.core.main.CoreMainActivity
class FetchDownloadNotificationManager(
private val context: Context,
private val fetchDownloadDao: FetchDownloadDao
) :
DefaultFetchNotificationManager(context) {
override fun getFetchInstanceForNamespace(namespace: String) = Fetch.getDefaultInstance()
override fun createNotificationChannels(
context: Context,
notificationManager: NotificationManager
) {
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
val channelId = context.getString(R.string.fetch_notification_default_channel_id)
if (notificationManager.getNotificationChannel(channelId) == null) {
notificationManager.createNotificationChannel(createChannel(channelId, context))
}
}
}
override fun updateNotification(
notificationBuilder: NotificationCompat.Builder,
downloadNotification: DownloadNotification,
context: Context
) {
// super method but with pause button removed
val smallIcon = if (downloadNotification.isDownloading) {
android.R.drawable.stat_sys_download
} else {
android.R.drawable.stat_sys_download_done
}
val notificationTitle = downloadNotification.title
notificationBuilder.setPriority(NotificationCompat.PRIORITY_DEFAULT)
.setSmallIcon(smallIcon)
.setContentTitle(notificationTitle)
.setContentText(getSubtitleText(context, downloadNotification))
.setOngoing(downloadNotification.isOnGoingNotification)
.setGroup(downloadNotification.groupId.toString())
.setGroupSummary(false)
if (downloadNotification.isFailed || downloadNotification.isCompleted) {
notificationBuilder.setProgress(0, 0, false)
} else {
val progressIndeterminate = downloadNotification.progressIndeterminate
val maxProgress = if (downloadNotification.progressIndeterminate) 0 else 100
val progress = if (downloadNotification.progress < 0) 0 else downloadNotification.progress
notificationBuilder.setProgress(maxProgress, progress, progressIndeterminate)
}
when {
downloadNotification.isDownloading ->
notificationBuilder.setTimeoutAfter(getNotificationTimeOutMillis())
.addAction(
R.drawable.fetch_notification_cancel,
context.getString(R.string.cancel),
getActionPendingIntent(downloadNotification, DownloadNotification.ActionType.DELETE)
).addAction(
R.drawable.fetch_notification_pause,
context.getString(R.string.tts_pause),
getActionPendingIntent(downloadNotification, DownloadNotification.ActionType.PAUSE)
)
downloadNotification.isPaused ->
notificationBuilder.setTimeoutAfter(getNotificationTimeOutMillis())
.addAction(
R.drawable.fetch_notification_resume,
context.getString(R.string.tts_resume),
getActionPendingIntent(downloadNotification, DownloadNotification.ActionType.RESUME)
)
.addAction(
R.drawable.fetch_notification_cancel,
context.getString(R.string.cancel),
getActionPendingIntent(downloadNotification, DownloadNotification.ActionType.DELETE)
)
downloadNotification.isQueued ->
notificationBuilder.setTimeoutAfter(getNotificationTimeOutMillis())
else -> notificationBuilder.setTimeoutAfter(DEFAULT_NOTIFICATION_TIMEOUT_AFTER_RESET)
}
notificationCustomisation(downloadNotification, notificationBuilder, context)
}
override fun getActionPendingIntent(
downloadNotification: DownloadNotification,
actionType: DownloadNotification.ActionType
): PendingIntent {
val intent = Intent(notificationManagerAction).apply {
putExtra(EXTRA_NAMESPACE, downloadNotification.namespace)
putExtra(EXTRA_DOWNLOAD_ID, downloadNotification.notificationId)
putExtra(EXTRA_NOTIFICATION_ID, downloadNotification.notificationId)
putExtra(EXTRA_GROUP_ACTION, false)
putExtra(EXTRA_NOTIFICATION_GROUP_ID, downloadNotification.groupId)
}
val action = when (actionType) {
DownloadNotification.ActionType.CANCEL -> ACTION_TYPE_CANCEL
DownloadNotification.ActionType.DELETE -> ACTION_TYPE_DELETE
DownloadNotification.ActionType.RESUME -> ACTION_TYPE_RESUME
DownloadNotification.ActionType.PAUSE -> ACTION_TYPE_PAUSE
DownloadNotification.ActionType.RETRY -> ACTION_TYPE_RETRY
else -> ACTION_TYPE_INVALID
}
intent.putExtra(EXTRA_ACTION_TYPE, action)
val flags = PendingIntent.FLAG_IMMUTABLE or PendingIntent.FLAG_UPDATE_CURRENT
return PendingIntent.getBroadcast(
context,
downloadNotification.notificationId + action,
intent,
flags
)
}
@SuppressLint("UnspecifiedImmutableFlag")
private fun notificationCustomisation(
downloadNotification: DownloadNotification,
notificationBuilder: NotificationCompat.Builder,
context: Context
) {
if (downloadNotification.isCompleted) {
val internal = Intents.internal(CoreMainActivity::class.java).apply {
addFlags(Intent.FLAG_ACTIVITY_NEW_TASK)
putExtra(DOWNLOAD_NOTIFICATION_TITLE, downloadNotification.title)
}
val pendingIntent =
getActivity(context, 0, internal, FLAG_IMMUTABLE or FLAG_UPDATE_CURRENT)
notificationBuilder.setContentIntent(pendingIntent)
notificationBuilder.setAutoCancel(true)
}
}
@RequiresApi(VERSION_CODES.O)
private fun createChannel(channelId: String, context: Context) =
NotificationChannel(
channelId,
context.getString(string.fetch_notification_default_channel_name),
NotificationManager.IMPORTANCE_DEFAULT
).apply {
setSound(null, null)
enableVibration(false)
}
}

View File

@ -1,65 +0,0 @@
/*
* Kiwix Android
* Copyright (c) 2019 Kiwix <android.kiwix.org>
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*
*/
package org.kiwix.kiwixmobile.core.downloader.fetch
import com.tonyodev.fetch2.Fetch
import com.tonyodev.fetch2.NetworkType.ALL
import com.tonyodev.fetch2.NetworkType.WIFI_ONLY
import com.tonyodev.fetch2.Request
import org.kiwix.kiwixmobile.core.downloader.DownloadRequester
import org.kiwix.kiwixmobile.core.downloader.model.DownloadRequest
import org.kiwix.kiwixmobile.core.utils.AUTO_RETRY_MAX_ATTEMPTS
import org.kiwix.kiwixmobile.core.utils.SharedPreferenceUtil
import javax.inject.Inject
class FetchDownloadRequester @Inject constructor(
private val fetch: Fetch,
private val sharedPreferenceUtil: SharedPreferenceUtil
) : DownloadRequester {
override fun enqueue(downloadRequest: DownloadRequest): Long {
val request = downloadRequest.toFetchRequest(sharedPreferenceUtil)
fetch.enqueue(request)
return request.id.toLong()
}
override fun cancel(downloadId: Long) {
fetch.delete(downloadId.toInt())
}
override fun retryDownload(downloadId: Long) {
fetch.retry(downloadId.toInt())
}
override fun pauseResumeDownload(downloadId: Long, isPause: Boolean) {
if (isPause)
fetch.resume(downloadId.toInt())
else
fetch.pause(downloadId.toInt())
}
override fun onDownloadAdded() {
// empty function
}
}
private fun DownloadRequest.toFetchRequest(sharedPreferenceUtil: SharedPreferenceUtil) =
Request("$uri", getDestinationFile(sharedPreferenceUtil).path).apply {
networkType = if (sharedPreferenceUtil.prefWifiOnly) WIFI_ONLY else ALL
autoRetryMaxAttempts = AUTO_RETRY_MAX_ATTEMPTS
}