blob: a3e15cd3d09f3749157ec18fbaa91e7ce0214300 [file] [view] [edit]
# Session roles and responsibilities, by example
The session component encapsulate a product experience, within a component
topology. It launches all of the product-specific components (directly or
indirectly), manages the lifecycle of those components, and manages the flow of
control and information between the product-specific components (such as
user-facing apps) and device-specific components (such as input devices, audio,
and a display, if any).
The following sections demonstrate how a session author might implement some of
these responsibilities.
## Presenting an element's view {#presenting-an-elements-view}
In the following example, a session forwards an `[Elements](/docs/glossary/README.md#element)` view to a
`[GraphicalPresenter](/docs/glossary/README.md#graphicalpresenter)`,
by calling `PresentView()` with a
`[ViewSpec](/docs/glossary/README.md#viewspec)`. The
`ViewSpec` includes the duplicated `[ViewRef](/docs/glossary/README.md#ViewRef)` \(a sharable handle to the
`Element`'s View), and an optional set of initial, product-specific
`[Annotations](/docs/glossary/README.md#element-annotation)`.
The component that implements the Graphical Presenter role knows how to open
the view on a connected display.
```rust
fn present_view_for_element(
graphical_presenter: &GraphicalPresenterProxy,
element: &Element
) -> Result<ViewControllerProxy, Error> {
let view_provider = element.connect_to_service::<ViewProviderMarker>()?;
let token_pair = scenic::ViewTokenPair::new()?;
let scenic::ViewRefPair {
mut control_ref,
mut view_ref
} = scenic::ViewRefPair::new()?;
let view_ref_dup = fuchsia_scenic::duplicate_view_ref(&view_ref)?;
view_provider.create_view_with_view_ref(
token_pair.view_token.value,
&mut control_ref,
&mut view_ref,
)?;
let annotations = element.get_annotations()?;
let view_spec = ViewSpec {
view_holder_token: Some(token_pair.view_holder_token),
view_ref: Some(view_ref_dup),
annotations: Some(annotations),
..ViewSpec::EMPTY
};
let (view_controller_proxy, server_end) = create_proxy::<ViewControllerMarker>()?;
graphical_presenter.present_view(view_spec, Some(server_end))?;
Ok(view_controller_proxy)
}
```
## Handling input {#handling-input}
In the following example, if the `MouseHandler` detects a mouse-typed input
event, the handler sends the event to Scenic and returns an empty vector. On all
other types of input events, the `MouseHandler` returns a vector containing the
`[InputEvent](/docs/glossary/README.md#InputEvent)` for the next
`[InputHandler](/docs/glossary/README.md#InputHandler)` to process.
```rust
#[async_trait]
impl InputHandler for MouseHandler {
async fn handle_input_event(
&mut self,
input_event: InputEvent,
) -> Vec<InputEvent> {
match input_event {
InputEvent {
device_event: InputDeviceEvent::Mouse(mouse_event),
device_descriptor: InputDeviceDescriptor::Mouse(mouse_descriptor),
} => {
// ... Handler specific details
self.send_events_to_scenic(...)).await;
vec![] // InputEvent is consumed because it was sent to Scenic
}
_ => vec![input_event], // InputEvent is returned for the next InputHanlder
}
}
}
```