| # How a Flutter component works |
| |
| For a very detailed overview of Flutter architecture on all platforms, |
| see [this doc](https://docs.flutter.dev/resources/architectural-overview). |
| |
| A Flutter component for Fuchsia is an [ELF binary](https://en.wikipedia.org/wiki/Executable_and_Linkable_Format) |
| that is built and run using Fuchsia's [Bazel SDK](https://fuchsia.dev/fuchsia-src/contribute/governance/rfcs/0139_bazel_sdk). |
| The component is launched by |
| [Fuchsia's ELF runner](https://fuchsia.dev/fuchsia-src/concepts/components/v2/elf_runner) |
| (there is no longer a separate Flutter runner or Dart runner). |
| |
| Building and running an example Flutter component is done by: |
| |
| 1. Compiling the Flutter application to get a folder of compiled assets |
| ([snapshot](https://mrale.ph/dartvm/#how-does-dart-vm-run-your-code), fonts, images). |
| |
| This is currently done with the Flutter CLI using `flutter build bundle`. |
| This only supports JIT compilation. To support AOT compilation, we should switch to |
| using the Dart SDK's tools instead (see |
| [this doc](https://github.com/flutter/flutter/wiki/Custom-Flutter-Engine-Embedding-in-AOT-Mode#the-hard-way) |
| for reference). |
| |
| 2. [Packaging](https://fuchsia.dev/fuchsia-src/concepts/packages/package) |
| these assets together with the embedder executable and shared libraries. |
| See [_"Package layout"_](#package-layout) for details. |
| |
| 3. Running the embedder executable with the ELF runner. This is handled |
| by the Bazel SDK. |
| |
| We pass the path to the compiled assets as an argument |
| [here](https://fuchsia.googlesource.com/flutter-embedder/+/refs/heads/main/src/embedder/meta/embedder.cml#18). |
| |
| Running the application using the assets is handled by `libflutter_engine.so`, |
| a shared library from the [Flutter Engine repository](https://github.com/flutter/engine). |
| We interact with `libflutter_engine.so` using |
| [`embedder.h`](https://fuchsia.googlesource.com/flutter-embedder/+/refs/heads/main/src/embedder/engine/embedder.h). |
| |
|  |
| |
| ## Package layout |
| |
| The compiled Flutter component's package has three main folders: |
| |
| - **`bin/embedder`**: The executable. |
| |
| - **`data/flutter_assets/`**: The compiled assets of the Flutter app that should |
| be run by the executable. |
| |
| - **`lib/`**: Shared libraries that are used by `bin/embedder`. |
| |
| Notably, `lib/libflutter_engine.so` is the Flutter Engine code that |
| `bin/embedder` uses to run the Flutter app. |
| |
| When building and running a Flutter example, the full package contents are printed |
| for debugging. |
| |
| ## Threading model |
| |
| The easiest way to understand how threading works in Flutter |
| is to |
| [attach a debugger in VS Code](https://fuchsia.googlesource.com/flutter-embedder/+/refs/heads/main/docs/debugging.md#attaching-a-debugger-from-vscode) |
| and break on a function that you're interested in. VS Code will tell |
| you what thread the code is running on. |
| |
|  |
| |
| Some notable threads: |
| |
| - Platform thread (`initial-thread`): The thread that `main()` runs on. |
| |
| - We connect to all |
| [FIDL services](https://fuchsia.dev/fuchsia-src/concepts/fidl/overview) |
| on this thread and |
| [platform messages](https://docs.flutter.dev/development/platform-integration/platform-channels) |
| are sent on this thread. |
| |
| - Async requests and responses to FIDL services are handled by an async loop that is started by `FlutterEngineRun`. |
| |
| - Raster thread (`io.flutter.raster`): Handles rendering logic for Flutter. |
| |
| - Callbacks for rendering are called on this thread. |