Using ParcelFileDescriptor instead of FileDescriptor.

* Telling android to not compress the `.zim` files in asset folder while building the apk/bundle.
This commit is contained in:
MohitMali 2023-10-31 11:55:21 +05:30 committed by Kelson
parent 99614ed88f
commit c8b98cc504
6 changed files with 34 additions and 25 deletions

View File

@ -38,6 +38,7 @@ import android.os.CountDownTimer
import android.os.Handler import android.os.Handler
import android.os.IBinder import android.os.IBinder
import android.os.Looper import android.os.Looper
import android.os.ParcelFileDescriptor
import android.provider.Settings import android.provider.Settings
import android.util.AttributeSet import android.util.AttributeSet
import android.util.Log import android.util.Log
@ -154,7 +155,6 @@ import org.kiwix.kiwixmobile.core.utils.dialog.KiwixDialog
import org.kiwix.kiwixmobile.core.utils.files.FileUtils.deleteCachedFiles import org.kiwix.kiwixmobile.core.utils.files.FileUtils.deleteCachedFiles
import org.kiwix.kiwixmobile.core.utils.files.FileUtils.readFile import org.kiwix.kiwixmobile.core.utils.files.FileUtils.readFile
import java.io.File import java.io.File
import java.io.FileDescriptor
import java.io.IOException import java.io.IOException
import java.text.SimpleDateFormat import java.text.SimpleDateFormat
import java.util.Date import java.util.Date
@ -1390,14 +1390,14 @@ abstract class CoreReaderFragment :
protected fun openZimFile( protected fun openZimFile(
file: File?, file: File?,
isCustomApp: Boolean = false, isCustomApp: Boolean = false,
fileDescriptor: FileDescriptor? = null parcelFileDescriptor: ParcelFileDescriptor? = null
) { ) {
if (hasPermission(Manifest.permission.READ_EXTERNAL_STORAGE) || isCustomApp) { if (hasPermission(Manifest.permission.READ_EXTERNAL_STORAGE) || isCustomApp) {
if (file?.isFileExist() == true) { if (file?.isFileExist() == true) {
openAndSetInContainer(file = file) openAndSetInContainer(file = file)
updateTitle() updateTitle()
} else if (fileDescriptor != null) { } else if (parcelFileDescriptor != null) {
openAndSetInContainer(fileDescriptor = fileDescriptor) openAndSetInContainer(parcelFileDescriptor = parcelFileDescriptor)
updateTitle() updateTitle()
} else { } else {
Log.w(TAG_KIWIX, "ZIM file doesn't exist at " + file?.absolutePath) Log.w(TAG_KIWIX, "ZIM file doesn't exist at " + file?.absolutePath)
@ -1427,7 +1427,10 @@ abstract class CoreReaderFragment :
) )
} }
private fun openAndSetInContainer(file: File? = null, fileDescriptor: FileDescriptor? = null) { private fun openAndSetInContainer(
file: File? = null,
parcelFileDescriptor: ParcelFileDescriptor? = null
) {
try { try {
if (isNotPreviouslyOpenZim(file?.canonicalPath)) { if (isNotPreviouslyOpenZim(file?.canonicalPath)) {
webViewList.clear() webViewList.clear()
@ -1436,8 +1439,8 @@ abstract class CoreReaderFragment :
e.printStackTrace() e.printStackTrace()
} }
zimReaderContainer?.let { zimReaderContainer -> zimReaderContainer?.let { zimReaderContainer ->
if (fileDescriptor != null) { if (parcelFileDescriptor != null) {
zimReaderContainer.setZimFileDescriptor(fileDescriptor) zimReaderContainer.setZimFileDescriptor(parcelFileDescriptor)
} else { } else {
zimReaderContainer.setZimFile(file) zimReaderContainer.setZimFile(file)
} }

View File

@ -40,7 +40,6 @@ import org.kiwix.libzim.Item
import org.kiwix.libzim.SuggestionSearch import org.kiwix.libzim.SuggestionSearch
import org.kiwix.libzim.SuggestionSearcher import org.kiwix.libzim.SuggestionSearcher
import java.io.File import java.io.File
import java.io.FileDescriptor
import java.io.FileInputStream import java.io.FileInputStream
import java.io.IOException import java.io.IOException
import java.io.InputStream import java.io.InputStream
@ -54,13 +53,14 @@ private const val TAG = "ZimFileReader"
class ZimFileReader constructor( class ZimFileReader constructor(
val zimFile: File?, val zimFile: File?,
val parcelFileDescriptor: ParcelFileDescriptor? = null,
private val jniKiwixReader: Archive, private val jniKiwixReader: Archive,
private val nightModeConfig: NightModeConfig, private val nightModeConfig: NightModeConfig,
private val searcher: SuggestionSearcher = SuggestionSearcher(jniKiwixReader) private val searcher: SuggestionSearcher = SuggestionSearcher(jniKiwixReader)
) { ) {
interface Factory { interface Factory {
fun create(file: File): ZimFileReader? fun create(file: File): ZimFileReader?
fun create(fileDescriptor: FileDescriptor): ZimFileReader? fun create(parcelFileDescriptor: ParcelFileDescriptor): ZimFileReader?
class Impl @Inject constructor(private val nightModeConfig: NightModeConfig) : class Impl @Inject constructor(private val nightModeConfig: NightModeConfig) :
Factory { Factory {
@ -79,12 +79,13 @@ class ZimFileReader constructor(
null null
} }
override fun create(fileDescriptor: FileDescriptor): ZimFileReader? = override fun create(parcelFileDescriptor: ParcelFileDescriptor): ZimFileReader? =
try { try {
ZimFileReader( ZimFileReader(
null, null,
parcelFileDescriptor,
nightModeConfig = nightModeConfig, nightModeConfig = nightModeConfig,
jniKiwixReader = Archive(fileDescriptor) jniKiwixReader = Archive(parcelFileDescriptor.fileDescriptor)
).also { ).also {
Log.e(TAG, "create: with fileDescriptor") Log.e(TAG, "create: with fileDescriptor")
} }

View File

@ -17,11 +17,11 @@
*/ */
package org.kiwix.kiwixmobile.core.reader package org.kiwix.kiwixmobile.core.reader
import android.os.ParcelFileDescriptor
import android.webkit.WebResourceResponse import android.webkit.WebResourceResponse
import org.kiwix.kiwixmobile.core.extensions.isFileExist import org.kiwix.kiwixmobile.core.extensions.isFileExist
import org.kiwix.kiwixmobile.core.reader.ZimFileReader.Factory import org.kiwix.kiwixmobile.core.reader.ZimFileReader.Factory
import java.io.File import java.io.File
import java.io.FileDescriptor
import java.net.HttpURLConnection import java.net.HttpURLConnection
import javax.inject.Inject import javax.inject.Inject
import javax.inject.Singleton import javax.inject.Singleton
@ -43,9 +43,10 @@ class ZimReaderContainer @Inject constructor(private val zimFileReaderFactory: F
else null else null
} }
fun setZimFileDescriptor(fileDescriptor: FileDescriptor) { fun setZimFileDescriptor(parcelFileDescriptor: ParcelFileDescriptor) {
zimFileReader = zimFileReader =
if (fileDescriptor.valid()) zimFileReaderFactory.create(fileDescriptor) if (parcelFileDescriptor.fileDescriptor.valid())
zimFileReaderFactory.create(parcelFileDescriptor)
else null else null
} }

View File

@ -49,6 +49,10 @@ android {
} }
} }
assetPacks += ":install_time_asset" assetPacks += ":install_time_asset"
androidResources {
// to not compress zim file in asset folder
noCompress.add("zim")
}
} }
fun ProductFlavor.createDownloadTask(file: File): Task { fun ProductFlavor.createDownloadTask(file: File): Task {

View File

@ -20,6 +20,7 @@ package org.kiwix.kiwixmobile.custom.main
import android.content.Context import android.content.Context
import android.content.pm.PackageManager import android.content.pm.PackageManager
import android.os.ParcelFileDescriptor
import android.util.Log import android.util.Log
import androidx.core.content.ContextCompat import androidx.core.content.ContextCompat
import org.kiwix.kiwixmobile.custom.BuildConfig import org.kiwix.kiwixmobile.custom.BuildConfig
@ -27,7 +28,6 @@ import org.kiwix.kiwixmobile.custom.main.ValidationState.HasBothFiles
import org.kiwix.kiwixmobile.custom.main.ValidationState.HasFile import org.kiwix.kiwixmobile.custom.main.ValidationState.HasFile
import org.kiwix.kiwixmobile.custom.main.ValidationState.HasNothing import org.kiwix.kiwixmobile.custom.main.ValidationState.HasNothing
import java.io.File import java.io.File
import java.io.FileDescriptor
import java.io.IOException import java.io.IOException
import javax.inject.Inject import javax.inject.Inject
@ -43,24 +43,24 @@ class CustomFileValidator @Inject constructor(private val context: Context) {
private fun detectInstallationState( private fun detectInstallationState(
obbFiles: List<File> = obbFiles(), obbFiles: List<File> = obbFiles(),
zimFiles: List<File> = zimFiles(), zimFiles: List<File> = zimFiles(),
assetFileDescriptor: FileDescriptor? = getFileFromPlayAssetDelivery() assetFileDescriptor: ParcelFileDescriptor? = getParcelFileDescriptorFromPlayAssetDelivery()
): ValidationState { ): ValidationState {
return when { return when {
assetFileDescriptor != null -> HasFile(null, assetFileDescriptor) assetFileDescriptor != null -> HasFile(null, assetFileDescriptor)
obbFiles.isNotEmpty() && zimFiles().isNotEmpty() -> HasBothFiles(obbFiles[0], zimFiles[0]) // obbFiles.isNotEmpty() && zimFiles().isNotEmpty() -> HasBothFiles(obbFiles[0], zimFiles[0])
obbFiles.isNotEmpty() -> HasFile(obbFiles[0]) // obbFiles.isNotEmpty() -> HasFile(obbFiles[0])
zimFiles.isNotEmpty() -> HasFile(zimFiles[0]) // zimFiles.isNotEmpty() -> HasFile(zimFiles[0])
else -> HasNothing else -> HasNothing
} }
} }
@Suppress("NestedBlockDepth", "MagicNumber") @Suppress("NestedBlockDepth", "MagicNumber")
private fun getFileFromPlayAssetDelivery(): FileDescriptor? { private fun getParcelFileDescriptorFromPlayAssetDelivery(): ParcelFileDescriptor? {
try { try {
val context = context.createPackageContext(context.packageName, 0) val context = context.createPackageContext(context.packageName, 0)
val assetManager = context.assets val assetManager = context.assets
val inputStream = assetManager.openFd(BuildConfig.PLAY_ASSET_FILE) val assetFileDescriptor = assetManager.openFd(BuildConfig.PLAY_ASSET_FILE)
return inputStream.fileDescriptor return assetFileDescriptor.parcelFileDescriptor
} catch (packageNameNotFoundException: PackageManager.NameNotFoundException) { } catch (packageNameNotFoundException: PackageManager.NameNotFoundException) {
Log.w( Log.w(
"ASSET_PACKAGE_DELIVERY", "ASSET_PACKAGE_DELIVERY",
@ -105,7 +105,7 @@ class CustomFileValidator @Inject constructor(private val context: Context) {
sealed class ValidationState { sealed class ValidationState {
data class HasBothFiles(val obbFile: File, val zimFile: File) : ValidationState() data class HasBothFiles(val obbFile: File, val zimFile: File) : ValidationState()
data class HasFile(val file: File?, val fileDescriptor: FileDescriptor? = null) : data class HasFile(val file: File?, val parcelFileDescriptor: ParcelFileDescriptor? = null) :
ValidationState() ValidationState()
object HasNothing : ValidationState() object HasNothing : ValidationState()

View File

@ -144,8 +144,8 @@ class CustomReaderFragment : CoreReaderFragment() {
onFilesFound = { onFilesFound = {
when (it) { when (it) {
is ValidationState.HasFile -> { is ValidationState.HasFile -> {
if (it.fileDescriptor != null) { if (it.parcelFileDescriptor != null) {
openZimFile(null, true, it.fileDescriptor) openZimFile(null, true, it.parcelFileDescriptor)
} else { } else {
openZimFile(it.file, true) openZimFile(it.file, true)
} }