This is all for shorebirdtech/shorebird#695 I ended up fixing a lot of things in our Rust code while I was in there, including: * Using PathBuf instead of Sting wherever we are holding onto Path objects (this removed a bunch of code which was converting in and out of these). * Made a variety of functions private (the default) that were previously mistakenly pub. * Moved the android hacks around libapp_paths closer to the C++ code. Previously we were storing all of the libapp_paths on ResolvedConfig and handling the android hacks during patch install. Now we're doing the android path hacks on init, eventually we'll remove them entirely by making the C++ code pass us in the android app_dir or even the resolved .apk we need instead of the libapp_paths. * Fixed several tests to use /dir/lib/arch/libapp.so paths instead of 'libapp.so' now that the init code applies the android hacks an expects the deeper paths. Again, this will go away when we move the android hacks into c++. * Added a test which confirms that if we init twice we log instead of trying to init again (this was one behavior which FCM was triggering as part of fix: ANR when using Firebase Cloud Messaging with Shorebird shorebird#695 * Add a test which confirms that further calls to update while an update is ongoing just fail out quickly instead of hanging. * Moved to serial_test instead of a separate per-thread config system for testing. This makes our tests operate more like the code does in the wild, at the cost of needing to annotate a test as #[serial] any time it needs to use shorebird_init. * Removed ResolvedConfig and now call it UpdateConfig. ResolvedConfig previously had a bool on it to tell if it was initialized, that's now represented as Option instead which is more rusty. * Changed how we handle NetworkHooks from being compile-time test switched to using function pointers held off of UpdateConfig.network_hooks. I think this makes more sense? I did this to remove the special ThreadConfig object which was used during unit tests, but didn't exist in production. I think the way we mock networking could still be improved.
Updater library
This is the Rust side of the Shorebird code push system. This is built
in Rust with a C API for easy calling from other languages, most notably
for linking into libflutter.so.
Parts
dart_cli: Test ffi wrapping of updater library.library: The rust library that does the actual update work.dart_bindings: The Dart bindings for the updater library.
All of the interesting code is in the library directory. There is also
a README.md in that directory explaining the design.
Developing
It's best to edit this repository from within an engine checkout. See BUILDING_ENGINE.md for instructions on how to set up an engine checkout.
The workflow I use involves 2 to 3 VSC windows:
- Opening the engine
src.
In that terminal I:
cd third_party/updater
- To build the updater as part of the engine:
cargo ndk --target aarch64-linux-android build --release && \
ninja -C ../../out/android_release_arm64 && say "done"
The cargo part should not be needed, but I haven't yet done the work to integrate the Rust code into the gn files for the Flutter engine yet.
I add say "done" to the end as linking can take several minutes for release
Android builds.
-
In a second window, I open
code third_party/updater. I do this because otherwise therust_analyzercan't seem to find the rust code. We could fix this by adding the directory to the VSC workspace, but I'm not sure where we would put the workspace file in the first place.srcis actuallyshorebirdtech/buildrootand is controlled viagclientbyshorebirdtech/engine/DEPS. -
In a third window I open my test app. e.g.:
flutter create test_app
cd test_app
shorebird init
shorebird release
code .
- To run the test app with my local engine I use:
shorebird run --local-engine-src-path $HOME/Documents/GitHub/engine/src \
--local-engine android_release_arm64
You may also need to build out/host_release once as flutter build looks for
some Dart .dill files in host_release.
Coverage
We'd like to get to 100% coverage but aren't there yet.
https://github.com/taiki-e/cargo-llvm-cov is the best tool I've found for generating coverage reports.
Install: https://github.com/taiki-e/cargo-llvm-cov#installation
cargo llvm-cov will then generate the report.