Using FIDL proxies with plugins

FFX plugins can communicate with a target device using FIDL through Overnet.

The examples in this doc extend the example code from the plugins page.

First we add a dependency to the plugin’s BUILD.gn file:

  1. import("//src/developer/ffx/build/ffx_plugin.gni")
  2. ffx_plugin("ffx_example") {
  3. version = "0.1.0"
  4. edition = "2018"
  5. with_unit_tests = true
  6. deps = [
  7. "//sdk/fidl/fuchsia.device:fuchsia.device-rustc",
  8. ]
  9. sources = [
  10. "src/args.rs",
  11. "src/lib.rs",
  12. ]
  13. }

This makes the FIDL proxy bindings available for usage in the plugin. In this case you can now import NameProviderProxy.

  1. use {
  2. anyhow::Result,
  3. ffx_core::ffx_plugin,
  4. ffx_example_args::ExampleCommand,
  5. fidl_fuchsia_device::NameProviderProxy,
  6. };

Now that the type is imported, the proxy can be used in the plugin function. FFX plugins can accept proxies in the parameter list:

  1. pub async fn example(
  2. name_proxy: NameProviderProxy,
  3. _cmd: ExampleCommand,
  4. ) -> Result<()> { }

In order to correctly connect a proxy to the FIDL service on the target, you will need to map the proxy type to a component selector that can be used to find the FIDL service. More about component selectors can be found on the Component Select page. This mapping is passed into the ffx_plugin annotation at the top of the function signature:

  1. #[ffx_plugin(
  2. NameProviderProxy = "core/appmgr:out:fuchsia.device.NameProvider"
  3. )]

Putting it all together, your src/lib.rs file should look like:

  1. use {
  2. anyhow::Result,
  3. ffx_core::ffx_plugin,
  4. ffx_example_args::ExampleCommand,
  5. fidl_fuchsia_device::NameProviderProxy,
  6. };
  7. #[ffx_plugin(
  8. NameProviderProxy = "core/appmgr:out:fuchsia.device.NameProvider"
  9. )]
  10. pub async fn example(
  11. name_proxy: NameProviderProxy,
  12. _cmd: ExampleCommand,
  13. ) -> Result<()> {
  14. if let Ok(name) = name_proxy.get_device_name().await? {
  15. println!("Hello, {}", name);
  16. }
  17. Ok(())
  18. }

And that’s it. The plugin should now be able to communicate with target device using native FIDL calls. FFX plugins can accept any number of proxies as long as the same steps are followed and the proxies are correctly mapped to component selectors.

There are two exceptions to this rule. FFX already knows how to communicate with two proxies without mappings. It’s enough to just add these proxies to the parameter list without changing the ffx_plugin annotation: