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.