Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Added file picker in play store variant #3636

Draft
wants to merge 9 commits into
base: main
Choose a base branch
from
Draft

Conversation

MohitMaliFtechiz
Copy link
Collaborator

Fixes #3628

MohitMaliFtechiz added 8 commits December 26, 2023 18:19
* Now we are creating only one reader for both `zimFile`, `assetFileDescriptor` and using for all the features.
…restriction to directly access the files via filePath so instead of a file now we are acquiring the fileDescriptor approach since we can directly open ZIM files via file descriptor without any special permission. Therefore, we are now starting to utilize the fileDescriptor instead of a file.
…via file picker. Since we need access of this uri to open the same file again, if user tries to open notes, history etc.
…pplication or navigate to the other fragments.

* Improved the error logging if due to some condition we are unable to open the assetFileDescriptor.
…cted via file picker since we can only take this permission for those file that we have selected via file picker.

* exist the previous book, if any open in reader screen when there is some error in opening new file in the reader screen.
…' button in the NotesFragment.

* Now, we primarily utilize the `FileDescriptor` instead of the file in conjunction with the URI for various functionalities. Consequently, we have refactored our note-opening functionality accordingly.
* If current file is same that is previously opened in the `ZimFileReader` then it will not create the reader again.
* Improved the variable naming.
@MohitMaliFtechiz MohitMaliFtechiz marked this pull request as draft December 27, 2023 13:11
Copy link

codecov bot commented Dec 27, 2023

Codecov Report

Attention: 70 lines in your changes are missing coverage. Please review.

Comparison is base (5fe3f5e) 48.68% compared to head (7c59193) 49.19%.
Report is 10 commits behind head on main.

❗ Current head 7c59193 differs from pull request most recent head 21b34e2. Consider uploading reports for the commit 21b34e2 to get more accurate results

Files Patch % Lines
...bile/nav/destination/reader/KiwixReaderFragment.kt 54.28% 9 Missing and 7 partials ⚠️
...org/kiwix/kiwixmobile/core/reader/ZimFileReader.kt 44.44% 11 Missing and 4 partials ⚠️
...le/nav/destination/library/LocalLibraryFragment.kt 8.33% 11 Missing ⚠️
...page/notes/viewmodel/effects/ShowOpenNoteDialog.kt 0.00% 8 Missing ⚠️
.../kiwix/kiwixmobile/core/main/CoreReaderFragment.kt 41.66% 4 Missing and 3 partials ⚠️
...rg/kiwix/kiwixmobile/core/utils/files/FileUtils.kt 37.50% 4 Missing and 1 partial ⚠️
...iwix/kiwixmobile/core/reader/ZimReaderContainer.kt 80.95% 2 Missing and 2 partials ⚠️
...e/zimManager/fileselectView/effects/DeleteFiles.kt 0.00% 1 Missing ⚠️
...xmobile/core/page/bookmark/adapter/BookmarkItem.kt 0.00% 1 Missing ⚠️
...obile/core/page/history/adapter/HistoryListItem.kt 0.00% 0 Missing and 1 partial ⚠️
... and 1 more
Additional details and impacted files
@@             Coverage Diff              @@
##               main    #3636      +/-   ##
============================================
+ Coverage     48.68%   49.19%   +0.51%     
- Complexity     1090     1102      +12     
============================================
  Files           285      285              
  Lines         10564    10598      +34     
  Branches       1415     1411       -4     
============================================
+ Hits           5143     5214      +71     
+ Misses         4580     4545      -35     
+ Partials        841      839       -2     

☔ View full report in Codecov by Sentry.
📢 Have feedback on the report? Share it here.

@MohitMaliFtechiz
Copy link
Collaborator Author

  • The file descriptor is working with SAF(Storage access framework) on the armeabi-v7a device (we only have one device of this architecture, there is no emulator present for this architecture on Android 11 and above) but it is not working with other architectures. On the other architectures, libkiwix gives the permission denied error.
    However, I have checked the permission of fileDescriptor on both devices and it is the same for both. The file descriptor has read access and it is working fine in armeabi-v7a but on other devices, it gives the error. Other architecture are arm64-v8a , x86, and x86_64 on these architectures it is not working.
  • We already know that we can only access the Uri on Android 11 and above via SAF. Also if we try to select the folder then it will return the URI of the file in that folder. We can not make the file object on that since Android does not allow us to do it, We can get the inputStream but here in our case, this will not work, one other approach is to use the fileDescriptor which we are using in this PR, unfortunately, libkiwix does not allow us to read with that fileDescriptor.
  • The fileDescriptor's permission is the same for every architecture, and the fileDescriptor is valid before passing it to the libkiwix, However, when we are passing the file descriptor to libkiwix on armeabi-v7a device it is working, but for other architecture, it is showing permission denied error. Therefore, there might be an issue with the validation of file descriptors in other architecture's .so file. I am not sure about it but it seems this is the possible reason.
  • Apart from this, when I gave the MANAGE_EXTERNAL_STORAGE permission then it started to read the file via fileDescriptor which is obvious because it is working in the non-playstore variant with this permission. We take this permission then our app has all the access related to the storage.
  • Here we need to know what are the parameters of libkiwix that are validating the fileDescriptor. And is there any difference in .so files because it is working on armeabi-v7a.

@mgautierfr Can you please help me out in this? What are the parameters you are using for validating the fileDescriptor?

@kelson42
Copy link
Collaborator

kelson42 commented Jan 1, 2024

@MohitMaliDeveloper Please put a link to the exact part of the code generating the error. Put proper debug code aroujnd this to prove the file is readable and share both log traces (one working an one failing).

@MohitMaliFtechiz
Copy link
Collaborator Author

MohitMaliFtechiz commented Jan 1, 2024

The error is happening inside the libkiwix when we are creating an Archive object with fileDescriptor.

With armeabi-v7a device everything is normal.

PERMISSION              org.kiwix.kiwixmobile                E  getAssetFileDescriptorFromUri: can Read selected uri =  true
                                                                                                     can right selected uri = true
PERMISSION              org.kiwix.kiwixmobile                E  getAssetFileDescriptorFromUri: check file descriptor permission is fileDescriptor readable = true

StrictMode policy violation: android.os.strictmode.NonSdkApiUsedViolation: Ljava/io/FileDescriptor;->descriptor:I
                                                                                                    	at android.os.StrictMode.lambda$static$1(StrictMode.java:420)
                                                                                                    	at android.os.StrictMode$$ExternalSyntheticLambda3.accept(Unknown Source:2)
                                                                                                    	at org.kiwix.libzim.Archive.setNativeArchiveEmbedded(Native Method)
                                                                                                    	at org.kiwix.libzim.Archive.<init>(Archive.java:44)
                                                                                                    	at org.kiwix.kiwixmobile.core.reader.ZimFileReader$Factory$Impl.createArchiveWithAssetFileDescriptor(ZimFileReader.kt:121)
                                                                                                    	at org.kiwix.kiwixmobile.core.reader.ZimFileReader$Factory$Impl.create(ZimFileReader.kt:82)
                                                                                                    	at org.kiwix.kiwixmobile.core.reader.ZimReaderContainer.setZimFileOrFileDescriptor(ZimReaderContainer.kt:45)
                                                                                                    	at org.kiwix.kiwixmobile.core.main.CoreReaderFragment.openAndSetInContainer(CoreReaderFragment.kt:1531)
                                                                                                    	at org.kiwix.kiwixmobile.core.main.CoreReaderFragment.openZimFile(CoreReaderFragment.kt:1486)
                                                                                                    	at org.kiwix.kiwixmobile.core.main.CoreReaderFragment.openZimFile$default(CoreReaderFragment.kt:1478)
                                                                                                    	at org.kiwix.kiwixmobile.nav.destination.reader.KiwixReaderFragment.restoreViewStateOnValidJSON(KiwixReaderFragment.kt:239)
                                                                                                    	at org.kiwix.kiwixmobile.core.main.CoreReaderFragment.manageExternalLaunchAndRestoringViewState(CoreReaderFragment.kt:2138)
                                                                                                    	at org.kiwix.kiwixmobile.nav.destination.reader.KiwixReaderFragment.openPageInBookFromNavigationArguments(KiwixReaderFragment.kt:101)
                                                                                                    	at org.kiwix.kiwixmobile.nav.destination.reader.KiwixReaderFragment.onViewCreated(KiwixReaderFragment.kt:80)
                                                                                                    	at androidx.fragment.app.Fragment.performViewCreated(Fragment.java:3128)
                                                                                                    	at androidx.fragment.app.FragmentStateManager.createView(FragmentStateManager.java:552)
                                                                                                    	at androidx.fragment.app.FragmentStateManager.moveToExpectedState(FragmentStateManager.java:261)
                                                                                                    	at androidx.fragment.app.FragmentStore.moveToExpectedState(FragmentStore.java:113)
                                                                                                    	at androidx.fragment.app.FragmentManager.moveToState(FragmentManager.java:1433)
                                                                                                    	at androidx.fragment.app.FragmentManager.dispatchStateChange(FragmentManager.java:2977)
                                                                                                    	at androidx.fragment.app.FragmentManager.dispatchViewCreated(FragmentManager.java:2888)
                                                                                                    	at androidx.fragment.app.Fragment.performViewCreated(Fragment.java:3129)
                                                                                                    	at androidx.fragment.app.FragmentStateManager.createView(FragmentStateManager.java:552)
                                                                                                    	at androidx.fragment.app.FragmentStateManager.moveToExpectedState(FragmentStateManager.java:261)
                                                                                                    	at androidx.fragment.app.FragmentStore.moveToExpectedState(FragmentStore.java:113)
                                                                                                    	at androidx.fragment.app.FragmentManager.moveToState(FragmentManager.java:1433)
                                                                                                    	at androidx.fragment.app.FragmentManager.dispatchStateChange(FragmentManager.java:2977)
                                                                                                    	at androidx.fragment.app.FragmentManager.dispatchActivityCreated(FragmentManager.java:2895)
                                                                                                    	at androidx.fragment.app.FragmentController.dispatchActivityCreated(FragmentController.java:263)
                                                                                                    	at androidx.fragment.app.FragmentActivity.onStart(FragmentActivity.java:351)
                                                                                                    	at androidx.appcompat.app.AppCompatActivity.onStart(AppCompatActivity.java:210)
                                                                                                    	at org.kiwix.kiwixmobile.core.main.CoreMainActivity.onStart(CoreMainActivity.kt:117)
                                                                                                    	at org.kiwix.kiwixmobile.main.KiwixMainActivity.onStart(KiwixMainActivity.kt:141)
                                                                                                    	at android.app.Instrumentation.callActivityOnStart(Instrumentation.java:1455)
                                                                                                    	at android.app.Activity.performStart(Activity.java:8315)
                                                                                                    	at android.app.ActivityThread.handleStartActivity(ActivityThread.java:4136)
                                                                                                    	at android.app.servertransaction.TransactionExecutor.performLifecycleSequence(TransactionExecutor.java:221)
                                                                                                    	at android.app.servertransaction.TransactionExecutor.cycleToPath(TransactionExecutor.java:201)
                                                                                                    	at android.app.servertransaction.TransactionExecutor.executeLifecycleState(TransactionExecutor.java:173)
                                                                                                    	at android.app.servertransaction.TransactionExecutor.execute(TransactionExecutor.java:97)
                                                                                                    	at android.app.ActivityThread$H.handleMessage(ActivityThread.java:2443)
                                                                                                    	at android.os.Handler.dispatchMessage(Handler.java:106)
                                                                                                    	at android.os.Looper.loopOnce(Looper.java:226)
                                                                                                    	at android.os.Looper.loop(Looper.java:313)
2024-01-01 16:45:47.124 27597-27597 StrictMode              org.kiwix.kiwixmobile                D  	at android.app.ActivityThread.main(ActivityThread.java:8751)
                                                                                                    	at java.lang.reflect.Method.invoke(Native Method)
                                                                                                    	at com.android.internal.os.RuntimeInit$MethodAndArgsCaller.run(RuntimeInit.java:571)
                                                                                                    	at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:1135)

kiwix                   org.kiwix.kiwixmobile                E  Attempting to create reader with fd: 235
ZimFileReader           org.kiwix.kiwixmobile                E  created: with assetFileDescriptor {AssetFileDescriptor: {ParcelFileDescriptor: java.io.FileDescriptor@320c6bd} start=0 len=-1}}

With arm64 device it giving permission denied error with the same permissions.

PERMISSION              org.kiwix.kiwixmobile                E  getAssetFileDescriptorFromUri: can Read selected uri =  true
                                                                                                     can right selected uri = true
PERMISSION              org.kiwix.kiwixmobile                E  getAssetFileDescriptorFromUri: check file descriptor permission is fileDescriptor readable = true
2024-01-01 16:51:52.446  8729-8729  wix.kiwixmobile         org.kiwix.kiwixmobile                W  Accessing hidden field Ljava/io/FileDescriptor;->descriptor:I (unsupported, JNI, allowed)
2024-01-01 16:51:52.471  8729-8729  StrictMode              org.kiwix.kiwixmobile                D  StrictMode policy violation: android.os.strictmode.NonSdkApiUsedViolation: Ljava/io/FileDescriptor;->descriptor:I
                                                                                                    	at android.os.StrictMode.lambda$static$1(StrictMode.java:430)
                                                                                                    	at android.os.StrictMode$$ExternalSyntheticLambda2.accept(Unknown Source:2)
                                                                                                    	at org.kiwix.libzim.Archive.setNativeArchiveEmbedded(Native Method)
                                                                                                    	at org.kiwix.libzim.Archive.<init>(Archive.java:44)
                                                                                                    	at org.kiwix.kiwixmobile.core.reader.ZimFileReader$Factory$Impl.createArchiveWithAssetFileDescriptor(ZimFileReader.kt:121)
                                                                                                    	at org.kiwix.kiwixmobile.core.reader.ZimFileReader$Factory$Impl.create(ZimFileReader.kt:82)
                                                                                                    	at org.kiwix.kiwixmobile.core.reader.ZimReaderContainer.setZimFileOrFileDescriptor(ZimReaderContainer.kt:45)
                                                                                                    	at org.kiwix.kiwixmobile.core.main.CoreReaderFragment.openAndSetInContainer(CoreReaderFragment.kt:1531)
                                                                                                    	at org.kiwix.kiwixmobile.core.main.CoreReaderFragment.openZimFile(CoreReaderFragment.kt:1486)
                                                                                                    	at org.kiwix.kiwixmobile.core.main.CoreReaderFragment.openZimFile$default(CoreReaderFragment.kt:1478)
                                                                                                    	at org.kiwix.kiwixmobile.nav.destination.reader.KiwixReaderFragment.tryOpeningZimFile(KiwixReaderFragment.kt:112)
                                                                                                    	at org.kiwix.kiwixmobile.nav.destination.reader.KiwixReaderFragment.openPageInBookFromNavigationArguments(KiwixReaderFragment.kt:99)
                                                                                                    	at org.kiwix.kiwixmobile.nav.destination.reader.KiwixReaderFragment.onViewCreated(KiwixReaderFragment.kt:80)
                                                                                                    	at androidx.fragment.app.Fragment.performViewCreated(Fragment.java:3128)
                                                                                                    	at androidx.fragment.app.FragmentStateManager.createView(FragmentStateManager.java:552)
                                                                                                    	at androidx.fragment.app.FragmentStateManager.moveToExpectedState(FragmentStateManager.java:261)
                                                                                                    	at androidx.fragment.app.FragmentManager.executeOpsTogether(FragmentManager.java:1899)
                                                                                                    	at androidx.fragment.app.FragmentManager.removeRedundantOperationsAndExecute(FragmentManager.java:1823)
                                                                                                    	at androidx.fragment.app.FragmentManager.execPendingActions(FragmentManager.java:1760)
                                                                                                    	at androidx.fragment.app.Fragment.performResume(Fragment.java:3177)
                                                                                                    	at androidx.fragment.app.FragmentStateManager.resume(FragmentStateManager.java:606)
                                                                                                    	at androidx.fragment.app.FragmentStateManager.moveToExpectedState(FragmentStateManager.java:285)
                                                                                                    	at androidx.fragment.app.FragmentStore.moveToExpectedState(FragmentStore.java:113)
                                                                                                    	at androidx.fragment.app.FragmentManager.moveToState(FragmentManager.java:1433)
                                                                                                    	at androidx.fragment.app.FragmentManager.dispatchStateChange(FragmentManager.java:2977)
                                                                                                    	at androidx.fragment.app.FragmentManager.dispatchResume(FragmentManager.java:2909)
                                                                                                    	at androidx.fragment.app.FragmentController.dispatchResume(FragmentController.java:285)
                                                                                                    	at androidx.fragment.app.FragmentActivity.onResumeFragments(FragmentActivity.java:334)
                                                                                                    	at androidx.fragment.app.FragmentActivity.onPostResume(FragmentActivity.java:323)
                                                                                                    	at androidx.appcompat.app.AppCompatActivity.onPostResume(AppCompatActivity.java:204)
                                                                                                    	at android.app.Activity.performResume(Activity.java:8796)
                                                                                                    	at android.app.ActivityThread.performResumeActivity(ActivityThread.java:4972)
                                                                                                    	at android.app.ActivityThread.handleResumeActivity(ActivityThread.java:5015)
                                                                                                    	at android.app.servertransaction.ResumeActivityItem.execute(ResumeActivityItem.java:57)
                                                                                                    	at android.app.servertransaction.ActivityTransactionItem.execute(ActivityTransactionItem.java:45)
                                                                                                    	at android.app.servertransaction.TransactionExecutor.executeLifecycleState(TransactionExecutor.java:180)
                                                                                                    	at android.app.servertransaction.TransactionExecutor.execute(TransactionExecutor.java:98)
                                                                                                    	at android.app.ActivityThread$H.handleMessage(ActivityThread.java:2448)
                                                                                                    	at android.os.Handler.dispatchMessage(Handler.java:106)
                                                                                                    	at android.os.Looper.loopOnce(Looper.java:205)
                                                                                                    	at android.os.Looper.loop(Looper.java:294)
                                                                                                    	at android.app.ActivityThread.main(ActivityThread.java:8194)
                                                                                                    	at java.lang.reflect.Method.invoke(Native Method)
                                                                                                    	at com.android.internal.os.RuntimeInit$MethodAndArgsCaller.run(RuntimeInit.java:552)
                                                                                                    	at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:971)
2024-01-01 16:51:52.471  8729-8729  kiwix                   org.kiwix.kiwixmobile                E  Attempting to create reader with fd: 114
2024-01-01 16:51:52.517  8729-8729  kiwix                   org.kiwix.kiwixmobile                E  Error opening ZIM file
2024-01-01 16:51:52.517  8729-8729  kiwix                   org.kiwix.kiwixmobile                E  Error opening file: /dev/fd/114: Permission denied
2024-01-01 16:51:52.886  8729-8729  libc                    org.kiwix.kiwixmobile                A  Fatal signal 11 (SIGSEGV), code 1 (SEGV_MAPERR), fault addr 0x0 in tid 8729 (wix.kiwixmobile), pid 8729 (wix.kiwixmobile)
---------------------------- PROCESS STARTED (9128) for package org.kiwix.kiwixmobile ----------------------------
2024-01-01 16:51:53.495  9126-9126  DEBUG                   crash_dump64                         A  Cmdline: org.kiwix.kiwixmobile
2024-01-01 16:51:53.495  9126-9126  DEBUG                   crash_dump64                         A  pid: 8729, tid: 8729, name: wix.kiwixmobile  >>> org.kiwix.kiwixmobile <<<
2024-01-01 16:51:53.495  9126-9126  DEBUG                   crash_dump64                         A        #00 pc 0000000000025464  /data/app/~~4Y9TsGqSS5d1rQF16d9IRw==/org.kiwix.kiwixmobile-uCGCV91Em8CgHXNtdh48sQ==/base.apk!libzim_wrapper.so (offset 0x1b45000) (Java_org_kiwix_libzim_SuggestionSearcher_setNativeSearcher+112) (BuildId: 6c0d6ee977af86c7d817e067ec4176543043faa4)
2024-01-01 16:51:53.495  9126-9126  DEBUG                   crash_dump64                         A        #06 pc 0000000000337610  [anon:dalvik-classes29.dex extracted in memory from /data/app/~~4Y9TsGqSS5d1rQF16d9IRw==/org.kiwix.kiwixmobile-uCGCV91Em8CgHXNtdh48sQ==/base.apk!classes29.dex] (org.kiwix.libzim.SuggestionSearcher.<init>+0)
2024-01-01 16:51:53.495  9126-9126  DEBUG                   crash_dump64                         A        #11 pc 0000000000008a78  [anon:dalvik-classes13.dex extracted in memory from /data/app/~~4Y9TsGqSS5d1rQF16d9IRw==/org.kiwix.kiwixmobile-uCGCV91Em8CgHXNtdh48sQ==/base.apk!classes13.dex] (org.kiwix.kiwixmobile.core.reader.ZimFileReader.<init>+0)
2024-01-01 16:51:53.495  9126-9126  DEBUG                   crash_dump64                         A        #17 pc 0000000000006de8  [anon:dalvik-classes13.dex extracted in memory from /data/app/~~4Y9TsGqSS5d1rQF16d9IRw==/org.kiwix.kiwixmobile-uCGCV91Em8CgHXNtdh48sQ==/base.apk!classes13.dex] (org.kiwix.kiwixmobile.core.reader.ZimFileReader$Factory$Impl.createArchiveWithAssetFileDescriptor+0)
2024-01-01 16:51:53.495  9126-9126  DEBUG                   crash_dump64                         A        #22 pc 0000000000006d48  [anon:dalvik-classes13.dex extracted in memory from /data/app/~~4Y9TsGqSS5d1rQF16d9IRw==/org.kiwix.kiwixmobile-uCGCV91Em8CgHXNtdh48sQ==/base.apk!classes13.dex] (org.kiwix.kiwixmobile.core.reader.ZimFileReader$Factory$Impl.create+0)
2024-01-01 16:51:53.495  9126-9126  DEBUG                   crash_dump64                         A        #27 pc 00000000000099cc  [anon:dalvik-classes13.dex extracted in memory from /data/app/~~4Y9TsGqSS5d1rQF16d9IRw==/org.kiwix.kiwixmobile-uCGCV91Em8CgHXNtdh48sQ==/base.apk!classes13.dex] (org.kiwix.kiwixmobile.core.reader.ZimReaderContainer.setZimFileOrFileDescriptor+0)
2024-01-01 16:51:53.495  9126-9126  DEBUG                   crash_dump64                         A        #32 pc 000000000001ad7c  [anon:dalvik-classes5.dex extracted in memory from /data/app/~~4Y9TsGqSS5d1rQF16d9IRw==/org.kiwix.kiwixmobile-uCGCV91Em8CgHXNtdh48sQ==/base.apk!classes5.dex] (org.kiwix.kiwixmobile.core.main.CoreReaderFragment.openAndSetInContainer+0)
2024-01-01 16:51:53.495  9126-9126  DEBUG                   crash_dump64                         A        #37 pc 000000000001b664  [anon:dalvik-classes5.dex extracted in memory from /data/app/~~4Y9TsGqSS5d1rQF16d9IRw==/org.kiwix.kiwixmobile-uCGCV91Em8CgHXNtdh48sQ==/base.apk!classes5.dex] (org.kiwix.kiwixmobile.core.main.CoreReaderFragment.openZimFile+0)
2024-01-01 16:51:53.495  9126-9126  DEBUG                   crash_dump64                         A        #42 pc 000000000001b5c8  [anon:dalvik-classes5.dex extracted in memory from /data/app/~~4Y9TsGqSS5d1rQF16d9IRw==/org.kiwix.kiwixmobile-uCGCV91Em8CgHXNtdh48sQ==/base.apk!classes5.dex] (org.kiwix.kiwixmobile.core.main.CoreReaderFragment.openZimFile$default+0)
2024-01-01 16:51:53.495  9126-9126  DEBUG                   crash_dump64                         A        #48 pc 0000000000006f90  [anon:dalvik-classes28.dex extracted in memory from /data/app/~~4Y9TsGqSS5d1rQF16d9IRw==/org.kiwix.kiwixmobile-uCGCV91Em8CgHXNtdh48sQ==/base.apk!classes28.dex] (org.kiwix.kiwixmobile.nav.destination.reader.KiwixReaderFragment.tryOpeningZimFile+0)
2024-01-01 16:51:53.496  9126-9126  DEBUG                   crash_dump64                         A        #53 pc 0000000000006a28  [anon:dalvik-classes28.dex extracted in memory from /data/app/~~4Y9TsGqSS5d1rQF16d9IRw==/org.kiwix.kiwixmobile-uCGCV91Em8CgHXNtdh48sQ==/base.apk!classes28.dex] (org.kiwix.kiwixmobile.nav.destination.reader.KiwixReaderFragment.openPageInBookFromNavigationArguments+0)
2024-01-01 16:51:53.496  9126-9126  DEBUG                   crash_dump64                         A        #58 pc 000000000000684c  [anon:dalvik-classes28.dex extracted in memory from /data/app/~~4Y9TsGqSS5d1rQF16d9IRw==/org.kiwix.kiwixmobile-uCGCV91Em8CgHXNtdh48sQ==/base.apk!classes28.dex] (org.kiwix.kiwixmobile.nav.destination.reader.KiwixReaderFragment.onViewCreated+0)
2024-01-01 16:51:53.496  9126-9126  DEBUG                   crash_dump64                         A        #63 pc 000000000033ffa0  [anon:dalvik-classes.dex extracted in memory from /data/app/~~4Y9TsGqSS5d1rQF16d9IRw==/org.kiwix.kiwixmobile-uCGCV91Em8CgHXNtdh48sQ==/base.apk] (androidx.fragment.app.Fragment.performViewCreated+0)
2024-01-01 16:51:53.496  9126-9126  DEBUG                   crash_dump64                         A        #68 pc 000000000033205c  [anon:dalvik-classes.dex extracted in memory from /data/app/~~4Y9TsGqSS5d1rQF16d9IRw==/org.kiwix.kiwixmobile-uCGCV91Em8CgHXNtdh48sQ==/base.apk] (androidx.fragment.app.FragmentStateManager.createView+0)
2024-01-01 16:51:53.496  9126-9126  DEBUG                   crash_dump64                         A        #73 pc 0000000000332de4  [anon:dalvik-classes.dex extracted in memory from /data/app/~~4Y9TsGqSS5d1rQF16d9IRw==/org.kiwix.kiwixmobile-uCGCV91Em8CgHXNtdh48sQ==/base.apk] (androidx.fragment.app.FragmentStateManager.moveToExpectedState+0)
2024-01-01 16:51:53.496  9126-9126  DEBUG                   crash_dump64                         A        #79 pc 000000000032e32c  [anon:dalvik-classes.dex extracted in memory from /data/app/~~4Y9TsGqSS5d1rQF16d9IRw==/org.kiwix.kiwixmobile-uCGCV91Em8CgHXNtdh48sQ==/base.apk] (androidx.fragment.app.FragmentManager.executeOpsTogether+0)
2024-01-01 16:51:53.496  9126-9126  DEBUG                   crash_dump64                         A        #84 pc 000000000032f59c  [anon:dalvik-classes.dex extracted in memory from /data/app/~~4Y9TsGqSS5d1rQF16d9IRw==/org.kiwix.kiwixmobile-uCGCV91Em8CgHXNtdh48sQ==/base.apk] (androidx.fragment.app.FragmentManager.removeRedundantOperationsAndExecute+0)
2024-01-01 16:51:53.496  9126-9126  DEBUG                   crash_dump64                         A        #89 pc 000000000032a7cc  [anon:dalvik-classes.dex extracted in memory from /data/app/~~4Y9TsGqSS5d1rQF16d9IRw==/org.kiwix.kiwixmobile-uCGCV91Em8CgHXNtdh48sQ==/base.apk] (androidx.fragment.app.FragmentManager.execPendingActions+0)
2024-01-01 16:51:53.496  9126-9126  DEBUG                   crash_dump64                         A        #94 pc 000000000033fc5c  [anon:dalvik-classes.dex extracted in memory from /data/app/~~4Y9TsGqSS5d1rQF16d9IRw==/org.kiwix.kiwixmobile-uCGCV91Em8CgHXNtdh48sQ==/base.apk] (androidx.fragment.app.Fragment.performResume+0)
2024-01-01 16:51:53.496  9126-9126  DEBUG                   crash_dump64                         A        #99 pc 0000000000333778  [anon:dalvik-classes.dex extracted in memory from /data/app/~~4Y9TsGqSS5d1rQF16d9IRw==/org.kiwix.kiwixmobile-uCGCV91Em8CgHXNtdh48sQ==/base.apk] (androidx.fragment.app.FragmentStateManager.resume+0)
2024-01-01 16:51:53.496  9126-9126  DEBUG                   crash_dump64                         A        #104 pc 0000000000332de4  [anon:dalvik-classes.dex extracted in memory from /data/app/~~4Y9TsGqSS5d1rQF16d9IRw==/org.kiwix.kiwixmobile-uCGCV91Em8CgHXNtdh48sQ==/base.apk] (androidx.fragment.app.FragmentStateManager.moveToExpectedState+0)
2024-01-01 16:51:53.496  9126-9126  DEBUG                   crash_dump64                         A        #109 pc 0000000000335f34  [anon:dalvik-classes.dex extracted in memory from /data/app/~~4Y9TsGqSS5d1rQF16d9IRw==/org.kiwix.kiwixmobile-uCGCV91Em8CgHXNtdh48sQ==/base.apk] (androidx.fragment.app.FragmentStore.moveToExpectedState+0)
2024-01-01 16:51:53.496  9126-9126  DEBUG                   crash_dump64                         A        #114 pc 000000000032ef00  [anon:dalvik-classes.dex extracted in memory from /data/app/~~4Y9TsGqSS5d1rQF16d9IRw==/org.kiwix.kiwixmobile-uCGCV91Em8CgHXNtdh48sQ==/base.apk] (androidx.fragment.app.FragmentManager.moveToState+0)
2024-01-01 16:51:53.496  9126-9126  DEBUG                   crash_dump64                         A        #119 pc 000000000032d7e0  [anon:dalvik-classes.dex extracted in memory from /data/app/~~4Y9TsGqSS5d1rQF16d9IRw==/org.kiwix.kiwixmobile-uCGCV91Em8CgHXNtdh48sQ==/base.apk] (androidx.fragment.app.FragmentManager.dispatchStateChange+0)
2024-01-01 16:51:53.496  9126-9126  DEBUG                   crash_dump64                         A        #124 pc 000000000032d740  [anon:dalvik-classes.dex extracted in memory from /data/app/~~4Y9TsGqSS5d1rQF16d9IRw==/org.kiwix.kiwixmobile-uCGCV91Em8CgHXNtdh48sQ==/base.apk] (androidx.fragment.app.FragmentManager.dispatchResume+0)
2024-01-01 16:51:53.496  9126-9126  DEBUG                   crash_dump64                         A        #129 pc 0000000000324114  [anon:dalvik-classes.dex extracted in memory from /data/app/~~4Y9TsGqSS5d1rQF16d9IRw==/org.kiwix.kiwixmobile-uCGCV91Em8CgHXNtdh48sQ==/base.apk] (androidx.fragment.app.FragmentController.dispatchResume+0)
2024-01-01 16:51:53.496  9126-9126  DEBUG                   crash_dump64                         A        #134 pc 0000000000322020  [anon:dalvik-classes.dex extracted in memory from /data/app/~~4Y9TsGqSS5d1rQF16d9IRw==/org.kiwix.kiwixmobile-uCGCV91Em8CgHXNtdh48sQ==/base.apk] (androidx.fragment.app.FragmentActivity.onResumeFragments+0)
2024-01-01 16:51:53.496  9126-9126  DEBUG                   crash_dump64                         A        #139 pc 0000000000321f58  [anon:dalvik-classes.dex extracted in memory from /data/app/~~4Y9TsGqSS5d1rQF16d9IRw==/org.kiwix.kiwixmobile-uCGCV91Em8CgHXNtdh48sQ==/base.apk] (androidx.fragment.app.FragmentActivity.onPostResume+0)
2024-01-01 16:51:53.496  9126-9126  DEBUG                   crash_dump64                         A        #144 pc 00000000001773ec  [anon:dalvik-classes.dex extracted in memory from /data/app/~~4Y9TsGqSS5d1rQF16d9IRw==/org.kiwix.kiwixmobile-uCGCV91Em8CgHXNtdh48sQ==/base.apk] (androidx.appcompat.app.AppCompatActivity.onPostResume+0)
---------------------------- PROCESS ENDED (9128) for package org.kiwix.kiwixmobile ----------------------------

This is how i am checking the permission

 @JvmStatic
  fun getAssetFileDescriptorFromUri(
    context: Context,
    uri: Uri
  ): AssetFileDescriptor? {
    return try {
      val documentFile = DocumentFile.fromSingleUri(context, uri)
      if (documentFile?.uri == null) {
        return null
      }
      Log.e(
        "PERMISSION",
        "getAssetFileDescriptorFromUri: can Read selected uri =  ${documentFile.canRead()}\n" +
          " can right selected uri = ${documentFile.canWrite()}"
      )
      context.contentResolver.openFileDescriptor(documentFile.uri, "r", null).use {
        Log.e(
          "PERMISSION",
          "getAssetFileDescriptorFromUri: check file descriptor permission is fileDescriptor readable = " +
            "${checkReadFileDescriptorPermission(it?.fileDescriptor)}"
        )
        AssetFileDescriptor(
          ParcelFileDescriptor.dup(it?.fileDescriptor),
          0, AssetFileDescriptor.UNKNOWN_LENGTH
        )
      }
    } catch (ignore: Exception) {
      Log.e(
        "GET_FILE_DESCRIPTOR",
        "Unable to get the file descriptor for uri = $uri\n original exception = $ignore"
      )
      null
    }
  }

  private fun checkReadFileDescriptorPermission(fileDescriptor: FileDescriptor?): Boolean {
    if (fileDescriptor?.valid() == false) {
      // The FileDescriptor is not valid
      return false
    }

    return try {
      val channel = FileInputStream(fileDescriptor).channel
      // Try to check read access
      channel.position(0)
      channel.read(ByteBuffer.allocate(1))
      true
    } catch (ignore: Exception) {
      // An exception occurred, indicating a lack of read permission
      Log.e("PERMISSION", "checkReadFileDescriptorPermission: $ignore")
      false
    }
  }

@mgautierfr
Copy link
Member

Can you please help me out in this? What are the parameters you are using for validating the fileDescriptor?

We don't check. The Error opening file: /dev/fd/114: Permission denied comes from the system which doesn't allow use to open the fd.

Can you try to open it directly from java to see if it is a libzim issue or a java/android/kiwix-android one ?

Please try both:

@MohitMaliFtechiz
Copy link
Collaborator Author

@mgautierfr I have tried to read the content of fileDescriptor via inputStream and i am able to read it's content.

 @JvmStatic
  fun getAssetFileDescriptorFromUri(
    context: Context,
    uri: Uri
  ): AssetFileDescriptor? {
    return try {
      val documentFile = DocumentFile.fromSingleUri(context, uri)
      if (documentFile?.uri == null) {
        return null
      }
      context.contentResolver.openFileDescriptor(documentFile.uri, "r", null).use {
        AssetFileDescriptor(
          ParcelFileDescriptor.dup(it?.fileDescriptor),
          0, AssetFileDescriptor.UNKNOWN_LENGTH
        ).also { assetFileDescriptor ->
          Log.e(
            "GET_FILE_DESCRIPTOR",
            "File descriptor has content = ${hasContent(assetFileDescriptor.parcelFileDescriptor)}\n" +
              "File descriptor = ${assetFileDescriptor.parcelFileDescriptor.fd}"
          )
        }
      }
    } catch (ignore: Exception) {
      Log.e(
        "GET_FILE_DESCRIPTOR",
        "Unable to get the file descriptor for uri = $uri\n original exception = $ignore"
      )
      null
    }
  }

  fun hasContent(fileDescriptor: ParcelFileDescriptor?): Boolean {
    return try {
      val inputStream = FileInputStream(fileDescriptor?.fileDescriptor)
      val buffer = ByteArray(1024)
      var bytesRead: Int
      var totalBytesRead = 0
      while (inputStream.read(buffer).also { bytesRead = it } != -1) {
        totalBytesRead += bytesRead
      }
      inputStream.close()
      Log.e(
        "GET_FILE_DESCRIPTOR",
        "file descriptor content length with inputStream $totalBytesRead"
      )
      totalBytesRead > 0
    } catch (e: Exception) {
      e.printStackTrace()
      false
    }
  }

And outPut logs are these

GET_FILE_DESCRIPTOR     org.kiwix.kiwixmobile                E  file descriptor content length with inputStream 114374048
GET_FILE_DESCRIPTOR     org.kiwix.kiwixmobile                E  File descriptor has content = true
                                                 File descriptor = 258
2024-01-04 12:47:21.341 26340-26340 wix.kiwixmobile         org.kiwix.kiwixmobile                W  Accessing hidden field Ljava/io/FileDescriptor;->descriptor:I (unsupported, JNI, allowed)
2024-01-04 12:47:21.354 26340-26340 StrictMode              org.kiwix.kiwixmobile                D  StrictMode policy violation: android.os.strictmode.NonSdkApiUsedViolation: Ljava/io/FileDescriptor;->descriptor:I
                                                                                                    	at android.os.StrictMode.lambda$static$1(StrictMode.java:430)
                                                                                                    	at android.os.StrictMode$$ExternalSyntheticLambda2.accept(Unknown Source:2)
                                                                                                    	at org.kiwix.libzim.Archive.setNativeArchiveEmbedded(Native Method)
                                                                                                    	at org.kiwix.libzim.Archive.<init>(Archive.java:44)
                                                                                                    	at org.kiwix.kiwixmobile.core.reader.ZimFileReader$Factory$Impl.createArchiveWithAssetFileDescriptor(ZimFileReader.kt:121)
                                                                                                    	at org.kiwix.kiwixmobile.core.reader.ZimFileReader$Factory$Impl.create(ZimFileReader.kt:82)
                                                                                                    	at org.kiwix.kiwixmobile.core.reader.ZimReaderContainer.setZimFileOrFileDescriptor(ZimReaderContainer.kt:45)
                                                                                                    	at org.kiwix.kiwixmobile.core.main.CoreReaderFragment.openAndSetInContainer(CoreReaderFragment.kt:1531)
                                                                                                    	at org.kiwix.kiwixmobile.core.main.CoreReaderFragment.openZimFile(CoreReaderFragment.kt:1486)
                                                                                                    	at org.kiwix.kiwixmobile.core.main.CoreReaderFragment.openZimFile$default(CoreReaderFragment.kt:1478)
                                                                                                    	at org.kiwix.kiwixmobile.nav.destination.reader.KiwixReaderFragment.tryOpeningZimFile(KiwixReaderFragment.kt:112)
                                                                                                    	at org.kiwix.kiwixmobile.nav.destination.reader.KiwixReaderFragment.openPageInBookFromNavigationArguments(KiwixReaderFragment.kt:99)
                                                                                                    	at org.kiwix.kiwixmobile.nav.destination.reader.KiwixReaderFragment.onViewCreated(KiwixReaderFragment.kt:80)
                                                                                                    	at androidx.fragment.app.Fragment.performViewCreated(Fragment.java:3128)
                                                                                                    	at androidx.fragment.app.FragmentStateManager.createView(FragmentStateManager.java:552)
                                                                                                    	at androidx.fragment.app.FragmentStateManager.moveToExpectedState(FragmentStateManager.java:261)
                                                                                                    	at androidx.fragment.app.FragmentManager.executeOpsTogether(FragmentManager.java:1899)
                                                                                                    	at androidx.fragment.app.FragmentManager.removeRedundantOperationsAndExecute(FragmentManager.java:1823)
                                                                                                    	at androidx.fragment.app.FragmentManager.execPendingActions(FragmentManager.java:1760)
                                                                                                    	at androidx.fragment.app.Fragment.performResume(Fragment.java:3177)
                                                                                                    	at androidx.fragment.app.FragmentStateManager.resume(FragmentStateManager.java:606)
                                                                                                    	at androidx.fragment.app.FragmentStateManager.moveToExpectedState(FragmentStateManager.java:285)
                                                                                                    	at androidx.fragment.app.FragmentStore.moveToExpectedState(FragmentStore.java:113)
                                                                                                    	at androidx.fragment.app.FragmentManager.moveToState(FragmentManager.java:1433)
                                                                                                    	at androidx.fragment.app.FragmentManager.dispatchStateChange(FragmentManager.java:2977)
                                                                                                    	at androidx.fragment.app.FragmentManager.dispatchResume(FragmentManager.java:2909)
                                                                                                    	at androidx.fragment.app.FragmentController.dispatchResume(FragmentController.java:285)
                                                                                                    	at androidx.fragment.app.FragmentActivity.onResumeFragments(FragmentActivity.java:334)
                                                                                                    	at androidx.fragment.app.FragmentActivity.onPostResume(FragmentActivity.java:323)
                                                                                                    	at androidx.appcompat.app.AppCompatActivity.onPostResume(AppCompatActivity.java:204)
                                                                                                    	at android.app.Activity.performResume(Activity.java:8796)
                                                                                                    	at android.app.ActivityThread.performResumeActivity(ActivityThread.java:4972)
                                                                                                    	at android.app.ActivityThread.handleResumeActivity(ActivityThread.java:5015)
                                                                                                    	at android.app.servertransaction.ResumeActivityItem.execute(ResumeActivityItem.java:57)
                                                                                                    	at android.app.servertransaction.ActivityTransactionItem.execute(ActivityTransactionItem.java:45)
                                                                                                    	at android.app.servertransaction.TransactionExecutor.executeLifecycleState(TransactionExecutor.java:180)
                                                                                                    	at android.app.servertransaction.TransactionExecutor.execute(TransactionExecutor.java:98)
                                                                                                    	at android.app.ActivityThread$H.handleMessage(ActivityThread.java:2448)
                                                                                                    	at android.os.Handler.dispatchMessage(Handler.java:106)
                                                                                                    	at android.os.Looper.loopOnce(Looper.java:205)
                                                                                                    	at android.os.Looper.loop(Looper.java:294)
                                                                                                    	at android.app.ActivityThread.main(ActivityThread.java:8194)
                                                                                                    	at java.lang.reflect.Method.invoke(Native Method)
                                                                                                    	at com.android.internal.os.RuntimeInit$MethodAndArgsCaller.run(RuntimeInit.java:552)
                                                                                                    	at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:971)
org.kiwix.kiwixmobile                E  Attempting to create reader with fd: 258
org.kiwix.kiwixmobile                E  Error opening ZIM file
org.kiwix.kiwixmobile                E  Error opening file: /dev/fd/258: Permission denied
org.kiwix.kiwixmobile                A  Fatal signal 11 (SIGSEGV), code 1 (SEGV_MAPERR), fault addr 0x0 in tid 26340 (wix.kiwixmobile), pid 26340 (wix.kiwixmobile)
2024-01-04 12:47:21.882 26552-26552 DEBUG                   pid-26552                            A  Cmdline: org.kiwix.kiwixmobile
2024-01-04 12:47:21.882 26552-26552 DEBUG                   pid-26552                            A  pid: 26340, tid: 26340, name: wix.kiwixmobile  >>> org.kiwix.kiwixmobile <<<
2024-01-04 12:47:21.882 26552-26552 DEBUG                   pid-26552                            A        #00 pc 0000000000025464  /data/app/~~FbsClYufNLE-k_YHGkWZeA==/org.kiwix.kiwixmobile-qfSf0fV-Rl8p6Jimx62qNQ==/base.apk!libzim_wrapper.so (offset 0x198c000) (Java_org_kiwix_libzim_SuggestionSearcher_setNativeSearcher+112) (BuildId: 6c0d6ee977af86c7d817e067ec4176543043faa4)
2024-01-04 12:47:21.882 26552-26552 DEBUG                   pid-26552                            A        #06 pc 0000000000337610  [anon:dalvik-classes29.dex extracted in memory from /data/app/~~FbsClYufNLE-k_YHGkWZeA==/org.kiwix.kiwixmobile-qfSf0fV-Rl8p6Jimx62qNQ==/base.apk!classes29.dex] (org.kiwix.libzim.SuggestionSearcher.<init>+0)
2024-01-04 12:47:21.882 26552-26552 DEBUG                   pid-26552                            A        #11 pc 0000000000008a38  /data/data/org.kiwix.kiwixmobile/code_cache/.overlay/base.apk/classes13.dex (org.kiwix.kiwixmobile.core.reader.ZimFileReader.<init>+0)
2024-01-04 12:47:21.882 26552-26552 DEBUG                   pid-26552                            A        #17 pc 0000000000006dc8  /data/data/org.kiwix.kiwixmobile/code_cache/.overlay/base.apk/classes13.dex (org.kiwix.kiwixmobile.core.reader.ZimFileReader$Factory$Impl.createArchiveWithAssetFileDescriptor+0)
2024-01-04 12:47:21.882 26552-26552 DEBUG                   pid-26552                            A        #22 pc 0000000000006d28  /data/data/org.kiwix.kiwixmobile/code_cache/.overlay/base.apk/classes13.dex (org.kiwix.kiwixmobile.core.reader.ZimFileReader$Factory$Impl.create+0)
2024-01-04 12:47:21.882 26552-26552 DEBUG                   pid-26552                            A        #27 pc 000000000000998c  /data/data/org.kiwix.kiwixmobile/code_cache/.overlay/base.apk/classes13.dex (org.kiwix.kiwixmobile.core.reader.ZimReaderContainer.setZimFileOrFileDescriptor+0)
2024-01-04 12:47:21.882 26552-26552 DEBUG                   pid-26552                            A        #32 pc 000000000001ad7c  [anon:dalvik-classes5.dex extracted in memory from /data/app/~~FbsClYufNLE-k_YHGkWZeA==/org.kiwix.kiwixmobile-qfSf0fV-Rl8p6Jimx62qNQ==/base.apk!classes5.dex] (org.kiwix.kiwixmobile.core.main.CoreReaderFragment.openAndSetInContainer+0)
2024-01-04 12:47:21.882 26552-26552 DEBUG                   pid-26552                            A        #37 pc 000000000001b664  [anon:dalvik-classes5.dex extracted in memory from /data/app/~~FbsClYufNLE-k_YHGkWZeA==/org.kiwix.kiwixmobile-qfSf0fV-Rl8p6Jimx62qNQ==/base.apk!classes5.dex] (org.kiwix.kiwixmobile.core.main.CoreReaderFragment.openZimFile+0)
2024-01-04 12:47:21.882 26552-26552 DEBUG                   pid-26552                            A        #42 pc 000000000001b5c8  [anon:dalvik-classes5.dex extracted in memory from /data/app/~~FbsClYufNLE-k_YHGkWZeA==/org.kiwix.kiwixmobile-qfSf0fV-Rl8p6Jimx62qNQ==/base.apk!classes5.dex] (org.kiwix.kiwixmobile.core.main.CoreReaderFragment.openZimFile$default+0)
2024-01-04 12:47:21.882 26552-26552 DEBUG                   pid-26552                            A        #48 pc 0000000000006f90  [anon:dalvik-classes28.dex extracted in memory from /data/app/~~FbsClYufNLE-k_YHGkWZeA==/org.kiwix.kiwixmobile-qfSf0fV-Rl8p6Jimx62qNQ==/base.apk!classes28.dex] (org.kiwix.kiwixmobile.nav.destination.reader.KiwixReaderFragment.tryOpeningZimFile+0)
2024-01-04 12:47:21.882 26552-26552 DEBUG                   pid-26552                            A        #53 pc 0000000000006a28  [anon:dalvik-classes28.dex extracted in memory from /data/app/~~FbsClYufNLE-k_YHGkWZeA==/org.kiwix.kiwixmobile-qfSf0fV-Rl8p6Jimx62qNQ==/base.apk!classes28.dex] (org.kiwix.kiwixmobile.nav.destination.reader.KiwixReaderFragment.openPageInBookFromNavigationArguments+0)
2024-01-04 12:47:21.882 26552-26552 DEBUG                   pid-26552                            A        #58 pc 000000000000684c  [anon:dalvik-classes28.dex extracted in memory from /data/app/~~FbsClYufNLE-k_YHGkWZeA==/org.kiwix.kiwixmobile-qfSf0fV-Rl8p6Jimx62qNQ==/base.apk!classes28.dex] (org.kiwix.kiwixmobile.nav.destination.reader.KiwixReaderFragment.onViewCreated+0)
2024-01-04 12:47:21.882 26552-26552 DEBUG                   pid-26552                            A        #63 pc 000000000033ffa0  [anon:dalvik-classes.dex extracted in memory from /data/app/~~FbsClYufNLE-k_YHGkWZeA==/org.kiwix.kiwixmobile-qfSf0fV-Rl8p6Jimx62qNQ==/base.apk] (androidx.fragment.app.Fragment.performViewCreated+0)
2024-01-04 12:47:21.882 26552-26552 DEBUG                   pid-26552                            A        #68 pc 000000000033205c  [anon:dalvik-classes.dex extracted in memory from /data/app/~~FbsClYufNLE-k_YHGkWZeA==/org.kiwix.kiwixmobile-qfSf0fV-Rl8p6Jimx62qNQ==/base.apk] (androidx.fragment.app.FragmentStateManager.createView+0)
2024-01-04 12:47:21.882 26552-26552 DEBUG                   pid-26552                            A        #73 pc 0000000000332de4  [anon:dalvik-classes.dex extracted in memory from /data/app/~~FbsClYufNLE-k_YHGkWZeA==/org.kiwix.kiwixmobile-qfSf0fV-Rl8p6Jimx62qNQ==/base.apk] (androidx.fragment.app.FragmentStateManager.moveToExpectedState+0)
2024-01-04 12:47:21.882 26552-26552 DEBUG                   pid-26552                            A        #79 pc 000000000032e32c  [anon:dalvik-classes.dex extracted in memory from /data/app/~~FbsClYufNLE-k_YHGkWZeA==/org.kiwix.kiwixmobile-qfSf0fV-Rl8p6Jimx62qNQ==/base.apk] (androidx.fragment.app.FragmentManager.executeOpsTogether+0)
2024-01-04 12:47:21.882 26552-26552 DEBUG                   pid-26552                            A        #84 pc 000000000032f59c  [anon:dalvik-classes.dex extracted in memory from /data/app/~~FbsClYufNLE-k_YHGkWZeA==/org.kiwix.kiwixmobile-qfSf0fV-Rl8p6Jimx62qNQ==/base.apk] (androidx.fragment.app.FragmentManager.removeRedundantOperationsAndExecute+0)
2024-01-04 12:47:21.882 26552-26552 DEBUG                   pid-26552                            A        #89 pc 000000000032a7cc  [anon:dalvik-classes.dex extracted in memory from /data/app/~~FbsClYufNLE-k_YHGkWZeA==/org.kiwix.kiwixmobile-qfSf0fV-Rl8p6Jimx62qNQ==/base.apk] (androidx.fragment.app.FragmentManager.execPendingActions+0)
2024-01-04 12:47:21.882 26552-26552 DEBUG                   pid-26552                            A        #94 pc 000000000033fc5c  [anon:dalvik-classes.dex extracted in memory from /data/app/~~FbsClYufNLE-k_YHGkWZeA==/org.kiwix.kiwixmobile-qfSf0fV-Rl8p6Jimx62qNQ==/base.apk] (androidx.fragment.app.Fragment.performResume+0)
2024-01-04 12:47:21.882 26552-26552 DEBUG                   pid-26552                            A        #99 pc 0000000000333778  [anon:dalvik-classes.dex extracted in memory from /data/app/~~FbsClYufNLE-k_YHGkWZeA==/org.kiwix.kiwixmobile-qfSf0fV-Rl8p6Jimx62qNQ==/base.apk] (androidx.fragment.app.FragmentStateManager.resume+0)
2024-01-04 12:47:21.882 26552-26552 DEBUG                   pid-26552                            A        #104 pc 0000000000332de4  [anon:dalvik-classes.dex extracted in memory from /data/app/~~FbsClYufNLE-k_YHGkWZeA==/org.kiwix.kiwixmobile-qfSf0fV-Rl8p6Jimx62qNQ==/base.apk] (androidx.fragment.app.FragmentStateManager.moveToExpectedState+0)
2024-01-04 12:47:21.882 26552-26552 DEBUG                   pid-26552                            A        #109 pc 0000000000335f34  [anon:dalvik-classes.dex extracted in memory from /data/app/~~FbsClYufNLE-k_YHGkWZeA==/org.kiwix.kiwixmobile-qfSf0fV-Rl8p6Jimx62qNQ==/base.apk] (androidx.fragment.app.FragmentStore.moveToExpectedState+0)
2024-01-04 12:47:21.882 26552-26552 DEBUG                   pid-26552                            A        #114 pc 000000000032ef00  [anon:dalvik-classes.dex extracted in memory from /data/app/~~FbsClYufNLE-k_YHGkWZeA==/org.kiwix.kiwixmobile-qfSf0fV-Rl8p6Jimx62qNQ==/base.apk] (androidx.fragment.app.FragmentManager.moveToState+0)
2024-01-04 12:47:21.882 26552-26552 DEBUG                   pid-26552                            A        #119 pc 000000000032d7e0  [anon:dalvik-classes.dex extracted in memory from /data/app/~~FbsClYufNLE-k_YHGkWZeA==/org.kiwix.kiwixmobile-qfSf0fV-Rl8p6Jimx62qNQ==/base.apk] (androidx.fragment.app.FragmentManager.dispatchStateChange+0)
2024-01-04 12:47:21.882 26552-26552 DEBUG                   pid-26552                            A        #124 pc 000000000032d740  [anon:dalvik-classes.dex extracted in memory from /data/app/~~FbsClYufNLE-k_YHGkWZeA==/org.kiwix.kiwixmobile-qfSf0fV-Rl8p6Jimx62qNQ==/base.apk] (androidx.fragment.app.FragmentManager.dispatchResume+0)
2024-01-04 12:47:21.882 26552-26552 DEBUG                   pid-26552                            A        #129 pc 0000000000324114  [anon:dalvik-classes.dex extracted in memory from /data/app/~~FbsClYufNLE-k_YHGkWZeA==/org.kiwix.kiwixmobile-qfSf0fV-Rl8p6Jimx62qNQ==/base.apk] (androidx.fragment.app.FragmentController.dispatchResume+0)
2024-01-04 12:47:21.882 26552-26552 DEBUG                   pid-26552                            A        #134 pc 0000000000322020  [anon:dalvik-classes.dex extracted in memory from /data/app/~~FbsClYufNLE-k_YHGkWZeA==/org.kiwix.kiwixmobile-qfSf0fV-Rl8p6Jimx62qNQ==/base.apk] (androidx.fragment.app.FragmentActivity.onResumeFragments+0)
2024-01-04 12:47:21.882 26552-26552 DEBUG                   pid-26552                            A        #139 pc 0000000000321f58  [anon:dalvik-classes.dex extracted in memory from /data/app/~~FbsClYufNLE-k_YHGkWZeA==/org.kiwix.kiwixmobile-qfSf0fV-Rl8p6Jimx62qNQ==/base.apk] (androidx.fragment.app.FragmentActivity.onPostResume+0)
2024-01-04 12:47:21.883 26552-26552 DEBUG                   pid-26552                            A        #144 pc 00000000001773ec  [anon:dalvik-classes.dex extracted in memory from /data/app/~~FbsClYufNLE-k_YHGkWZeA==/org.kiwix.kiwixmobile-qfSf0fV-Rl8p6Jimx62qNQ==/base.apk] (androidx.appcompat.app.AppCompatActivity.onPostResume+0)

@MohitMaliFtechiz
Copy link
Collaborator Author

@kelson42, @mgautierfr I also tried to open the fd via dev/fd/fdNumber and I think we found the actual problem. When we are trying to open the fd via the path on other architectures, it gives the permission denied error. See the below logs.

@mgautierfr are we opening the fileDescriptor via path in libkiwix? since we are able to read the content directly from the fileDescriptor as shown in the above comment so I think we should use that fileDescriptor which we are opening from the selected URI because it has the necessary permissions. Above Android 11 there are limitations to accessing files via path that's the reason it is giving this error, let me know if I am wrong about the libkiwix.

The code i have used

 @JvmStatic
  fun getAssetFileDescriptorFromUri(
    context: Context,
    uri: Uri
  ): AssetFileDescriptor? {
    return try {
      val documentFile = DocumentFile.fromSingleUri(context, uri)
      if (documentFile?.uri == null) {
        return null
      }
      context.contentResolver.openFileDescriptor(documentFile.uri, "r", null).use {
        AssetFileDescriptor(
          ParcelFileDescriptor.dup(it?.fileDescriptor),
          0, AssetFileDescriptor.UNKNOWN_LENGTH
        ).also { assetFileDescriptor ->
          Log.e(
            "GET_FILE_DESCRIPTOR",
            "With uri = ${documentFile.uri}\n" +
              "File descriptor has content = ${hasContent(assetFileDescriptor.parcelFileDescriptor)}\n" +
              "File descriptor = ${assetFileDescriptor.parcelFileDescriptor.fd}\n" +
              "Has content with path = ${hasContentWithPath(assetFileDescriptor.parcelFileDescriptor.fd)}"
          )
        }
      }
    } catch (ignore: Exception) {
      Log.e(
        "GET_FILE_DESCRIPTOR",
        "Unable to get the file descriptor for uri = $uri\n original exception = $ignore"
      )
      null
    }
  }

  fun hasContent(fileDescriptor: ParcelFileDescriptor?): Boolean {
    return try {
      val inputStream = FileInputStream(fileDescriptor?.fileDescriptor)
      val buffer = ByteArray(1024)
      var bytesRead: Int
      var totalBytesRead = 0
      while (inputStream.read(buffer).also { bytesRead = it } != -1) {
        totalBytesRead += bytesRead
      }
      inputStream.close()
      Log.e(
        "GET_FILE_DESCRIPTOR",
        "file descriptor content length with inputStream $totalBytesRead"
      )
      totalBytesRead > 0
    } catch (e: Exception) {
      e.printStackTrace()
      false
    }
  }

  fun hasContentWithPath(fdNumber: Int?): Boolean {
    return try {
      val inputStream = FileInputStream("dev/fd/$fdNumber")
      val buffer = ByteArray(1024)
      var bytesRead: Int
      var totalBytesRead = 0
      while (inputStream.read(buffer).also { bytesRead = it } != -1) {
        totalBytesRead += bytesRead
      }
      inputStream.close()
      Log.e(
        "GET_FILE_DESCRIPTOR",
        "content length from from path with inputStream $totalBytesRead"
      )
      totalBytesRead > 0
    } catch (e: Exception) {
      e.printStackTrace()
      false
    }
  }

With armeabi-v7a.

2024-01-04 14:13:44.213 21113-21113 GET_FILE_DESCRIPTOR     org.kiwix.kiwixmobile                E  file descriptor content length with inputStream 3643055
2024-01-04 14:13:44.550 21113-21113 GET_FILE_DESCRIPTOR     org.kiwix.kiwixmobile                E  content length from from path with inputStream 3643055
2024-01-04 14:13:44.551 21113-21113 GET_FILE_DESCRIPTOR     org.kiwix.kiwixmobile                E  With uri = Zcontent://com.android.externalstorage.documents/document/58DD-0C22%3ADownload%2Falpinelinux_en_all_maxi_2022-10.zim
                                                                                                    File descriptor has content = true
                                                                                                    File descriptor = 94
                                                                                                    Has content with path = true

With arm64.

2024-01-04 14:17:27.903  5043-5043  GET_FILE_DESCRIPTOR     org.kiwix.kiwixmobile                E  file descriptor content length with inputStream 114374048
2024-01-04 14:17:27.906  5043-5043  System.err              org.kiwix.kiwixmobile                W  java.io.FileNotFoundException: dev/fd/98: open failed: EACCES (Permission denied)
2024-01-04 14:17:27.906  5043-5043  System.err              org.kiwix.kiwixmobile                W  	at libcore.io.IoBridge.open(IoBridge.java:574)
2024-01-04 14:17:27.906  5043-5043  System.err              org.kiwix.kiwixmobile                W  	at java.io.FileInputStream.<init>(FileInputStream.java:160)
2024-01-04 14:17:27.906  5043-5043  System.err              org.kiwix.kiwixmobile                W  	at java.io.FileInputStream.<init>(FileInputStream.java:115)
2024-01-04 14:17:27.906  5043-5043  System.err              org.kiwix.kiwixmobile                W  	at org.kiwix.kiwixmobile.core.utils.files.FileUtils.hasContentWithPath(FileUtils.kt:473)
2024-01-04 14:17:27.907  5043-5043  System.err              org.kiwix.kiwixmobile                W  	at org.kiwix.kiwixmobile.core.utils.files.FileUtils.getAssetFileDescriptorFromUri(FileUtils.kt:437)
2024-01-04 14:17:27.907  5043-5043  System.err              org.kiwix.kiwixmobile                W  	at org.kiwix.kiwixmobile.nav.destination.reader.KiwixReaderFragment.tryOpeningZimFile(KiwixReaderFragment.kt:108)
2024-01-04 14:17:27.907  5043-5043  System.err              org.kiwix.kiwixmobile                W  	at org.kiwix.kiwixmobile.nav.destination.reader.KiwixReaderFragment.openPageInBookFromNavigationArguments(KiwixReaderFragment.kt:99)
2024-01-04 14:17:27.907  5043-5043  System.err              org.kiwix.kiwixmobile                W  	at org.kiwix.kiwixmobile.nav.destination.reader.KiwixReaderFragment.onViewCreated(KiwixReaderFragment.kt:80)
2024-01-04 14:17:27.907  5043-5043  System.err              org.kiwix.kiwixmobile                W  	at androidx.fragment.app.Fragment.performViewCreated(Fragment.java:3128)
2024-01-04 14:17:27.907  5043-5043  System.err              org.kiwix.kiwixmobile                W  	at androidx.fragment.app.FragmentStateManager.createView(FragmentStateManager.java:552)
2024-01-04 14:17:27.908  5043-5043  System.err              org.kiwix.kiwixmobile                W  	at androidx.fragment.app.FragmentStateManager.moveToExpectedState(FragmentStateManager.java:261)
2024-01-04 14:17:27.908  5043-5043  System.err              org.kiwix.kiwixmobile                W  	at androidx.fragment.app.FragmentManager.executeOpsTogether(FragmentManager.java:1899)
2024-01-04 14:17:27.908  5043-5043  System.err              org.kiwix.kiwixmobile                W  	at androidx.fragment.app.FragmentManager.removeRedundantOperationsAndExecute(FragmentManager.java:1823)
2024-01-04 14:17:27.908  5043-5043  System.err              org.kiwix.kiwixmobile                W  	at androidx.fragment.app.FragmentManager.execPendingActions(FragmentManager.java:1760)
2024-01-04 14:17:27.908  5043-5043  System.err              org.kiwix.kiwixmobile                W  	at androidx.fragment.app.Fragment.performResume(Fragment.java:3177)
2024-01-04 14:17:27.908  5043-5043  System.err              org.kiwix.kiwixmobile                W  	at androidx.fragment.app.FragmentStateManager.resume(FragmentStateManager.java:606)
2024-01-04 14:17:27.909  5043-5043  System.err              org.kiwix.kiwixmobile                W  	at androidx.fragment.app.FragmentStateManager.moveToExpectedState(FragmentStateManager.java:285)
2024-01-04 14:17:27.909  5043-5043  System.err              org.kiwix.kiwixmobile                W  	at androidx.fragment.app.FragmentStore.moveToExpectedState(FragmentStore.java:113)
2024-01-04 14:17:27.909  5043-5043  System.err              org.kiwix.kiwixmobile                W  	at androidx.fragment.app.FragmentManager.moveToState(FragmentManager.java:1433)
2024-01-04 14:17:27.909  5043-5043  System.err              org.kiwix.kiwixmobile                W  	at androidx.fragment.app.FragmentManager.dispatchStateChange(FragmentManager.java:2977)
2024-01-04 14:17:27.909  5043-5043  System.err              org.kiwix.kiwixmobile                W  	at androidx.fragment.app.FragmentManager.dispatchResume(FragmentManager.java:2909)
2024-01-04 14:17:27.909  5043-5043  System.err              org.kiwix.kiwixmobile                W  	at androidx.fragment.app.FragmentController.dispatchResume(FragmentController.java:285)
2024-01-04 14:17:27.909  5043-5043  System.err              org.kiwix.kiwixmobile                W  	at androidx.fragment.app.FragmentActivity.onResumeFragments(FragmentActivity.java:334)
2024-01-04 14:17:27.910  5043-5043  System.err              org.kiwix.kiwixmobile                W  	at androidx.fragment.app.FragmentActivity.onPostResume(FragmentActivity.java:323)
2024-01-04 14:17:27.910  5043-5043  System.err              org.kiwix.kiwixmobile                W  	at androidx.appcompat.app.AppCompatActivity.onPostResume(AppCompatActivity.java:204)
2024-01-04 14:17:27.910  5043-5043  System.err              org.kiwix.kiwixmobile                W  	at android.app.Activity.performResume(Activity.java:8796)
2024-01-04 14:17:27.910  5043-5043  System.err              org.kiwix.kiwixmobile                W  	at android.app.ActivityThread.performResumeActivity(ActivityThread.java:4972)
2024-01-04 14:17:27.910  5043-5043  System.err              org.kiwix.kiwixmobile                W  	at android.app.ActivityThread.handleResumeActivity(ActivityThread.java:5015)
2024-01-04 14:17:27.910  5043-5043  System.err              org.kiwix.kiwixmobile                W  	at android.app.servertransaction.ResumeActivityItem.execute(ResumeActivityItem.java:57)
2024-01-04 14:17:27.910  5043-5043  System.err              org.kiwix.kiwixmobile                W  	at android.app.servertransaction.ActivityTransactionItem.execute(ActivityTransactionItem.java:45)
2024-01-04 14:17:27.911  5043-5043  System.err              org.kiwix.kiwixmobile                W  	at android.app.servertransaction.TransactionExecutor.executeLifecycleState(TransactionExecutor.java:180)
2024-01-04 14:17:27.911  5043-5043  System.err              org.kiwix.kiwixmobile                W  	at android.app.servertransaction.TransactionExecutor.execute(TransactionExecutor.java:98)
2024-01-04 14:17:27.911  5043-5043  System.err              org.kiwix.kiwixmobile                W  	at android.app.ActivityThread$H.handleMessage(ActivityThread.java:2448)
2024-01-04 14:17:27.911  5043-5043  System.err              org.kiwix.kiwixmobile                W  	at android.os.Handler.dispatchMessage(Handler.java:106)
2024-01-04 14:17:27.911  5043-5043  System.err              org.kiwix.kiwixmobile                W  	at android.os.Looper.loopOnce(Looper.java:205)
2024-01-04 14:17:27.911  5043-5043  System.err              org.kiwix.kiwixmobile                W  	at android.os.Looper.loop(Looper.java:294)
2024-01-04 14:17:27.911  5043-5043  System.err              org.kiwix.kiwixmobile                W  	at android.app.ActivityThread.main(ActivityThread.java:8194)
2024-01-04 14:17:27.912  5043-5043  System.err              org.kiwix.kiwixmobile                W  	at java.lang.reflect.Method.invoke(Native Method)
2024-01-04 14:17:27.912  5043-5043  System.err              org.kiwix.kiwixmobile                W  	at com.android.internal.os.RuntimeInit$MethodAndArgsCaller.run(RuntimeInit.java:552)
2024-01-04 14:17:27.912  5043-5043  System.err              org.kiwix.kiwixmobile                W  	at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:971)
2024-01-04 14:17:27.912  5043-5043  System.err              org.kiwix.kiwixmobile                W  Caused by: android.system.ErrnoException: open failed: EACCES (Permission denied)
2024-01-04 14:17:27.912  5043-5043  System.err              org.kiwix.kiwixmobile                W  	at libcore.io.Linux.open(Native Method)
2024-01-04 14:17:27.913  5043-5043  System.err              org.kiwix.kiwixmobile                W  	at libcore.io.ForwardingOs.open(ForwardingOs.java:563)
2024-01-04 14:17:27.913  5043-5043  System.err              org.kiwix.kiwixmobile                W  	at libcore.io.BlockGuardOs.open(BlockGuardOs.java:274)
2024-01-04 14:17:27.913  5043-5043  System.err              org.kiwix.kiwixmobile                W  	at libcore.io.ForwardingOs.open(ForwardingOs.java:563)
2024-01-04 14:17:27.913  5043-5043  System.err              org.kiwix.kiwixmobile                W  	at android.app.ActivityThread$AndroidOs.open(ActivityThread.java:8080)
2024-01-04 14:17:27.913  5043-5043  System.err              org.kiwix.kiwixmobile                W  	at libcore.io.IoBridge.open(IoBridge.java:560)
2024-01-04 14:17:27.913  5043-5043  System.err              org.kiwix.kiwixmobile                W  	... 39 more
2024-01-04 14:17:27.913  5043-5043  GET_FILE_DESCRIPTOR     org.kiwix.kiwixmobile                E  With uri = content://com.android.externalstorage.documents/document/primary%3ADownload%2Finternet-encyclopedia-philosophy_en_all_2023-08.zim
                                                                                                    File descriptor has content = true
                                                                                                    File descriptor = 98
                                                                                                    Has content with path = false

@mgautierfr
Copy link
Member

@mgautierfr are we opening the fileDescriptor via path in libkiwix? since we are able to read the content directly from the fileDescriptor as shown in the above comment so I think we should use that fileDescriptor which we are opening from the selected URI because it has the necessary permissions. Above Android 11 there are limitations to accessing files via path that's the reason it is giving this error, let me know if I am wrong about the libkiwix.

Yes. The fact is that for having fulltext search (and titlesearch using xapian) we have to pass a fd to xapian. And the only way to acquire a new fd is to open a file (using a path). It is impossible to reopen a file from a fd.
On linux (and so android), each fd open is also accessible by a symlink /dev/fd/<fdnumber> pointing to the actual file. So we open this path to be able to have xapian search (and also getDirectAccessInformation as it give you a path to open)

@MohitMaliFtechiz
Copy link
Collaborator Author

Yes. The fact is that for having fulltext search (and titlesearch using xapian) we have to pass a fd to xapian. And the only way to acquire a new fd is to open a file (using a path). It is impossible to reopen a file from a fd.

@mgautierfr Thanks for explaining the limitation, If we need to pass a new fd to Xapian, can we open a new fd from the existing fd via fileInputStream API and use it for Xapian without affecting the existing one? Somehow this is possible at the libkiwix level.

@MohitMaliFtechiz
Copy link
Collaborator Author

@mgautierfr Is it possible?

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

Add FilePicker in PlayStore variant.
4 participants