blob: 467e9e491fcd808d2e9cc8c897a9c621d18bccdb [file] [log] [blame]
// Copyright 2023 The Fuchsia Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
use anyhow::{Context, Error};
use fidl::endpoints::{create_endpoints, ClientEnd, Proxy};
use fidl_fuchsia_developer_tiles::{
ControllerMarker as TilesControllerMarker, ControllerProxy as TilesControllerProxy,
};
use fidl_fuchsia_ui_app::ViewProviderMarker;
use fuchsia_component::client::{connect_channel_to_protocol_at_path, connect_to_protocol};
use serde_json::{json, Value};
use std::cell::RefCell;
use tracing::info;
pub struct FlatlandExampleFacade {
state: RefCell<Option<FacadeState>>,
}
impl std::fmt::Debug for FlatlandExampleFacade {
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
f.debug_struct("FlatlandExampleFacade").finish()
}
}
impl FlatlandExampleFacade {
pub fn new() -> FlatlandExampleFacade {
FlatlandExampleFacade { state: RefCell::new(None) }
}
pub async fn start(&self) -> Result<Value, Error> {
info!("Starting the flatland example app.");
if self.state.borrow().is_none() {
let new_state = FacadeState::start().await.context("starting example app")?;
*self.state.borrow_mut() = Some(new_state);
}
Ok(json!({}))
}
pub async fn stop(&self) -> Result<Value, Error> {
if let Some(old_state) = self.state.borrow_mut().take() {
old_state.stop().await.context("stopping example app")?;
}
Ok(json!({}))
}
}
// TODO(https://fxbug.dev/42059306) switch to session APIs
struct FacadeState {
tiles: TilesControllerProxy,
tile_key: u32,
}
impl FacadeState {
async fn start() -> Result<Self, Error> {
info!("Starting Flatland example.");
let view_provider =
connect_to_protocol::<ViewProviderMarker>().context("connecting to ViewProvider")?;
let view_provider = ClientEnd::from(
view_provider.into_channel().expect("no clones, just created").into_zx_channel(),
);
info!("Adding Flatland example to tiles");
let (tiles_client, tiles_server) = create_endpoints::<TilesControllerMarker>();
connect_channel_to_protocol_at_path(
tiles_server.into_channel(),
"/svc/fuchsia.developer.tiles.Controller.flatland",
)
.context("connecting to tiles.Controller")?;
let tiles = tiles_client.into_proxy().unwrap();
let url = "fuchsia-pkg://fuchsia.com/flatland-examples#meta/flatland-view-provider.cm";
let tile_key = tiles
.add_tile_from_view_provider(url, view_provider)
.await
.context("creating new tile for example")?;
Ok(Self { tiles, tile_key })
}
async fn stop(self) -> Result<(), Error> {
info!("Removing Flatland example from tiles");
self.tiles.remove_tile(self.tile_key).context("removing flatland example tile")?;
Ok(())
}
}