Moved free space to IO thread.

This commit is contained in:
MohitMaliFtechiz 2024-12-09 12:51:13 +05:30 committed by Kelson
parent 3e197cfcd2
commit cd73d6eb89
6 changed files with 86 additions and 87 deletions

View File

@ -106,6 +106,7 @@ androidComponents {
} }
dependencies { dependencies {
implementation(Libs.kotlinx_coroutines_rx3)
androidTestImplementation(Libs.leakcanary_android_instrumentation) androidTestImplementation(Libs.leakcanary_android_instrumentation)
testImplementation(Libs.kotlinx_coroutines_test) testImplementation(Libs.kotlinx_coroutines_test)
} }

View File

@ -208,7 +208,7 @@ class CopyMoveFileHandler @Inject constructor(
} }
} }
fun handleDetectingFileSystemState() { suspend fun handleDetectingFileSystemState() {
if (isBookLessThan4GB()) { if (isBookLessThan4GB()) {
performCopyMoveOperationIfSufficientSpaceAvailable() performCopyMoveOperationIfSufficientSpaceAvailable()
} else { } else {
@ -217,7 +217,7 @@ class CopyMoveFileHandler @Inject constructor(
} }
} }
fun handleCannotWrite4GbFileState() { suspend fun handleCannotWrite4GbFileState() {
if (isBookLessThan4GB()) { if (isBookLessThan4GB()) {
performCopyMoveOperationIfSufficientSpaceAvailable() performCopyMoveOperationIfSufficientSpaceAvailable()
} else { } else {
@ -240,14 +240,12 @@ class CopyMoveFileHandler @Inject constructor(
} }
} }
fun performCopyMoveOperationIfSufficientSpaceAvailable() { suspend fun performCopyMoveOperationIfSufficientSpaceAvailable() {
lifecycleScope?.launch { val availableSpace = storageCalculator.availableBytes(File(sharedPreferenceUtil.prefStorage))
val availableSpace = storageCalculator.availableBytes(File(sharedPreferenceUtil.prefStorage)) if (hasNotSufficientStorageSpace(availableSpace)) {
if (hasNotSufficientStorageSpace(availableSpace)) { fileCopyMoveCallback?.insufficientSpaceInStorage(availableSpace)
fileCopyMoveCallback?.insufficientSpaceInStorage(availableSpace) } else {
} else { performCopyMoveOperation()
performCopyMoveOperation()
}
} }
} }

View File

@ -244,69 +244,72 @@ class LocalLibraryFragment : BaseFragment(), CopyMoveFileHandler.FileCopyMoveCal
) )
} }
@Suppress("LongMethod")
override fun onViewCreated(view: View, savedInstanceState: Bundle?) { override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
super.onViewCreated(view, savedInstanceState) super.onViewCreated(view, savedInstanceState)
setUpSwipeRefreshLayout() lifecycleScope.launch {
copyMoveFileHandler?.apply { setUpSwipeRefreshLayout()
setFileCopyMoveCallback(this@LocalLibraryFragment) copyMoveFileHandler?.apply {
setLifeCycleScope(lifecycleScope) setFileCopyMoveCallback(this@LocalLibraryFragment)
} setLifeCycleScope(lifecycleScope)
fragmentDestinationLibraryBinding?.zimfilelist?.run { }
adapter = booksOnDiskAdapter fragmentDestinationLibraryBinding?.zimfilelist?.run {
layoutManager = LinearLayoutManager(context, RecyclerView.VERTICAL, false) adapter = booksOnDiskAdapter
setHasFixedSize(true) layoutManager = LinearLayoutManager(context, RecyclerView.VERTICAL, false)
visibility = GONE setHasFixedSize(true)
} visibility = GONE
zimManageViewModel.fileSelectListStates.observe(viewLifecycleOwner, Observer(::render)) }
.also { zimManageViewModel.fileSelectListStates.observe(viewLifecycleOwner, Observer(::render))
coreMainActivity.navHostContainer .also {
.setBottomMarginToFragmentContainerView(0) coreMainActivity.navHostContainer
.setBottomMarginToFragmentContainerView(0)
getBottomNavigationView()?.let { getBottomNavigationView()?.let {
setBottomMarginToSwipeRefreshLayout(it.measuredHeight) setBottomMarginToSwipeRefreshLayout(it.measuredHeight)
}
}
disposable.add(sideEffects())
disposable.add(fileSelectActions())
zimManageViewModel.deviceListScanningProgress.observe(viewLifecycleOwner) {
fragmentDestinationLibraryBinding?.scanningProgressView?.apply {
progress = it
// hide this progress bar when scanning is complete.
visibility = if (it == MAX_PROGRESS) GONE else VISIBLE
// enable if the previous scanning is completes.
fragmentDestinationLibraryBinding?.zimSwiperefresh?.isEnabled = it == MAX_PROGRESS
} }
} }
disposable.add(sideEffects()) if (savedInstanceState != null && savedInstanceState.getBoolean(WAS_IN_ACTION_MODE)) {
disposable.add(fileSelectActions()) zimManageViewModel.fileSelectActions.offer(FileSelectActions.RestartActionMode)
zimManageViewModel.deviceListScanningProgress.observe(viewLifecycleOwner) {
fragmentDestinationLibraryBinding?.scanningProgressView?.apply {
progress = it
// hide this progress bar when scanning is complete.
visibility = if (it == MAX_PROGRESS) GONE else VISIBLE
// enable if the previous scanning is completes.
fragmentDestinationLibraryBinding?.zimSwiperefresh?.isEnabled = it == MAX_PROGRESS
} }
}
if (savedInstanceState != null && savedInstanceState.getBoolean(WAS_IN_ACTION_MODE)) {
zimManageViewModel.fileSelectActions.offer(FileSelectActions.RestartActionMode)
}
fragmentDestinationLibraryBinding?.goToDownloadsButtonNoFiles?.setOnClickListener { fragmentDestinationLibraryBinding?.goToDownloadsButtonNoFiles?.setOnClickListener {
if (permissionDeniedLayoutShowing) { if (permissionDeniedLayoutShowing) {
permissionDeniedLayoutShowing = false permissionDeniedLayoutShowing = false
requireActivity().navigateToAppSettings() requireActivity().navigateToAppSettings()
} else { } else {
offerAction(FileSelectActions.UserClickedDownloadBooksButton) offerAction(FileSelectActions.UserClickedDownloadBooksButton)
}
} }
} setUpFilePickerButton()
setUpFilePickerButton()
fragmentDestinationLibraryBinding?.zimfilelist?.addOnScrollListener( fragmentDestinationLibraryBinding?.zimfilelist?.addOnScrollListener(
SimpleRecyclerViewScrollListener { _, newState -> SimpleRecyclerViewScrollListener { _, newState ->
when (newState) { when (newState) {
SCROLL_DOWN -> { SCROLL_DOWN -> {
setBottomMarginToSwipeRefreshLayout(0) setBottomMarginToSwipeRefreshLayout(0)
} }
SCROLL_UP -> { SCROLL_UP -> {
getBottomNavigationView()?.let { getBottomNavigationView()?.let {
setBottomMarginToSwipeRefreshLayout(it.measuredHeight) setBottomMarginToSwipeRefreshLayout(it.measuredHeight)
}
} }
} }
} }
} )
) showCopyMoveDialogForOpenedZimFileFromStorage()
showCopyMoveDialogForOpenedZimFileFromStorage() }
} }
private fun showCopyMoveDialogForOpenedZimFileFromStorage() { private fun showCopyMoveDialogForOpenedZimFileFromStorage() {
@ -680,14 +683,16 @@ class LocalLibraryFragment : BaseFragment(), CopyMoveFileHandler.FileCopyMoveCal
private fun storeDeviceInPreferences( private fun storeDeviceInPreferences(
storageDevice: StorageDevice storageDevice: StorageDevice
) { ) {
sharedPreferenceUtil.putPrefStorage( lifecycleScope.launch {
sharedPreferenceUtil.getPublicDirectoryPath(storageDevice.name) sharedPreferenceUtil.putPrefStorage(
) sharedPreferenceUtil.getPublicDirectoryPath(storageDevice.name)
sharedPreferenceUtil.putStoragePosition( )
if (storageDevice.isInternal) INTERNAL_SELECT_POSITION sharedPreferenceUtil.putStoragePosition(
else EXTERNAL_SELECT_POSITION if (storageDevice.isInternal) INTERNAL_SELECT_POSITION
) else EXTERNAL_SELECT_POSITION
// after selecting the storage try to copy/move the zim file. )
copyMoveFileHandler?.copyMoveZIMFileInSelectedStorage(storageDevice) // after selecting the storage try to copy/move the zim file.
copyMoveFileHandler?.copyMoveZIMFileInSelectedStorage(storageDevice)
}
} }
} }

View File

@ -136,11 +136,11 @@ class CopyMoveFileHandlerTest {
val result = fileHandler.validateZimFileCanCopyOrMove(storageFile) val result = fileHandler.validateZimFileCanCopyOrMove(storageFile)
assertFalse(result) assertFalse(result)
verify { fileHandler.handleDetectingFileSystemState() } coVerify { fileHandler.handleDetectingFileSystemState() }
} }
@Test @Test
fun validateZimFileCanCopyOrMoveShouldReturnFalseWhenCannotWrite4GbFile() = runBlocking { fun validateZimFileCanCopyOrMoveShouldReturnFalseWhenCannotWrite4GbFile() = runTest {
every { fileHandler.isBookLessThan4GB() } returns true every { fileHandler.isBookLessThan4GB() } returns true
every { fileHandler.showCopyMoveDialog() } just Runs every { fileHandler.showCopyMoveDialog() } just Runs
every { every {
@ -151,23 +151,23 @@ class CopyMoveFileHandlerTest {
val result = fileHandler.validateZimFileCanCopyOrMove(storageFile) val result = fileHandler.validateZimFileCanCopyOrMove(storageFile)
assertFalse(result) assertFalse(result)
verify { fileHandler.handleCannotWrite4GbFileState() } coVerify { fileHandler.handleCannotWrite4GbFileState() }
} }
@Test @Test
fun handleDetectingFileSystemStateShouldPerformCopyMoveOperationIfBookLessThan4GB() { fun handleDetectingFileSystemStateShouldPerformCopyMoveOperationIfBookLessThan4GB() = runTest {
fileHandler = spyk(fileHandler) fileHandler = spyk(fileHandler)
prepareFileSystemAndFileForMockk() prepareFileSystemAndFileForMockk()
every { fileHandler.isBookLessThan4GB() } returns true every { fileHandler.isBookLessThan4GB() } returns true
every { fileHandler.performCopyMoveOperationIfSufficientSpaceAvailable() } just Runs coEvery { fileHandler.performCopyMoveOperationIfSufficientSpaceAvailable() } just Runs
fileHandler.handleDetectingFileSystemState() fileHandler.handleDetectingFileSystemState()
verify { fileHandler.performCopyMoveOperationIfSufficientSpaceAvailable() } coVerify { fileHandler.performCopyMoveOperationIfSufficientSpaceAvailable() }
} }
@Test @Test
fun handleDetectingFileSystemStateShouldObserveFileSystemStateIfBookGreaterThan4GB() { fun handleDetectingFileSystemStateShouldObserveFileSystemStateIfBookGreaterThan4GB() = runTest {
fileHandler = spyk(fileHandler) fileHandler = spyk(fileHandler)
prepareFileSystemAndFileForMockk(fileSystemState = DetectingFileSystem) prepareFileSystemAndFileForMockk(fileSystemState = DetectingFileSystem)
every { fileHandler.isBookLessThan4GB() } returns false every { fileHandler.isBookLessThan4GB() } returns false
@ -178,19 +178,19 @@ class CopyMoveFileHandlerTest {
} }
@Test @Test
fun handleCannotWrite4GbFileStateShouldPerformCopyMoveOperationIfBookLessThan4GB() { fun handleCannotWrite4GbFileStateShouldPerformCopyMoveOperationIfBookLessThan4GB() = runTest {
fileHandler = spyk(fileHandler) fileHandler = spyk(fileHandler)
prepareFileSystemAndFileForMockk() prepareFileSystemAndFileForMockk()
every { fileHandler.isBookLessThan4GB() } returns true every { fileHandler.isBookLessThan4GB() } returns true
every { fileHandler.performCopyMoveOperationIfSufficientSpaceAvailable() } just Runs coEvery { fileHandler.performCopyMoveOperationIfSufficientSpaceAvailable() } just Runs
fileHandler.handleCannotWrite4GbFileState() fileHandler.handleCannotWrite4GbFileState()
verify { fileHandler.performCopyMoveOperationIfSufficientSpaceAvailable() } coVerify { fileHandler.performCopyMoveOperationIfSufficientSpaceAvailable() }
} }
@Test @Test
fun handleCannotWrite4GbFileStateShouldCallCallbackIfBookGreaterThan4GB() { fun handleCannotWrite4GbFileStateShouldCallCallbackIfBookGreaterThan4GB() = runTest {
fileHandler = spyk(fileHandler) fileHandler = spyk(fileHandler)
prepareFileSystemAndFileForMockk() prepareFileSystemAndFileForMockk()
every { fileHandler.isBookLessThan4GB() } returns false every { fileHandler.isBookLessThan4GB() } returns false

View File

@ -19,17 +19,12 @@
package org.kiwix.kiwixmobile.core.extensions package org.kiwix.kiwixmobile.core.extensions
import kotlinx.coroutines.Dispatchers import kotlinx.coroutines.Dispatchers
import kotlinx.coroutines.runBlocking
import kotlinx.coroutines.withContext import kotlinx.coroutines.withContext
import java.io.File import java.io.File
suspend fun File.isFileExist(): Boolean = withContext(Dispatchers.IO) { exists() } suspend fun File.isFileExist(): Boolean = withContext(Dispatchers.IO) { exists() }
fun File.freeSpace(): Long = runBlocking { suspend fun File.freeSpace(): Long = withContext(Dispatchers.IO) { freeSpace }
withContext(Dispatchers.IO) {
freeSpace
}
}
suspend fun File.totalSpace(): Long = withContext(Dispatchers.IO) { totalSpace } suspend fun File.totalSpace(): Long = withContext(Dispatchers.IO) { totalSpace }

View File

@ -28,7 +28,7 @@ import javax.inject.Inject
class SetPreferredStorageWithMostSpace @Inject constructor( class SetPreferredStorageWithMostSpace @Inject constructor(
private val storageCalculator: StorageCalculator, private val storageCalculator: StorageCalculator,
private val sharedPreferenceUtil: SharedPreferenceUtil private val sharedPreferenceUtil: SharedPreferenceUtil,
) : SideEffect<Unit> { ) : SideEffect<Unit> {
override fun invokeWith(activity: AppCompatActivity) { override fun invokeWith(activity: AppCompatActivity) {
activity.lifecycleScope.launch { activity.lifecycleScope.launch {