carnelian/app/strategies/
flatland.rs1use crate::app::strategies::base::AppStrategy;
6use crate::app::{InternalSender, MessageInternal};
7use crate::view::strategies::base::{FlatlandParams, ViewStrategyParams, ViewStrategyPtr};
8use crate::view::strategies::flatland::FlatlandViewStrategy;
9use crate::view::ViewKey;
10use anyhow::{bail, Context as _, Error};
11use async_trait::async_trait;
12use fidl_fuchsia_ui_app::{CreateView2Args, ViewProviderRequest, ViewProviderRequestStream};
13use fuchsia_async::{self as fasync};
14use fuchsia_component::server::{ServiceFs, ServiceObjLocal};
15use fuchsia_scenic::flatland::ViewCreationTokenPair;
16use futures::channel::mpsc::UnboundedSender;
17use futures::{TryFutureExt, TryStreamExt};
18
19pub(crate) struct FlatlandAppStrategy;
20
21#[async_trait(?Send)]
22impl AppStrategy for FlatlandAppStrategy {
23 async fn create_view_strategy(
24 &mut self,
25 key: ViewKey,
26 app_sender: UnboundedSender<MessageInternal>,
27 strategy_params: ViewStrategyParams,
28 ) -> Result<ViewStrategyPtr, Error> {
29 match strategy_params {
30 ViewStrategyParams::Flatland(flatland_params) => {
31 Ok(FlatlandViewStrategy::new(key, flatland_params, app_sender.clone()).await?)
32 }
33 _ => bail!(
34 "Incorrect ViewStrategyParams passed to create_view_strategy for Scenic (Flatland)"
35 ),
36 }
37 }
38
39 fn create_view_strategy_params_for_additional_view(
40 &mut self,
41 _view_key: ViewKey,
42 ) -> ViewStrategyParams {
43 todo!("Additional views not yet supported on Scenic (Flatland)");
44 }
45
46 fn create_view_for_testing(
47 &self,
48 app_sender: &UnboundedSender<MessageInternal>,
49 ) -> Result<(), Error> {
50 let tokens = ViewCreationTokenPair::new().context("ViewCreationTokenPair::new")?;
51 app_sender
52 .unbounded_send(MessageInternal::CreateView(ViewStrategyParams::Flatland(
53 FlatlandParams {
54 args: CreateView2Args {
55 view_creation_token: Some(tokens.view_creation_token),
56 ..Default::default()
57 },
58 debug_name: Some("Test View".to_string()),
59 },
60 )))
61 .expect("send");
62 Ok(())
63 }
64
65 fn supports_scenic(&self) -> bool {
66 return true;
67 }
68
69 fn start_services<'a, 'b>(
70 &self,
71 app_sender: UnboundedSender<MessageInternal>,
72 fs: &'a mut ServiceFs<ServiceObjLocal<'b, ()>>,
73 ) -> Result<(), Error> {
74 let mut public = fs.dir("svc");
75
76 let sender = app_sender;
77 let f = move |stream: ViewProviderRequestStream| {
78 let sender = sender.clone();
79 fasync::Task::local(
80 stream
81 .try_for_each(move |req| {
82 #[allow(unreachable_patterns)]
83 match req {
84 ViewProviderRequest::CreateView2 { args, .. } => {
85 sender
86 .unbounded_send(MessageInternal::CreateView(
87 ViewStrategyParams::Flatland(FlatlandParams {
88 args,
89 debug_name: Some("Carnelian View".to_string()),
90 }),
91 ))
92 .expect("unbounded_send");
93 }
94
95 _ => {}
96 };
97 futures::future::ready(Ok(()))
98 })
99 .unwrap_or_else(|e| eprintln!("error running ViewProvider server: {:?}", e)),
100 )
101 .detach()
102 };
103 public.add_fidl_service(f);
104
105 Ok(())
106 }
107
108 async fn post_setup(&mut self, _internal_sender: &InternalSender) -> Result<(), Error> {
109 Ok(())
110 }
111}