diff --git a/app/src/androidTest/java/org/kiwix/kiwixmobile/mimetype/MimeTypeTest.kt b/app/src/androidTest/java/org/kiwix/kiwixmobile/mimetype/MimeTypeTest.kt index 07a5a129da..2f17f0d51b 100644 --- a/app/src/androidTest/java/org/kiwix/kiwixmobile/mimetype/MimeTypeTest.kt +++ b/app/src/androidTest/java/org/kiwix/kiwixmobile/mimetype/MimeTypeTest.kt @@ -76,7 +76,7 @@ class MimeTypeTest : BaseActivityTest() { } } } - val zimSource = ZimReaderSource.ZimFile(zimFile) + val zimSource = ZimReaderSource(zimFile) val zimFileReader = ZimFileReader( zimSource, Archive(zimFile.canonicalPath), diff --git a/app/src/main/java/org/kiwix/kiwixmobile/nav/destination/library/LocalLibraryFragment.kt b/app/src/main/java/org/kiwix/kiwixmobile/nav/destination/library/LocalLibraryFragment.kt index 53c1ced024..aee78620be 100644 --- a/app/src/main/java/org/kiwix/kiwixmobile/nav/destination/library/LocalLibraryFragment.kt +++ b/app/src/main/java/org/kiwix/kiwixmobile/nav/destination/library/LocalLibraryFragment.kt @@ -73,7 +73,7 @@ import org.kiwix.kiwixmobile.core.main.MainRepositoryActions import org.kiwix.kiwixmobile.core.navigateToAppSettings import org.kiwix.kiwixmobile.core.navigateToSettings import org.kiwix.kiwixmobile.core.reader.ZimFileReader -import org.kiwix.kiwixmobile.core.reader.ZimReaderSource.ZimFile +import org.kiwix.kiwixmobile.core.reader.ZimReaderSource import org.kiwix.kiwixmobile.core.utils.LanguageUtils import org.kiwix.kiwixmobile.core.utils.SharedPreferenceUtil import org.kiwix.kiwixmobile.core.utils.SimpleRecyclerViewScrollListener @@ -396,7 +396,7 @@ class LocalLibraryFragment : BaseFragment() { // local library screen. Since our application is already aware of this opened ZIM file, // we can directly add it to the database. // See https://github.com/kiwix/kiwix-android/issues/3650 - zimReaderFactory.create(ZimFile(file)) + zimReaderFactory.create(ZimReaderSource(file)) ?.let { zimFileReader -> BookOnDisk(zimFileReader).also { mainRepositoryActions.saveBook(it) diff --git a/app/src/main/java/org/kiwix/kiwixmobile/nav/destination/reader/KiwixReaderFragment.kt b/app/src/main/java/org/kiwix/kiwixmobile/nav/destination/reader/KiwixReaderFragment.kt index ca907c231f..cfbdf65f98 100644 --- a/app/src/main/java/org/kiwix/kiwixmobile/nav/destination/reader/KiwixReaderFragment.kt +++ b/app/src/main/java/org/kiwix/kiwixmobile/nav/destination/reader/KiwixReaderFragment.kt @@ -52,9 +52,8 @@ import org.kiwix.kiwixmobile.core.main.CoreMainActivity import org.kiwix.kiwixmobile.core.main.CoreReaderFragment import org.kiwix.kiwixmobile.core.main.CoreWebViewClient import org.kiwix.kiwixmobile.core.main.ToolbarScrollingKiwixWebView +import org.kiwix.kiwixmobile.core.reader.ZimReaderSource import org.kiwix.kiwixmobile.core.reader.ZimReaderSource.Companion.fromDatabaseValue -import org.kiwix.kiwixmobile.core.reader.ZimReaderSource.ZimFile -import org.kiwix.kiwixmobile.core.reader.ZimReaderSource.ZimFileDescriptor import org.kiwix.kiwixmobile.core.utils.SharedPreferenceUtil import org.kiwix.kiwixmobile.core.utils.TAG_CURRENT_FILE import org.kiwix.kiwixmobile.core.utils.TAG_KIWIX @@ -119,7 +118,7 @@ class KiwixReaderFragment : CoreReaderFragment() { activity.toast(R.string.error_file_not_found) return } - openZimFile(ZimFile(File(filePath))) + openZimFile(ZimReaderSource(File(filePath))) } override fun loadDrawerViews() { @@ -296,9 +295,9 @@ class KiwixReaderFragment : CoreReaderFragment() { super.onNewIntent(intent, activity) intent.data?.let { when (it.scheme) { - "file" -> openZimFile(ZimFile(it.toFile())) + "file" -> openZimFile(ZimReaderSource(it.toFile())) "content" -> { - val zimReaderSource = ZimFileDescriptor(it) + val zimReaderSource = ZimReaderSource(it) if (zimReaderSource.canOpenInLibkiwix()) { zimReaderContainer?.let { zimReaderContainer -> zimReaderContainer.setZimReaderSource(zimReaderSource) @@ -311,7 +310,7 @@ class KiwixReaderFragment : CoreReaderFragment() { } } } - openZimFile(ZimFileDescriptor(it)) + openZimFile(ZimReaderSource(it)) } else { activity.toast(R.string.cannot_open_file) } diff --git a/app/src/main/java/org/kiwix/kiwixmobile/zimManager/fileselectView/effects/DeleteFiles.kt b/app/src/main/java/org/kiwix/kiwixmobile/zimManager/fileselectView/effects/DeleteFiles.kt index 47cf813752..bfa01f8066 100644 --- a/app/src/main/java/org/kiwix/kiwixmobile/zimManager/fileselectView/effects/DeleteFiles.kt +++ b/app/src/main/java/org/kiwix/kiwixmobile/zimManager/fileselectView/effects/DeleteFiles.kt @@ -27,7 +27,6 @@ import org.kiwix.kiwixmobile.core.dao.NewBookDao import org.kiwix.kiwixmobile.core.extensions.isFileExist import org.kiwix.kiwixmobile.core.extensions.toast import org.kiwix.kiwixmobile.core.reader.ZimReaderContainer -import org.kiwix.kiwixmobile.core.reader.ZimReaderSource import org.kiwix.kiwixmobile.core.utils.dialog.DialogShower import org.kiwix.kiwixmobile.core.utils.dialog.KiwixDialog.DeleteZims import org.kiwix.kiwixmobile.core.utils.files.FileUtils @@ -68,10 +67,7 @@ data class DeleteFiles(private val booksOnDiskListItems: List) : } private fun deleteSpecificZimFile(book: BookOnDisk): Boolean { - val file = when (val source = book.zimReaderSource) { - is ZimReaderSource.ZimFile -> source.file - else -> null - } + val file = book.zimReaderSource.file file?.let { @Suppress("UnreachableCode") FileUtils.deleteZimFile(it.path) diff --git a/core/src/main/java/org/kiwix/kiwixmobile/core/StorageObserver.kt b/core/src/main/java/org/kiwix/kiwixmobile/core/StorageObserver.kt index db0482aa08..04e384389c 100644 --- a/core/src/main/java/org/kiwix/kiwixmobile/core/StorageObserver.kt +++ b/core/src/main/java/org/kiwix/kiwixmobile/core/StorageObserver.kt @@ -24,7 +24,7 @@ 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.reader.ZimFileReader -import org.kiwix.kiwixmobile.core.reader.ZimReaderSource.ZimFile +import org.kiwix.kiwixmobile.core.reader.ZimReaderSource import org.kiwix.kiwixmobile.core.utils.files.FileSearch import org.kiwix.kiwixmobile.core.utils.files.ScanningProgressListener import org.kiwix.kiwixmobile.core.zim_manager.fileselect_view.adapter.BooksOnDiskListItem.BookOnDisk @@ -55,6 +55,6 @@ class StorageObserver @Inject constructor( downloads.firstOrNull { file.absolutePath.endsWith(it.fileNameFromUrl) } == null private fun convertToBookOnDisk(file: File) = - zimReaderFactory.create(ZimFile(file)) + zimReaderFactory.create(ZimReaderSource(file)) ?.let { zimFileReader -> BookOnDisk(zimFileReader).also { zimFileReader.dispose() } } } diff --git a/core/src/main/java/org/kiwix/kiwixmobile/core/dao/NewBookDao.kt b/core/src/main/java/org/kiwix/kiwixmobile/core/dao/NewBookDao.kt index 9c5120862e..89190de5a1 100644 --- a/core/src/main/java/org/kiwix/kiwixmobile/core/dao/NewBookDao.kt +++ b/core/src/main/java/org/kiwix/kiwixmobile/core/dao/NewBookDao.kt @@ -83,7 +83,7 @@ class NewBookDao @Inject constructor(private val box: Box) { books.map { BookOnDisk( book = it, - zimReaderSource = ZimReaderSource.ZimFile(it.file!!) + zimReaderSource = ZimReaderSource(it.file!!) ) } ) diff --git a/core/src/main/java/org/kiwix/kiwixmobile/core/dao/entities/BookOnDiskEntity.kt b/core/src/main/java/org/kiwix/kiwixmobile/core/dao/entities/BookOnDiskEntity.kt index 135fde874b..9c893a0064 100644 --- a/core/src/main/java/org/kiwix/kiwixmobile/core/dao/entities/BookOnDiskEntity.kt +++ b/core/src/main/java/org/kiwix/kiwixmobile/core/dao/entities/BookOnDiskEntity.kt @@ -90,5 +90,5 @@ class ZimSourceConverter : PropertyConverter { entityProperty?.toDatabase() override fun convertToEntityProperty(databaseValue: String?): ZimReaderSource = - fromDatabaseValue(databaseValue) ?: ZimReaderSource.ZimFile(File("")) + fromDatabaseValue(databaseValue) ?: ZimReaderSource(File("")) } diff --git a/core/src/main/java/org/kiwix/kiwixmobile/core/reader/ZimReaderContainer.kt b/core/src/main/java/org/kiwix/kiwixmobile/core/reader/ZimReaderContainer.kt index 2e49030a97..57b5c3ea4f 100644 --- a/core/src/main/java/org/kiwix/kiwixmobile/core/reader/ZimReaderContainer.kt +++ b/core/src/main/java/org/kiwix/kiwixmobile/core/reader/ZimReaderContainer.kt @@ -36,7 +36,9 @@ class ZimReaderContainer @Inject constructor(private val zimFileReaderFactory: F return } zimFileReader = - if (zimReaderSource?.exists() == true) zimFileReaderFactory.create(zimReaderSource) else null + if (zimReaderSource?.exists() == true && zimReaderSource.canOpenInLibkiwix()) + zimFileReaderFactory.create(zimReaderSource) + else null } fun getPageUrlFromTitle(title: String) = zimFileReader?.getPageUrlFrom(title) diff --git a/core/src/main/java/org/kiwix/kiwixmobile/core/reader/ZimReaderSource.kt b/core/src/main/java/org/kiwix/kiwixmobile/core/reader/ZimReaderSource.kt index 1c1a566f84..bb6189b917 100644 --- a/core/src/main/java/org/kiwix/kiwixmobile/core/reader/ZimReaderSource.kt +++ b/core/src/main/java/org/kiwix/kiwixmobile/core/reader/ZimReaderSource.kt @@ -31,79 +31,83 @@ import org.kiwix.kiwixmobile.core.utils.files.FileUtils.isFileDescriptorCanOpenW import org.kiwix.libzim.Archive import java.io.File -sealed class ZimReaderSource { - abstract fun exists(): Boolean - abstract fun canOpenInLibkiwix(): Boolean - abstract fun createArchive(): Archive? - abstract fun toDatabase(): String +class ZimReaderSource( + val file: File? = null, + val uri: Uri? = null, + private val assetFileDescriptor: AssetFileDescriptor? = null +) { + constructor(uri: Uri) : this( + uri = uri, + assetFileDescriptor = getAssetFileDescriptorFromUri(CoreApp.instance, uri) + ) + + constructor(file: File) : this(file = file, uri = null) companion object { fun fromDatabaseValue(databaseValue: String?) = - databaseValue?.let { - if (it.startsWith("content://")) ZimFileDescriptor(it.toUri()) - else ZimFile(File(it)) + databaseValue?.run { + if (startsWith("content://")) ZimReaderSource(toUri()) + else ZimReaderSource(File(this)) } } - override fun equals(other: Any?): Boolean { + fun exists(): Boolean { return when { - other is ZimFile && this is ZimFile -> file.canonicalPath == other.file.canonicalPath - other is ZimFileDescriptor && this is ZimFileDescriptor -> uri == other.uri + file != null -> file.isFileExist() + assetFileDescriptor != null -> + assetFileDescriptor.parcelFileDescriptor.fileDescriptor.valid() + else -> false } } - fun getUri(activity: AppCompatActivity): Uri? { - return when (this) { - is ZimFile -> { - FileProvider.getUriForFile( - activity, - activity.packageName + ".fileprovider", - file - ) - } + fun canOpenInLibkiwix(): Boolean { + return when { + file?.canReadFile() == true -> true + assetFileDescriptor?.parcelFileDescriptor?.fd + ?.let(::isFileDescriptorCanOpenWithLibkiwix) == true -> true - is ZimFileDescriptor -> uri + else -> false } } - override fun hashCode(): Int { - return when (this) { - is ZimFile -> file.hashCode() - is ZimFileDescriptor -> assetFileDescriptor.hashCode() + fun createArchive(): Archive? { + return file?.let { + Archive(it.canonicalPath) + } ?: assetFileDescriptor?.let { + Archive( + it.parcelFileDescriptor.dup().fileDescriptor, + it.startOffset, + it.length + ) } } - class ZimFile(val file: File) : ZimReaderSource() { - override fun exists() = file.isFileExist() - override fun canOpenInLibkiwix(): Boolean = file.canReadFile() + fun toDatabase(): String = file?.canonicalPath ?: uri.toString() - override fun createArchive() = Archive(file.canonicalPath) - override fun toDatabase(): String = file.canonicalPath - } - - class ZimFileDescriptor(val uri: Uri?, val assetFileDescriptor: AssetFileDescriptor?) : - ZimReaderSource() { - - constructor(uri: Uri) : this( - uri, - getAssetFileDescriptorFromUri(CoreApp.instance, uri) - ) + override fun equals(other: Any?): Boolean { + return when { + file != null && other is ZimReaderSource && other.file != null -> + file.canonicalPath == other.file.canonicalPath - override fun exists(): Boolean = - assetFileDescriptor?.parcelFileDescriptor?.fileDescriptor?.valid() == true + uri != null && other is ZimReaderSource && other.uri != null -> uri == other.uri + else -> false + } + } - override fun canOpenInLibkiwix(): Boolean = - isFileDescriptorCanOpenWithLibkiwix(assetFileDescriptor?.parcelFileDescriptor?.fd) + fun getUri(activity: AppCompatActivity): Uri? { + return when { + file != null -> { + FileProvider.getUriForFile( + activity, + "${activity.packageName}.fileprovider", + file + ) + } - override fun createArchive() = assetFileDescriptor?.let { - Archive( - assetFileDescriptor.parcelFileDescriptor.dup().fileDescriptor, - assetFileDescriptor.startOffset, - assetFileDescriptor.length - ) + else -> uri } - - override fun toDatabase(): String = uri.toString() } + + override fun hashCode(): Int = file?.hashCode() ?: assetFileDescriptor.hashCode() } diff --git a/core/src/main/java/org/kiwix/kiwixmobile/core/zim_manager/fileselect_view/adapter/BooksOnDiskListItem.kt b/core/src/main/java/org/kiwix/kiwixmobile/core/zim_manager/fileselect_view/adapter/BooksOnDiskListItem.kt index 0ca9686506..0575bec8b3 100644 --- a/core/src/main/java/org/kiwix/kiwixmobile/core/zim_manager/fileselect_view/adapter/BooksOnDiskListItem.kt +++ b/core/src/main/java/org/kiwix/kiwixmobile/core/zim_manager/fileselect_view/adapter/BooksOnDiskListItem.kt @@ -23,7 +23,6 @@ import org.kiwix.kiwixmobile.core.dao.entities.FetchDownloadEntity import org.kiwix.kiwixmobile.core.entity.LibraryNetworkEntity.Book import org.kiwix.kiwixmobile.core.reader.ZimFileReader import org.kiwix.kiwixmobile.core.reader.ZimReaderSource -import org.kiwix.kiwixmobile.core.reader.ZimReaderSource.ZimFile import org.kiwix.kiwixmobile.core.zim_manager.KiwixTag import java.io.File import java.util.Locale @@ -62,7 +61,7 @@ sealed class BooksOnDiskListItem { constructor(fetchDownloadEntity: FetchDownloadEntity) : this( book = fetchDownloadEntity.toBook(), - zimReaderSource = ZimFile(File(fetchDownloadEntity.file)) + zimReaderSource = ZimReaderSource(File(fetchDownloadEntity.file)) ) constructor(zimFileReader: ZimFileReader) : this( diff --git a/core/src/sharedTestFunctions/java/org/kiwix/sharedFunctions/TestModelFunctions.kt b/core/src/sharedTestFunctions/java/org/kiwix/sharedFunctions/TestModelFunctions.kt index c50be997ba..ae2be472c2 100644 --- a/core/src/sharedTestFunctions/java/org/kiwix/sharedFunctions/TestModelFunctions.kt +++ b/core/src/sharedTestFunctions/java/org/kiwix/sharedFunctions/TestModelFunctions.kt @@ -34,7 +34,6 @@ import org.kiwix.kiwixmobile.core.entity.MetaLinkNetworkEntity import org.kiwix.kiwixmobile.core.entity.MetaLinkNetworkEntity.FileElement import org.kiwix.kiwixmobile.core.entity.MetaLinkNetworkEntity.Pieces import org.kiwix.kiwixmobile.core.entity.MetaLinkNetworkEntity.Url -import org.kiwix.kiwixmobile.core.reader.ZimReaderSource.ZimFile import org.kiwix.kiwixmobile.core.reader.ZimReaderSource import org.kiwix.kiwixmobile.core.zim_manager.Language import org.kiwix.kiwixmobile.core.zim_manager.fileselect_view.adapter.BooksOnDiskListItem.BookOnDisk @@ -44,7 +43,7 @@ import java.util.LinkedList fun bookOnDisk( databaseId: Long = 0L, book: Book = book(), - zimReaderSource: ZimReaderSource = ZimFile(File("")) + zimReaderSource: ZimReaderSource = ZimReaderSource(File("")) ) = BookOnDisk(databaseId, book, zimReaderSource) fun downloadModel( @@ -177,7 +176,7 @@ fun recentSearchEntity( fun bookOnDiskEntity( id: Long = 0, - zimReaderSource: ZimReaderSource = ZimFile(File("")), + zimReaderSource: ZimReaderSource = ZimReaderSource(File("")), bookId: String = "", title: String = "", description: String = "", diff --git a/core/src/test/java/org/kiwix/kiwixmobile/core/StorageObserverTest.kt b/core/src/test/java/org/kiwix/kiwixmobile/core/StorageObserverTest.kt index 522086ec24..2843fc720f 100644 --- a/core/src/test/java/org/kiwix/kiwixmobile/core/StorageObserverTest.kt +++ b/core/src/test/java/org/kiwix/kiwixmobile/core/StorageObserverTest.kt @@ -113,6 +113,6 @@ class StorageObserverTest { every { downloadModel.fileNameFromUrl } returns "test" every { file.absolutePath } returns "This won't match" every { file.canonicalPath } returns "This won't match" - every { (zimReaderSource as ZimReaderSource.ZimFile).file } returns file + every { zimReaderSource.file } returns file } } diff --git a/core/src/test/java/org/kiwix/kiwixmobile/core/dao/NewBookDaoTest.kt b/core/src/test/java/org/kiwix/kiwixmobile/core/dao/NewBookDaoTest.kt index 02fb705e9c..69ae39f5da 100644 --- a/core/src/test/java/org/kiwix/kiwixmobile/core/dao/NewBookDaoTest.kt +++ b/core/src/test/java/org/kiwix/kiwixmobile/core/dao/NewBookDaoTest.kt @@ -39,7 +39,6 @@ import org.kiwix.kiwixmobile.core.dao.entities.BookOnDiskEntity import org.kiwix.kiwixmobile.core.dao.entities.BookOnDiskEntity_ import org.kiwix.kiwixmobile.core.entity.LibraryNetworkEntity import org.kiwix.kiwixmobile.core.reader.ZimReaderSource -import org.kiwix.kiwixmobile.core.reader.ZimReaderSource.ZimFile import org.kiwix.kiwixmobile.core.zim_manager.fileselect_view.adapter.BooksOnDiskListItem.BookOnDisk import org.kiwix.sharedFunctions.book import org.kiwix.sharedFunctions.bookOnDisk @@ -123,7 +122,7 @@ internal class NewBookDaoTest { every { query.find() } returns listOf( - bookOnDiskEntity(zimReaderSource = ZimFile(File("matches_nothing"))) + bookOnDiskEntity(zimReaderSource = ZimReaderSource(File("matches_nothing"))) ) slot.captured.call() verify { box.put(listOf(BookOnDiskEntity(distinctBook))) } @@ -203,7 +202,7 @@ internal class NewBookDaoTest { BookOnDiskEntity( BookOnDisk( book = book, - zimReaderSource = ZimFile(book.file!!) + zimReaderSource = ZimReaderSource(book.file!!) ) ) ) diff --git a/custom/src/main/java/org/kiwix/kiwixmobile/custom/main/CustomReaderFragment.kt b/custom/src/main/java/org/kiwix/kiwixmobile/custom/main/CustomReaderFragment.kt index 30f8d24406..b0351d899b 100644 --- a/custom/src/main/java/org/kiwix/kiwixmobile/custom/main/CustomReaderFragment.kt +++ b/custom/src/main/java/org/kiwix/kiwixmobile/custom/main/CustomReaderFragment.kt @@ -35,8 +35,7 @@ import org.kiwix.kiwixmobile.core.base.BaseActivity import org.kiwix.kiwixmobile.core.extensions.getResizedDrawable import org.kiwix.kiwixmobile.core.main.CoreReaderFragment import org.kiwix.kiwixmobile.core.main.MainMenu -import org.kiwix.kiwixmobile.core.reader.ZimReaderSource.ZimFile -import org.kiwix.kiwixmobile.core.reader.ZimReaderSource.ZimFileDescriptor +import org.kiwix.kiwixmobile.core.reader.ZimReaderSource import org.kiwix.kiwixmobile.core.utils.LanguageUtils import org.kiwix.kiwixmobile.core.utils.dialog.DialogShower import org.kiwix.kiwixmobile.core.zim_manager.fileselect_view.adapter.BooksOnDiskListItem.BookOnDisk @@ -180,13 +179,14 @@ class CustomReaderFragment : CoreReaderFragment() { onFilesFound = { when (it) { is ValidationState.HasFile -> { - it.assetFileDescriptor?.let { assetFileDescriptor -> - openZimFile(ZimFileDescriptor(null, assetFileDescriptor), true) - } ?: kotlin.run { - it.file?.let { file -> - openZimFile(ZimFile(file), true) - } - } + openZimFile( + ZimReaderSource( + file = it.file, + null, + it.assetFileDescriptor + ), + true + ) // Save book in the database to display it in `ZimHostFragment`. zimReaderContainer?.zimFileReader?.let { zimFileReader -> // Check if the file is not null. If the file is null, @@ -198,7 +198,7 @@ class CustomReaderFragment : CoreReaderFragment() { } is ValidationState.HasBothFiles -> { it.zimFile.delete() - openZimFile(ZimFile(it.obbFile), true) + openZimFile(ZimReaderSource(it.obbFile), true) } else -> {} }