mirror of
https://github.com/kiwix/kiwix-android.git
synced 2025-09-20 18:48:16 -04:00
Merge pull request #2003 from kiwix/macgills/feature/2002-pre-allocation
#2002 Stop pre allocation of downloads and instead check currently downloading books to calculate available space
This commit is contained in:
commit
45b14119c9
@ -7,12 +7,12 @@
|
||||
<ID>EmptyFunctionBlock:ZimHostActivity.kt$ZimHostActivity.<no name provided>${}</ID>
|
||||
<ID>ForbiddenComment:KiwixMainActivity.kt$KiwixMainActivity$// TODO: Show to user</ID>
|
||||
<ID>LongParameterList:ZimManageViewModel.kt$ZimManageViewModel$( booksOnFileSystem: List<BookOnDisk>, activeDownloads: List<DownloadModel>, allLanguages: List<Language>, libraryNetworkEntity: LibraryNetworkEntity, filter: String, fileSystemState: FileSystemState )</ID>
|
||||
<ID>MagicNumber:LibraryFragment.kt$LibraryFragment$1024f</ID>
|
||||
<ID>MagicNumber:LibraryListItem.kt$LibraryListItem.LibraryDownloadItem$1000L</ID>
|
||||
<ID>MagicNumber:ShareFiles.kt$ShareFiles$24</ID>
|
||||
<ID>MagicNumber:ZimManageViewModel.kt$ZimManageViewModel$5</ID>
|
||||
<ID>MagicNumber:ZimManageViewModel.kt$ZimManageViewModel$500</ID>
|
||||
<ID>MagicNumber:ZimManageViewModel.kt$ZimManageViewModel$60</ID>
|
||||
<ID>PackageNaming:AvailableSpaceCalculator.kt$package org.kiwix.kiwixmobile.zim_manager.library_view</ID>
|
||||
<ID>PackageNaming:ConnectivityBroadcastReceiver.kt$package org.kiwix.kiwixmobile.zim_manager</ID>
|
||||
<ID>PackageNaming:DefaultLanguageProvider.kt$package org.kiwix.kiwixmobile.zim_manager</ID>
|
||||
<ID>PackageNaming:DeleteFiles.kt$package org.kiwix.kiwixmobile.zim_manager.fileselect_view.effects</ID>
|
||||
@ -42,7 +42,6 @@
|
||||
<ID>PackageNaming:ZimManageViewModel.kt$package org.kiwix.kiwixmobile.zim_manager</ID>
|
||||
<ID>ReturnCount:Fat32Checker.kt$Fat32Checker$private fun canCreate4GbFile(storage: String): Boolean</ID>
|
||||
<ID>ReturnCount:LanguageActivity.kt$LanguageActivity$override fun onOptionsItemSelected(item: MenuItem): Boolean</ID>
|
||||
<ID>ReturnCount:LibraryFragment.kt$LibraryFragment$private fun onBookItemClick(item: BookItem)</ID>
|
||||
<ID>TooGenericExceptionCaught:FileWritingFileSystemChecker.kt$FileWritingFileSystemChecker$e: Exception</ID>
|
||||
<ID>TooGenericExceptionCaught:KiwixMainActivity.kt$KiwixMainActivity$e: Exception</ID>
|
||||
<ID>TooGenericExceptionThrown:ActivityExtensions.kt$throw RuntimeException( """ applicationContext is ${applicationContext::class.java.simpleName} application is ${application::class.java.simpleName} """.trimIndent() )</ID>
|
||||
|
@ -23,7 +23,6 @@ import android.os.Environment
|
||||
import org.kiwix.kiwixmobile.core.settings.CorePrefsFragment
|
||||
import org.kiwix.kiwixmobile.core.utils.SharedPreferenceUtil.PREF_LANG
|
||||
import org.kiwix.kiwixmobile.core.utils.SharedPreferenceUtil.PREF_STORAGE
|
||||
import java.io.File
|
||||
|
||||
class KiwixPrefsFragment : CorePrefsFragment() {
|
||||
override fun onCreate(savedInstanceState: Bundle?) {
|
||||
@ -37,7 +36,6 @@ class KiwixPrefsFragment : CorePrefsFragment() {
|
||||
} else {
|
||||
findPreference(PREF_STORAGE).title = sharedPreferenceUtil.getPrefStorageTitle("External")
|
||||
}
|
||||
findPreference(PREF_STORAGE).summary =
|
||||
storageCalculator.calculateAvailableSpace(File(sharedPreferenceUtil.prefStorage))
|
||||
findPreference(PREF_STORAGE).summary = storageCalculator.calculateAvailableSpace()
|
||||
}
|
||||
}
|
||||
|
@ -0,0 +1,53 @@
|
||||
/*
|
||||
* Kiwix Android
|
||||
* Copyright (c) 2020 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.zim_manager.library_view
|
||||
|
||||
import eu.mhutti1.utils.storage.Bytes
|
||||
import eu.mhutti1.utils.storage.Kb
|
||||
import io.reactivex.android.schedulers.AndroidSchedulers
|
||||
import io.reactivex.schedulers.Schedulers
|
||||
import org.kiwix.kiwixmobile.core.dao.FetchDownloadDao
|
||||
import org.kiwix.kiwixmobile.core.downloader.model.DownloadModel
|
||||
import org.kiwix.kiwixmobile.core.settings.StorageCalculator
|
||||
import org.kiwix.kiwixmobile.zim_manager.library_view.adapter.LibraryListItem
|
||||
import javax.inject.Inject
|
||||
|
||||
class AvailableSpaceCalculator @Inject constructor(
|
||||
private val downloadDao: FetchDownloadDao,
|
||||
private val storageCalculator: StorageCalculator
|
||||
) {
|
||||
fun hasAvailableSpaceFor(
|
||||
bookItem: LibraryListItem.BookItem,
|
||||
successAction: (LibraryListItem.BookItem) -> Unit,
|
||||
failureAction: (String) -> Unit
|
||||
) {
|
||||
downloadDao.allDownloads()
|
||||
.map { it.map(DownloadModel::bytesRemaining).sum() }
|
||||
.map { bytesToBeDownloaded -> storageCalculator.availableBytes() - bytesToBeDownloaded }
|
||||
.subscribeOn(Schedulers.io())
|
||||
.observeOn(AndroidSchedulers.mainThread())
|
||||
.subscribe { trueAvailableBytes ->
|
||||
if (bookItem.book.size.toLong() * Kb < trueAvailableBytes) {
|
||||
successAction.invoke(bookItem)
|
||||
} else {
|
||||
failureAction.invoke(Bytes(trueAvailableBytes).humanReadable)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
@ -42,7 +42,6 @@ import org.kiwix.kiwixmobile.core.downloader.Downloader
|
||||
import org.kiwix.kiwixmobile.core.entity.LibraryNetworkEntity.Book
|
||||
import org.kiwix.kiwixmobile.core.extensions.ActivityExtensions.viewModel
|
||||
import org.kiwix.kiwixmobile.core.extensions.snack
|
||||
import org.kiwix.kiwixmobile.core.settings.StorageCalculator
|
||||
import org.kiwix.kiwixmobile.core.utils.BookUtils
|
||||
import org.kiwix.kiwixmobile.core.utils.DialogShower
|
||||
import org.kiwix.kiwixmobile.core.utils.KiwixDialog.YesNoDialog.StopDownload
|
||||
@ -60,7 +59,6 @@ import org.kiwix.kiwixmobile.zim_manager.library_view.adapter.LibraryDelegate.Di
|
||||
import org.kiwix.kiwixmobile.zim_manager.library_view.adapter.LibraryDelegate.DownloadDelegate
|
||||
import org.kiwix.kiwixmobile.zim_manager.library_view.adapter.LibraryListItem
|
||||
import org.kiwix.kiwixmobile.zim_manager.library_view.adapter.LibraryListItem.BookItem
|
||||
import java.io.File
|
||||
import javax.inject.Inject
|
||||
|
||||
class LibraryFragment : BaseFragment() {
|
||||
@ -71,7 +69,7 @@ class LibraryFragment : BaseFragment() {
|
||||
@Inject lateinit var dialogShower: DialogShower
|
||||
@Inject lateinit var viewModelFactory: ViewModelProvider.Factory
|
||||
@Inject lateinit var bookUtils: BookUtils
|
||||
@Inject lateinit var storageCalculator: StorageCalculator
|
||||
@Inject lateinit var availableSpaceCalculator: AvailableSpaceCalculator
|
||||
|
||||
private val zimManageViewModel by lazy {
|
||||
activity!!.viewModel<ZimManageViewModel>(viewModelFactory)
|
||||
@ -87,9 +85,6 @@ class LibraryFragment : BaseFragment() {
|
||||
)
|
||||
}
|
||||
|
||||
private val spaceAvailable: Long
|
||||
get() = storageCalculator.availableBytes(File(sharedPreferenceUtil.prefStorage))
|
||||
|
||||
private val noWifiWithWifiOnlyPreferenceSet
|
||||
get() = sharedPreferenceUtil.prefWifiOnly && !NetworkUtils.isWiFi(context!!)
|
||||
|
||||
@ -192,16 +187,6 @@ class LibraryFragment : BaseFragment() {
|
||||
|
||||
private fun onBookItemClick(item: BookItem) {
|
||||
when {
|
||||
notEnoughSpaceAvailable(item) -> {
|
||||
libraryList.snack(
|
||||
getString(R.string.download_no_space) +
|
||||
"\n" + getString(R.string.space_available) + " " +
|
||||
storageCalculator.calculateAvailableSpace(File(sharedPreferenceUtil.prefStorage)),
|
||||
R.string.download_change_storage,
|
||||
::showStorageSelectDialog
|
||||
)
|
||||
return
|
||||
}
|
||||
isNotConnected -> {
|
||||
noInternetSnackbar()
|
||||
return
|
||||
@ -213,13 +198,20 @@ class LibraryFragment : BaseFragment() {
|
||||
})
|
||||
return
|
||||
}
|
||||
else -> downloadFile(item.book)
|
||||
else -> availableSpaceCalculator.hasAvailableSpaceFor(item,
|
||||
{ downloadFile(item.book) },
|
||||
{
|
||||
libraryList.snack(
|
||||
getString(R.string.download_no_space) +
|
||||
"\n" + getString(R.string.space_available) + " " +
|
||||
it,
|
||||
R.string.download_change_storage,
|
||||
::showStorageSelectDialog
|
||||
)
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
private fun notEnoughSpaceAvailable(item: BookItem) =
|
||||
spaceAvailable < item.book.size.toLong() * 1024f
|
||||
|
||||
private fun showStorageSelectDialog() = StorageSelectDialog()
|
||||
.apply {
|
||||
onSelectAction = ::storeDeviceInPreferences
|
||||
|
@ -23,6 +23,7 @@ import io.objectbox.Box
|
||||
import io.objectbox.kotlin.equal
|
||||
import io.objectbox.kotlin.query
|
||||
import io.reactivex.Flowable
|
||||
import io.reactivex.Single
|
||||
import org.kiwix.kiwixmobile.core.dao.entities.FetchDownloadEntity
|
||||
import org.kiwix.kiwixmobile.core.dao.entities.FetchDownloadEntity_
|
||||
import org.kiwix.kiwixmobile.core.downloader.DownloadRequester
|
||||
@ -43,6 +44,8 @@ class FetchDownloadDao @Inject constructor(
|
||||
.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 {
|
||||
|
@ -73,13 +73,19 @@ object DownloaderModule {
|
||||
enableLogging(BuildConfig.DEBUG)
|
||||
enableRetryOnNetworkGain(true)
|
||||
setHttpDownloader(okHttpDownloader)
|
||||
preAllocateFileOnCreation(false)
|
||||
setNotificationManager(fetchNotificationManager)
|
||||
}.build().also(Impl::setDefaultInstanceConfiguration)
|
||||
|
||||
@JvmStatic
|
||||
@Provides
|
||||
@Singleton
|
||||
fun provideOkHttpDownloader() = OkHttpDownloader(OkHttpClient.Builder().build())
|
||||
fun provideOkHttpDownloader() = OkHttpDownloader(
|
||||
OkHttpClient.Builder()
|
||||
.followRedirects(true)
|
||||
.followSslRedirects(true)
|
||||
.build()
|
||||
)
|
||||
|
||||
@JvmStatic
|
||||
@Provides
|
||||
|
@ -35,6 +35,7 @@ data class DownloadModel(
|
||||
val progress: Int,
|
||||
val book: Book
|
||||
) {
|
||||
val bytesRemaining: Long by lazy { totalSizeOfDownload - bytesDownloaded }
|
||||
val fileNameFromUrl: String by lazy { StorageUtils.getFileNameFromUrl(book.url) }
|
||||
|
||||
constructor(downloadEntity: FetchDownloadEntity) : this(
|
||||
|
@ -19,18 +19,21 @@
|
||||
package org.kiwix.kiwixmobile.core.settings
|
||||
|
||||
import eu.mhutti1.utils.storage.Bytes
|
||||
import org.kiwix.kiwixmobile.core.utils.SharedPreferenceUtil
|
||||
import java.io.File
|
||||
import javax.inject.Inject
|
||||
|
||||
class StorageCalculator @Inject constructor() {
|
||||
class StorageCalculator @Inject constructor(
|
||||
private val sharedPreferenceUtil: SharedPreferenceUtil
|
||||
) {
|
||||
|
||||
fun calculateAvailableSpace(file: File): String =
|
||||
fun calculateAvailableSpace(file: File = File(sharedPreferenceUtil.prefStorage)): String =
|
||||
Bytes(availableBytes(file)).humanReadable
|
||||
|
||||
fun calculateTotalSpace(file: File): String =
|
||||
fun calculateTotalSpace(file: File = File(sharedPreferenceUtil.prefStorage)): String =
|
||||
Bytes(totalBytes(file)).humanReadable
|
||||
|
||||
fun availableBytes(file: File) =
|
||||
fun availableBytes(file: File = File(sharedPreferenceUtil.prefStorage)) =
|
||||
if (file.exists()) file.freeSpace
|
||||
else 0L
|
||||
|
||||
|
@ -110,17 +110,24 @@ public class SharedPreferenceUtil {
|
||||
}
|
||||
|
||||
public String getPrefStorage() {
|
||||
String storage = sharedPreferences.getString(PREF_STORAGE, null);
|
||||
final String storage = sharedPreferences.getString(PREF_STORAGE, null);
|
||||
if (storage == null) {
|
||||
final File externalFilesDir =
|
||||
ContextCompat.getExternalFilesDirs(CoreApp.getInstance(), null)[0];
|
||||
storage = externalFilesDir != null ? externalFilesDir.getPath()
|
||||
: CoreApp.getInstance().getFilesDir().getPath(); // workaround for emulators
|
||||
putPrefStorage(storage);
|
||||
final String defaultStorage = defaultStorage();
|
||||
putPrefStorage(defaultStorage);
|
||||
return defaultStorage;
|
||||
} else if (!new File(storage).exists()) {
|
||||
return defaultStorage();
|
||||
}
|
||||
return storage;
|
||||
}
|
||||
|
||||
private String defaultStorage() {
|
||||
final File externalFilesDir =
|
||||
ContextCompat.getExternalFilesDirs(CoreApp.getInstance(), null)[0];
|
||||
return externalFilesDir != null ? externalFilesDir.getPath()
|
||||
: CoreApp.getInstance().getFilesDir().getPath(); // workaround for emulators
|
||||
}
|
||||
|
||||
public String getPrefStorageTitle(String defaultTitle) {
|
||||
return sharedPreferences.getString(PREF_STORAGE_TITLE, defaultTitle);
|
||||
}
|
||||
|
@ -26,7 +26,7 @@ import java.io.File
|
||||
|
||||
internal class StorageCalculatorTest {
|
||||
|
||||
private val storageCalculator = StorageCalculator()
|
||||
private val storageCalculator = StorageCalculator(mockk())
|
||||
private val file: File = mockk()
|
||||
|
||||
@Test
|
||||
|
Loading…
x
Reference in New Issue
Block a user