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 {
implementation(Libs.kotlinx_coroutines_rx3)
androidTestImplementation(Libs.leakcanary_android_instrumentation)
testImplementation(Libs.kotlinx_coroutines_test)
}

View File

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

View File

@ -244,69 +244,72 @@ class LocalLibraryFragment : BaseFragment(), CopyMoveFileHandler.FileCopyMoveCal
)
}
@Suppress("LongMethod")
override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
super.onViewCreated(view, savedInstanceState)
setUpSwipeRefreshLayout()
copyMoveFileHandler?.apply {
setFileCopyMoveCallback(this@LocalLibraryFragment)
setLifeCycleScope(lifecycleScope)
}
fragmentDestinationLibraryBinding?.zimfilelist?.run {
adapter = booksOnDiskAdapter
layoutManager = LinearLayoutManager(context, RecyclerView.VERTICAL, false)
setHasFixedSize(true)
visibility = GONE
}
zimManageViewModel.fileSelectListStates.observe(viewLifecycleOwner, Observer(::render))
.also {
coreMainActivity.navHostContainer
.setBottomMarginToFragmentContainerView(0)
lifecycleScope.launch {
setUpSwipeRefreshLayout()
copyMoveFileHandler?.apply {
setFileCopyMoveCallback(this@LocalLibraryFragment)
setLifeCycleScope(lifecycleScope)
}
fragmentDestinationLibraryBinding?.zimfilelist?.run {
adapter = booksOnDiskAdapter
layoutManager = LinearLayoutManager(context, RecyclerView.VERTICAL, false)
setHasFixedSize(true)
visibility = GONE
}
zimManageViewModel.fileSelectListStates.observe(viewLifecycleOwner, Observer(::render))
.also {
coreMainActivity.navHostContainer
.setBottomMarginToFragmentContainerView(0)
getBottomNavigationView()?.let {
setBottomMarginToSwipeRefreshLayout(it.measuredHeight)
getBottomNavigationView()?.let {
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())
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
if (savedInstanceState != null && savedInstanceState.getBoolean(WAS_IN_ACTION_MODE)) {
zimManageViewModel.fileSelectActions.offer(FileSelectActions.RestartActionMode)
}
}
if (savedInstanceState != null && savedInstanceState.getBoolean(WAS_IN_ACTION_MODE)) {
zimManageViewModel.fileSelectActions.offer(FileSelectActions.RestartActionMode)
}
fragmentDestinationLibraryBinding?.goToDownloadsButtonNoFiles?.setOnClickListener {
if (permissionDeniedLayoutShowing) {
permissionDeniedLayoutShowing = false
requireActivity().navigateToAppSettings()
} else {
offerAction(FileSelectActions.UserClickedDownloadBooksButton)
fragmentDestinationLibraryBinding?.goToDownloadsButtonNoFiles?.setOnClickListener {
if (permissionDeniedLayoutShowing) {
permissionDeniedLayoutShowing = false
requireActivity().navigateToAppSettings()
} else {
offerAction(FileSelectActions.UserClickedDownloadBooksButton)
}
}
}
setUpFilePickerButton()
setUpFilePickerButton()
fragmentDestinationLibraryBinding?.zimfilelist?.addOnScrollListener(
SimpleRecyclerViewScrollListener { _, newState ->
when (newState) {
SCROLL_DOWN -> {
setBottomMarginToSwipeRefreshLayout(0)
}
fragmentDestinationLibraryBinding?.zimfilelist?.addOnScrollListener(
SimpleRecyclerViewScrollListener { _, newState ->
when (newState) {
SCROLL_DOWN -> {
setBottomMarginToSwipeRefreshLayout(0)
}
SCROLL_UP -> {
getBottomNavigationView()?.let {
setBottomMarginToSwipeRefreshLayout(it.measuredHeight)
SCROLL_UP -> {
getBottomNavigationView()?.let {
setBottomMarginToSwipeRefreshLayout(it.measuredHeight)
}
}
}
}
}
)
showCopyMoveDialogForOpenedZimFileFromStorage()
)
showCopyMoveDialogForOpenedZimFileFromStorage()
}
}
private fun showCopyMoveDialogForOpenedZimFileFromStorage() {
@ -680,14 +683,16 @@ class LocalLibraryFragment : BaseFragment(), CopyMoveFileHandler.FileCopyMoveCal
private fun storeDeviceInPreferences(
storageDevice: StorageDevice
) {
sharedPreferenceUtil.putPrefStorage(
sharedPreferenceUtil.getPublicDirectoryPath(storageDevice.name)
)
sharedPreferenceUtil.putStoragePosition(
if (storageDevice.isInternal) INTERNAL_SELECT_POSITION
else EXTERNAL_SELECT_POSITION
)
// after selecting the storage try to copy/move the zim file.
copyMoveFileHandler?.copyMoveZIMFileInSelectedStorage(storageDevice)
lifecycleScope.launch {
sharedPreferenceUtil.putPrefStorage(
sharedPreferenceUtil.getPublicDirectoryPath(storageDevice.name)
)
sharedPreferenceUtil.putStoragePosition(
if (storageDevice.isInternal) INTERNAL_SELECT_POSITION
else EXTERNAL_SELECT_POSITION
)
// 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)
assertFalse(result)
verify { fileHandler.handleDetectingFileSystemState() }
coVerify { fileHandler.handleDetectingFileSystemState() }
}
@Test
fun validateZimFileCanCopyOrMoveShouldReturnFalseWhenCannotWrite4GbFile() = runBlocking {
fun validateZimFileCanCopyOrMoveShouldReturnFalseWhenCannotWrite4GbFile() = runTest {
every { fileHandler.isBookLessThan4GB() } returns true
every { fileHandler.showCopyMoveDialog() } just Runs
every {
@ -151,23 +151,23 @@ class CopyMoveFileHandlerTest {
val result = fileHandler.validateZimFileCanCopyOrMove(storageFile)
assertFalse(result)
verify { fileHandler.handleCannotWrite4GbFileState() }
coVerify { fileHandler.handleCannotWrite4GbFileState() }
}
@Test
fun handleDetectingFileSystemStateShouldPerformCopyMoveOperationIfBookLessThan4GB() {
fun handleDetectingFileSystemStateShouldPerformCopyMoveOperationIfBookLessThan4GB() = runTest {
fileHandler = spyk(fileHandler)
prepareFileSystemAndFileForMockk()
every { fileHandler.isBookLessThan4GB() } returns true
every { fileHandler.performCopyMoveOperationIfSufficientSpaceAvailable() } just Runs
coEvery { fileHandler.performCopyMoveOperationIfSufficientSpaceAvailable() } just Runs
fileHandler.handleDetectingFileSystemState()
verify { fileHandler.performCopyMoveOperationIfSufficientSpaceAvailable() }
coVerify { fileHandler.performCopyMoveOperationIfSufficientSpaceAvailable() }
}
@Test
fun handleDetectingFileSystemStateShouldObserveFileSystemStateIfBookGreaterThan4GB() {
fun handleDetectingFileSystemStateShouldObserveFileSystemStateIfBookGreaterThan4GB() = runTest {
fileHandler = spyk(fileHandler)
prepareFileSystemAndFileForMockk(fileSystemState = DetectingFileSystem)
every { fileHandler.isBookLessThan4GB() } returns false
@ -178,19 +178,19 @@ class CopyMoveFileHandlerTest {
}
@Test
fun handleCannotWrite4GbFileStateShouldPerformCopyMoveOperationIfBookLessThan4GB() {
fun handleCannotWrite4GbFileStateShouldPerformCopyMoveOperationIfBookLessThan4GB() = runTest {
fileHandler = spyk(fileHandler)
prepareFileSystemAndFileForMockk()
every { fileHandler.isBookLessThan4GB() } returns true
every { fileHandler.performCopyMoveOperationIfSufficientSpaceAvailable() } just Runs
coEvery { fileHandler.performCopyMoveOperationIfSufficientSpaceAvailable() } just Runs
fileHandler.handleCannotWrite4GbFileState()
verify { fileHandler.performCopyMoveOperationIfSufficientSpaceAvailable() }
coVerify { fileHandler.performCopyMoveOperationIfSufficientSpaceAvailable() }
}
@Test
fun handleCannotWrite4GbFileStateShouldCallCallbackIfBookGreaterThan4GB() {
fun handleCannotWrite4GbFileStateShouldCallCallbackIfBookGreaterThan4GB() = runTest {
fileHandler = spyk(fileHandler)
prepareFileSystemAndFileForMockk()
every { fileHandler.isBookLessThan4GB() } returns false

View File

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

View File

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