Refactored the code to not ask permission for custom apps while starting the hotspot since we do not required any permission for starting the server in custom apps.

* Fixed: ZIM file was not showing in the Hotspot screen.
* Removed the unnecessary code and creation of demo file for custom app.
This commit is contained in:
MohitMaliFtechiz 2025-02-12 18:31:04 +05:30
parent 0485691ab0
commit f918ce016b
5 changed files with 55 additions and 42 deletions

View File

@ -26,9 +26,11 @@ import kotlinx.coroutines.CoroutineScope
import kotlinx.coroutines.Dispatchers
import kotlinx.coroutines.launch
import kotlinx.coroutines.rx3.rxSingle
import org.kiwix.kiwixmobile.core.CoreApp.Companion.instance
import org.kiwix.kiwixmobile.core.dao.entities.BookOnDiskEntity
import org.kiwix.kiwixmobile.core.dao.entities.BookOnDiskEntity_
import org.kiwix.kiwixmobile.core.entity.LibraryNetworkEntity.Book
import org.kiwix.kiwixmobile.core.extensions.ActivityExtensions.isCustomApp
import org.kiwix.kiwixmobile.core.reader.ZimReaderSource
import org.kiwix.kiwixmobile.core.zim_manager.fileselect_view.adapter.BooksOnDiskListItem.BookOnDisk
import javax.inject.Inject
@ -42,7 +44,6 @@ class NewBookDao @Inject constructor(private val box: Box<BookOnDiskEntity>) {
.flatMapSingle { bookOnDiskEntity ->
val file = bookOnDiskEntity.file
val zimReaderSource = ZimReaderSource(file)
rxSingle { zimReaderSource.canOpenInLibkiwix() }
.map { canOpen ->
if (canOpen) {
@ -72,7 +73,8 @@ class NewBookDao @Inject constructor(private val box: Box<BookOnDiskEntity>) {
}
}
.filter { (bookOnDiskEntity, exists) ->
exists && !isInTrashFolder(bookOnDiskEntity.zimReaderSource.toDatabase())
(instance.getMainActivity().isCustomApp() || exists) &&
!isInTrashFolder(bookOnDiskEntity.zimReaderSource.toDatabase())
}
.map(Pair<BookOnDiskEntity, Boolean>::first)
.toList()
@ -152,6 +154,7 @@ class NewBookDao @Inject constructor(private val box: Box<BookOnDiskEntity>) {
}
private suspend fun removeBooksThatDoNotExist(books: MutableList<BookOnDiskEntity>) {
if (instance.getMainActivity().isCustomApp()) return
delete(books.filterNot { it.zimReaderSource.exists() })
}

View File

@ -593,10 +593,6 @@ object FileUtils {
}
}
@JvmStatic
fun getDemoFilePathForCustomApp(context: Context) =
"${context.getExternalFilesDirs(null)[0]}/demo.zim"
@SuppressLint("Recycle")
@JvmStatic
fun getAssetFileDescriptorFromUri(
@ -633,6 +629,10 @@ object FileUtils {
// via the given file path before passing it to libkiwix.
// This precaution helps prevent runtime crashes.
// For more details, refer to https://github.com/kiwix/kiwix-android/pull/3636.
Log.e(
"CAN_OPEN_IN_LIBKIWIX",
"isFileDescriptorCanOpenWithLibkiwix: ${FileInputStream("dev/fd/$fdNumber")}"
)
FileInputStream("dev/fd/$fdNumber")
true
} catch (ignore: Exception) {

View File

@ -19,11 +19,15 @@
package org.kiwix.kiwixmobile.core.webserver
import android.content.Context
import android.os.Looper
import kotlinx.coroutines.CoroutineScope
import kotlinx.coroutines.Dispatchers
import kotlinx.coroutines.launch
import kotlinx.coroutines.withContext
import org.kiwix.kiwixmobile.core.utils.files.Log
import org.kiwix.kiwixmobile.core.CoreApp
import org.kiwix.kiwixmobile.core.extensions.ActivityExtensions.isCustomApp
import org.kiwix.kiwixmobile.core.reader.ZimReaderContainer
import org.kiwix.kiwixmobile.core.utils.files.FileUtils.getDemoFilePathForCustomApp
import org.kiwix.kiwixmobile.core.utils.files.Log
import org.kiwix.libkiwix.Book
import org.kiwix.libkiwix.Library
import org.kiwix.libkiwix.Server
@ -44,25 +48,24 @@ class KiwixServer @Inject constructor(
private val context: Context,
private val zimReaderContainer: ZimReaderContainer
) {
@Suppress("NestedBlockDepth")
@Suppress("NestedBlockDepth", "MagicNumber")
suspend fun createKiwixServer(selectedBooksPath: ArrayList<String>): KiwixServer =
withContext(Dispatchers.IO) {
val kiwixLibrary = Library()
selectedBooksPath.forEach { path ->
try {
val book = Book().apply {
// Determine whether to create an Archive from an asset or a file path
val archive = if (path == getDemoFilePathForCustomApp(context)) {
// For custom apps using a demo file, create an Archive with FileDescriptor
val assetFileDescriptor =
zimReaderContainer.zimReaderSource?.assetFileDescriptorList?.get(0)
val startOffset = assetFileDescriptor?.startOffset ?: 0L
val size = assetFileDescriptor?.length ?: 0L
Archive(
assetFileDescriptor?.parcelFileDescriptor?.fileDescriptor,
startOffset,
size
Log.e(
TAG,
" FD is valid = ${zimReaderContainer.zimReaderSource?.exists()} \n" +
"FD can read via the dev/fd/fdNumber = " +
"${zimReaderContainer.zimReaderSource?.canOpenInLibkiwix()}"
)
// Determine whether to create an Archive from an asset or a file path
val archive =
if (path == "null" && (context as CoreApp).getMainActivity().isCustomApp()) {
// For custom apps using create an Archive with FileDescriptor
zimReaderContainer.zimReaderSource?.createArchive()
} else {
// For regular files, create an Archive from the file path
Archive(path)
@ -79,6 +82,17 @@ class KiwixServer @Inject constructor(
)
}
}
android.os.Handler(Looper.getMainLooper()).postDelayed({
CoroutineScope(Dispatchers.IO).launch {
Log.e(
TAG,
"After 5 second FD is valid = " +
"${zimReaderContainer.zimReaderSource?.exists()} \n" +
"FD can read via the dev/fd/fdNumber =" +
" ${zimReaderContainer.zimReaderSource?.canOpenInLibkiwix()}"
)
}
}, 5000)
return@withContext KiwixServer(kiwixLibrary, Server(kiwixLibrary))
}
}

View File

@ -230,8 +230,10 @@ class ZimHostFragment : BaseFragment(), ZimHostCallbacks, ZimHostContract.View {
}
private fun handleStoragePermissionAndServer() {
// we does not require any permission for playStore variant.
if (sharedPreferenceUtil.isPlayStoreBuildWithAndroid11OrAbove()) {
// we does not require any permission for playStore variant, and custom apps.
if (sharedPreferenceUtil.isPlayStoreBuildWithAndroid11OrAbove() ||
requireActivity().isCustomApp()
) {
startStopServer()
return
}

View File

@ -20,6 +20,7 @@ package org.kiwix.kiwixmobile.custom.main
import android.app.Dialog
import android.os.Bundle
import android.util.Log
import android.view.Menu
import android.view.MenuInflater
import android.view.View
@ -36,7 +37,6 @@ import org.kiwix.kiwixmobile.core.R.dimen
import org.kiwix.kiwixmobile.core.base.BaseActivity
import org.kiwix.kiwixmobile.core.extensions.browserIntent
import org.kiwix.kiwixmobile.core.extensions.getResizedDrawable
import org.kiwix.kiwixmobile.core.extensions.isFileExist
import org.kiwix.kiwixmobile.core.main.CoreReaderFragment
import org.kiwix.kiwixmobile.core.main.MainMenu
import org.kiwix.kiwixmobile.core.main.RestoreOrigin
@ -44,12 +44,10 @@ import org.kiwix.kiwixmobile.core.page.history.adapter.WebViewHistoryItem
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.utils.files.FileUtils.getDemoFilePathForCustomApp
import org.kiwix.kiwixmobile.core.zim_manager.fileselect_view.adapter.BooksOnDiskListItem.BookOnDisk
import org.kiwix.kiwixmobile.custom.BuildConfig
import org.kiwix.kiwixmobile.custom.R
import org.kiwix.kiwixmobile.custom.customActivityComponent
import java.io.File
import java.util.Locale
import javax.inject.Inject
@ -220,19 +218,11 @@ class CustomReaderFragment : CoreReaderFragment() {
true,
shouldManageExternalLaunch
)
// 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,
// it means we have created zimFileReader with a fileDescriptor,
// so we create a demo file to save it in the database for display on the `ZimHostFragment`.
val file = it.file ?: createDemoFile()
val bookOnDisk = BookOnDisk(zimFileReader)
repositoryActions?.saveBook(bookOnDisk)
}
if (shouldManageExternalLaunch) {
// Open the previous loaded pages after ZIM file loads.
manageExternalLaunchAndRestoringViewState()
}
saveBookInDatabase()
}
is ValidationState.HasBothFiles -> {
@ -242,6 +232,7 @@ class CustomReaderFragment : CoreReaderFragment() {
// Open the previous loaded pages after ZIM file loads.
manageExternalLaunchAndRestoringViewState()
}
saveBookInDatabase()
}
else -> {}
@ -256,16 +247,19 @@ class CustomReaderFragment : CoreReaderFragment() {
)
}
private suspend fun createDemoFile() =
File(getDemoFilePathForCustomApp(requireActivity())).also {
if (!it.isFileExist()) it.createNewFile()
private fun saveBookInDatabase() {
// Save book in the database to display it in `ZimHostFragment`.
zimReaderContainer?.zimFileReader?.let { zimFileReader ->
Log.e("SELECTED_BOOKS", "saveBookInDatabase: Saving book to database")
repositoryActions?.saveBook(BookOnDisk(zimFileReader))
}
}
@Suppress("DEPRECATION")
override fun onCreateOptionsMenu(menu: Menu, inflater: MenuInflater) {
super.onCreateOptionsMenu(menu, inflater)
menu.findItem(org.kiwix.kiwixmobile.core.R.id.menu_help)?.isVisible = false
menu.findItem(org.kiwix.kiwixmobile.core.R.id.menu_host_books)?.isVisible = false
menu.findItem(org.kiwix.kiwixmobile.core.R.id.menu_host_books)?.isVisible = true
}
private fun enforcedLanguage(): Boolean {