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

App erroneously disables working libzim full-text access on some Android devices #343

Closed
Jaifroid opened this issue Jan 6, 2023 · 20 comments
Assignees
Milestone

Comments

@Jaifroid
Copy link
Member

Jaifroid commented Jan 6, 2023

As reported by @Inbefortus:

@Jaifroid The issue appears to be installing Kiwix JS PWA rather than doing so directly in the browser (in this case, Samsung Internet Browser).

Installation:
20230106_143325

Browser:

20230106_143155
Screenshot_20230106-144236_Samsung Internet

Interesting. I've always used the installation, and I'm still puzzled as to why it used to work but now doesn't. Whatever. I'm glad it's working again. From now on, I will only use the browser version if necessary.

Originally posted by @Inbefortus in #208 (comment)

@Jaifroid Jaifroid added this to the Release 2.3.0 milestone Jan 6, 2023
@Jaifroid Jaifroid self-assigned this Jan 6, 2023
@Jaifroid
Copy link
Member Author

Jaifroid commented Jan 6, 2023

@Inbefortus I've added an override to force use of the libzim WASM or ASM version, for testing purposes. It's an expert setting at the bottom of Configuration (see screenshot below). When your installed PWA has updated to version 2.2.83, could you kindly try this setting, setting it first to WASM? If that solves the issue, then I'll know I need to do more work on the auto-detection for Android. Please note that leaving this setting on could make title search appear a bit unresponsive in ZIMs that don't have a full-text index, because this is an override that disables OS and ZIM checks for development purposes. However, it shouldn't stop title search from working, it will just force an attempt at full-text searching, which of course will fail if the ZIM doesn't have an ft index.

Also note that this dropdown is not well styled for the dark theme (yet), as I did it rather hastily as a workaround.

image

@Jaifroid
Copy link
Member Author

Jaifroid commented Jan 6, 2023

@Inbefortus N.B. Turn this setting on before you select your ZIM. If you turn it off, you'll need to exit and restart the app (or refresh Ctr-R) for the setting to take effect.

@Inbefortus
Copy link

@Jaifroid Your override was effective. FTS is now triggered even in the installation. That's really cool. Thank you for providing a workaround!

@Jaifroid
Copy link
Member Author

Jaifroid commented Jan 7, 2023

There was a typo preventing this setting from being re-applied on relaunch of the app. Now fixed (v2.2.84).

@Jaifroid
Copy link
Member Author

Jaifroid commented Jan 7, 2023

@Inbefortus Are you able to let me know the device on which you're running Android? I have tried on a Samsung midranger, and also on a Samsung Galaxy S22 with Android 12 (via BrowserStack), but neither is able to use ZIM archives in a way that is readable by the libzim WASM. If you would prefer to message me privately with this info, you could either send me a message via the Kiwix Slack - user Jaifroid -, or else email (egk10 at cam ac uk).

@Jaifroid
Copy link
Member Author

Jaifroid commented Jan 7, 2023

OK, curiously, I am able to use the WASM with a Samsung Galaxy S20 running Android 10 (via BrowserStack)! But not with a Samsung Galaxy S22 running Android 12... I wonder if it's the SharedArrayBuffer "security" feature (related to Spectre/Meltdown).

Update: on the same Galaxy S20, Chrome is unable to use the WASM, but Samsung Internet is. Must be related to Chromium version. Further update, Chrome CAN use the WASM on this device, but it takes a long time to load (I didn't time it, but more than 30 seconds for a small ZIM). Suggests that Chrome is copying the archive either into memory or into some other internal filespace.

@Jaifroid
Copy link
Member Author

Jaifroid commented Jan 7, 2023

It could be this issue: https://developer.chrome.com/blog/enabling-shared-array-buffer/#history. There was a brief period in 2017 when SharedArrayBuffer was enabled on mobile Chromium, then it was disabled at some point in 2018 due to vulnerabilities. Although it has now been re-enabled, it requires that we serve Cross-Origin-Opener-Policy: same-origin. I tried this in openzim/javascript-libzim#22 (comment), but it has disastrous effects on loading content into an iframe (it considers the iframe to be loading cross-origin resources even though it's actually same origin, and so it blocks programmatic access to the iframe).

@Inbefortus
Copy link

 Are you able to let me know the device on which you're running Android?

If you're still curious, the device is a Samsung Galaxy Tab S7 Plus. It's exactly the same device I bought when I first got it, because I don't recall ever performing a software update. Android 10 is still completely functional, with no issues.

OK, curiously, I am able to use the WASM with a Samsung Galaxy S20 running Android 10 (via BrowserStack)! But not with a Samsung Galaxy S22 running Android 12... I wonder if it's the SharedArrayBuffer "security" feature (related to Spectre/Meltdown).

I could have guessed that Android 12 was to blame. For some app developers, Android 12 is a living nightmare. It caused many apps, particularly background apps, to stop working properly. My favorite reminder app is no longer functional, but it still works flawlessly in Android 10.

@Jaifroid
Copy link
Member Author

Jaifroid commented Jan 7, 2023

Come to think of it, though, if it's SharedArrayBuffer, then it wouldn't make any difference if it were Android 10 or Android 12, because the security blocking is in the browser, not in the OS. This points to issues with the way Android handles files. Indeed, the standard Kiwix Android app has had such a difficulty, due to blocking of File scanning APIs in newer Android.

@Jaifroid
Copy link
Member Author

Jaifroid commented Jan 8, 2023

It works on Android 11 on a Samsung Galaxy S21 (via BrowserStack), albeit pretty slow to load a small 31MB archive into the libzim WASM. But that pretty much confirms that the blocking issue is with Android 12.

@Inbefortus
Copy link

Interestingly, I have an Android 12 device, and FTS appears to be functioning appropriately using Samsung Internet Browser. The ZIM is English Wikipedia 0.8, and search results appear relatively quickly.

@Jaifroid
Copy link
Member Author

Jaifroid commented Jan 8, 2023

@Inbefortus That's actually very good news, because it means it's not something inherent in Android 12. I'll keep investigating. The main challenge is detecting when it's supported and when not, because there is no error message produced from the libzim backend, and no exception -- it simply fails to produce any results.

@Jaifroid
Copy link
Member Author

Jaifroid commented Jan 8, 2023

Not working on a Google Pixel 7 with Android 13. ☹️
Nor on a Galaxy Tab S8 with Android 12.

@Inbefortus
Copy link

@Jaifroid That is quite strange. Maybe BrowserStack is interfering in some way? I can't speak for Android 13, but the fact that it's not working for you on Android 12 is indeed strange...

20230108_162621

@Jaifroid
Copy link
Member Author

Jaifroid commented Jan 8, 2023

That's encouraging, but what device is that? I have a physical Android 12 Samsung M31 on which it's not working. That's why I put in code disabling libzim in Android in the first place -- which I realize now is a mistake, we should always use feature detection and not OS detection (but I can't find the feature to detect yet!).

There could additionally be some interference from BrowserStack, especially if your Android 12 device is one of those I tested on BrowserStack. The plot thickens!

@Inbefortus
Copy link

That's encouraging, but what device is that?

@Jaifroid It's an S22 Ultra that hasn't been updated since September. Check the version of your Samsung Internet Browser, mine is 19.0.3.12.

Give the S22 Ultra a shot if you haven't already, but I doubt it'll make a difference!?

@Jaifroid
Copy link
Member Author

Jaifroid commented Jan 8, 2023

I confirm it works on the BrowserStack S22 Ultra, though it takes nearly a minute before the archive is loaded into the WASM. This is probably a BrowserStack storage issue, possibly they mount a network storage or something like that. But it does work: once the WASM is loaded the full-text search results come through quickly. @Inbefortus Thank you -- I now have a solid basis on which to try out different types of detection.

image

@Jaifroid
Copy link
Member Author

Jaifroid commented Jan 8, 2023

OK, it looks like there is some serialization of the archive going on with the way Android passes the File reference into the Web Worker. I've discovered that it does in fact work on my physical Android device, but only with small archives. Even a 31MB archive takes over a minute to load into the WASM on this midrange physical device (whether from microSD card or from Internal storage). Full English Wikipedia doesn't load into the WASM at all (from microSD), or at least after about 20 minutes it had not finished loading, which is as good as useless.

This is a bit problematic, because some kind of copying, at least into memory, appears to be going on, whereas the whole point of using the Emscripten WORKERFS API was that the file did NOT need to be copied or serialized. On a PC, the File reference is simply passed cleanly to the Web Worker without any copying (this is evident, because even the most well specified machines wouldn't be able to copy 92GB into memory or temporary file storage, and it loads pretty instantly).

It also means that there is no real way to detect support on Android other than to let it try and to give up after a certain amount of time, which may vary on different devices and OS types.

So for now, I see no alternative but to leave this as an override setting.

In the future, we should try using WASMFS (see openzim/javascript-libzim#24), to see if it solves this problem. The issue may well be to do with the need to use a Web Worker with WORKERFS,

@Jaifroid
Copy link
Member Author

Jaifroid commented Jan 8, 2023

For technical diagnosis of this issue, I've opened openzim/javascript-libzim#42. Summary is that opening a 92GB archive in our test case, which uses the same WORKERFS Emscripten File System, works perfectly well and instantly on Chromium on Android. So, the extreme slowdown in instantiating archives in javascript-libzim on Android is most likely not an issue with Emscripten, but with the javascript-libzim implementation at some level.

@Jaifroid Jaifroid modified the milestones: Release 2.3.0, Release 2.4.0 Jan 20, 2023
@Jaifroid Jaifroid modified the milestones: Release 2.4.0, Release 2.5.0 Mar 5, 2023
@Jaifroid Jaifroid removed this from the Release 2.5.0 milestone Jun 3, 2023
@Jaifroid Jaifroid added this to the Release 2.6.0 milestone Jun 3, 2023
@Jaifroid Jaifroid modified the milestones: Release 2.6.4, Release 2.7.0 Sep 4, 2023
@Jaifroid Jaifroid modified the milestones: Release 2.7.2, Release 2.8.0 Oct 9, 2023
@Jaifroid Jaifroid modified the milestones: Release 2.8.0, Release 2.9.0 Dec 6, 2023
@Jaifroid Jaifroid modified the milestones: Release 2.9.0, Release 3.0.0 Dec 28, 2023
@Jaifroid Jaifroid modified the milestones: Release 3.0.0, Release 3.1.0 Feb 2, 2024
@Jaifroid
Copy link
Member Author

It is pretty much confirmed that the issue here was speed of access to the archive, due to the multiple "security" layers Google uses to filter access to the File System in modern Android systems. The proof is that on almost any Android, when we have fast access via the Origin Private File System, libzim with ft search works fine even on large archives.

Therefore, while I already enabled libzim full-text search with OPFS, and in view of the fact that Android systems are getting faster, I'm now enabling Android use of libzim for ft search by default. This change has been pushed to main, and will be in the next release.

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

No branches or pull requests

2 participants