Note: This document covers API impact only. For more details, see the ABI compatibility page

Add a protocol event

Overview

-initstep 1step 2step 3step 4
fidllinklinklink
dartlinklink
golinklink
hlcpplinklink
llcpplinklink
rustlinklinklink

Initial State

FIDL

protocol Example {
    -> OnExistingEvent();
};

Dart

class Server extends fidllib.Example {
  final _onExistingEventStreamController = StreamController<void>();

  @override
  Stream<void> get onExistingEvent => _onExistingEventStreamController.stream;
}

void expectEvents(fidllib.ExampleProxy client) async {
  await client.onExistingEvent.first;
}

Go

func expectEvents(c *lib.ExampleWithCtxInterface) {
	_ = c.ExpectOnExistingEvent(context.Background())
}

func sendEvents(p *lib.ExampleEventProxy) {
	_ = p.OnExistingEvent()
}

HLCPP

void expectEvents(fidl_test::ExamplePtr* client) {
  client->events().OnExistingEvent = []() {};
}

void sendEvents(fidl::Binding<fidl_test::Example>* server) { server->events().OnExistingEvent(); }

LLCPP

class AsyncEventHandler : public fidl::WireAsyncEventHandler<fidl_test::Example> {
  void OnExistingEvent(fidl::WireResponse<fidl_test::Example::OnExistingEvent>* event) override {}
};

class SyncEventHandler : public fidl::WireSyncEventHandler<fidl_test::Example> {
  void OnExistingEvent(fidl::WireResponse<fidl_test::Example::OnExistingEvent>* event) override {}
};

void sendEvents(fidl::ServerBindingRef<fidl_test::Example> server) { server->OnExistingEvent(); }

Rust

fn send_events(stream: fidl_lib::ExampleRequestStream) -> Result<(), fidl::Error> {
    let control_handle = stream.control_handle();
    control_handle.send_on_existing_event()?;
    Ok(())
}

async fn receive_events(client: fidl_lib::ExampleProxy) -> Result<(), fidl::Error> {
    let mut event_stream = client.take_event_stream();
    while let Some(event) = event_stream.try_next().await? {
        match event {
            fidl_lib::ExampleEvent::OnExistingEvent { .. } => {}
        }
    }
    Ok(())
}

Update Source Code

Rust

  • Add #[allow(unreachable_patterns)] and a catch-all arm (_) to any client event stream match statements
  fn send_events(stream: fidl_lib::ExampleRequestStream) -> Result<(), fidl::Error> {
      let control_handle = stream.control_handle();
      control_handle.send_on_existing_event()?;
      Ok(())
  }
  
  async fn receive_events(client: fidl_lib::ExampleProxy) -> Result<(), fidl::Error> {
      let mut event_stream = client.take_event_stream();
      while let Some(event) = event_stream.try_next().await? {
+         #[allow(unreachable_patterns)]
          match event {
              fidl_lib::ExampleEvent::OnExistingEvent { .. } => {}
+             _ => {}
          }
      }
      Ok(())
  }

Update FIDL Library

  • Add the new event and mark it with the [Transitional] attribute.
  protocol Example {
      -> OnExistingEvent();
+     @transitional
+     -> OnNewEvent();
  };

Update Source Code

Dart

  • Implement the stream for the new event for any server implementations.
  • You can start receiving the new event in any clients.
  class Server extends fidllib.Example {
    final _onExistingEventStreamController = StreamController<void>();
+   final _onNewEventStreamController = StreamController<void>();
  
    @override
    Stream<void> get onExistingEvent => _onExistingEventStreamController.stream;
+ 
+   @override
+   Stream<void> get onNewEvent => _onNewEventStreamController.stream;
  }
  
  void expectEvents(fidllib.ExampleProxy client) async {
    await client.onExistingEvent.first;
+   await client.onNewEvent.first;
  }

Go

  • You can start using the new event on both the client and server side.
  func expectEvents(c *lib.ExampleWithCtxInterface) {
  	_ = c.ExpectOnExistingEvent(context.Background())
+ 	_ = c.ExpectOnNewEvent(context.Background())
  }
  
  func sendEvents(p *lib.ExampleEventProxy) {
  	_ = p.OnExistingEvent()
+ 	_ = p.OnNewEvent()
  }
  

HLCPP

  • You can start using the new event on both the client and server side.
  void expectEvents(fidl_test::ExamplePtr* client) {
    client->events().OnExistingEvent = []() {};
+   client->events().OnNewEvent = []() {};
  }
  
- void sendEvents(fidl::Binding<fidl_test::Example>* server) { server->events().OnExistingEvent(); }
+ void sendEvents(fidl::Binding<fidl_test::Example>* server) {
+   server->events().OnExistingEvent();
+   server->events().OnNewEvent();
+ }
  

LLCPP

  • For usages of the async event handle struct, add a handler for the new event if desired.
  • For usages of the async event handler class, you must add a handle for the new event.
  • You can start receiving the new event in any clients.
  class AsyncEventHandler : public fidl::WireAsyncEventHandler<fidl_test::Example> {
    void OnExistingEvent(fidl::WireResponse<fidl_test::Example::OnExistingEvent>* event) override {}
+   void OnNewEvent(fidl::WireResponse<fidl_test::Example::OnNewEvent>* event) override {}
  };
  
  class SyncEventHandler : public fidl::WireSyncEventHandler<fidl_test::Example> {
    void OnExistingEvent(fidl::WireResponse<fidl_test::Example::OnExistingEvent>* event) override {}
+   void OnNewEvent(fidl::WireResponse<fidl_test::Example::OnNewEvent>* event) override {}
  };
  
- void sendEvents(fidl::ServerBindingRef<fidl_test::Example> server) { server->OnExistingEvent(); }
+ void sendEvents(fidl::ServerBindingRef<fidl_test::Example> server) {
+   server->OnExistingEvent();
+   server->OnNewEvent();
+ }

Rust

  • Remove the #[allow(unreachable_patterns)] attribute and replace the catch-all arm with the new event.
  • You can start sending the new event in any servers.
  fn send_events(stream: fidl_lib::ExampleRequestStream) -> Result<(), fidl::Error> {
      let control_handle = stream.control_handle();
      control_handle.send_on_existing_event()?;
+     control_handle.send_on_new_event()?;
      Ok(())
  }
  
  async fn receive_events(client: fidl_lib::ExampleProxy) -> Result<(), fidl::Error> {
      let mut event_stream = client.take_event_stream();
      while let Some(event) = event_stream.try_next().await? {
-         #[allow(unreachable_patterns)]
          match event {
              fidl_lib::ExampleEvent::OnExistingEvent { .. } => {}
-             _ => {}
+             fidl_lib::ExampleEvent::OnNewEvent { .. } => {}
          }
      }
      Ok(())
  }

Update FIDL Library

  • Remove the [Transitional] attribute.
  protocol Example {
      -> OnExistingEvent();
-     @transitional
      -> OnNewEvent();
  };