Flutter uses a very old NDK (v16 iirc) but thankfully it pulls
down it's Android NDK into third_party/android_tools/ndk. Update
our instructions to explain how to use that ndk when building.
If we don't link against that ndk the arm64 version seems to work
fine, but the arm32 version seems to depend on an extra symbol
which the older ndk does not expose. Linking against the correct
ndk gets rust to do the right thing.
There was a separate change to fix a *second* missing symbol
caused by the ring crate (from rustls, from reqwests) depending
on getauxval, but that we changed by exposing a stub copy
from the flutter engine code for now.
Combined with the fix in the engine:
https://github.com/shorebirdtech/engine/commit/4288ae1125e38a772c6cc8a918ed020c276534a4
This makes it so the updater no longer crashes repeatedly with bad patches. Previously
1. the engine was not successfully reporting a patch bad before crashing (now it does just before crashing).
2. With that fixed, the patch was getting marked bad, but because we were sending the "current" patch to the server, the server would tell us to download a new one every time (which we would not check against our bad patches) and we'd repeatedly boot of a "new" known-bad patch. This is now fixed to both send the latest_installed_patch to the server (as patch_version) as well as refusing to install known bad patches.
3. Fixed the cache to destroy itself on version change (which I expect could hit us when an app upgrades its cache might not get cleared).
4. Also fixed tests being flakey because TempDir cleans up after itself when it goes out of scope (thus needs to be held at the test-lifetime scope rather than inside init_for_testing).
This separates patch download from install, which makes it possible for us to later asynchronously download patches into the downloads spot and then install them on completion.
This also makes marking patches good/bad actually do something and tests that it does something.
We're still quite aways away from actually validating patches and having good/bad be meaningful (for example good/bad are never called by the engine code yet) but this is a step in that direction.
activate_latest_bootable_patch is also only used the "set bad" codepath, and isn't even used when installing patches (those still manually set the current slot).
This also makes it so the slot index is now optional, which makes slightly more sense? And would be needed in the case where you have a single bad patch installed in slot 1, with slot 0 empty/invalid and you resolve to a "None" selected.
Lots more to do here, but this is a start.
This was needed so that it could be called from Dart as well as flutter_main/C++.
It turns out flutter_main does not run on the "ui thread", so when Dart was calling
into the updater it would panic due to thinking the updater (which was using a thread local) was not yet initialized.
Also added the log-panics crate on Android so that panics appear in adb logcat.