1use crate::node::{Node, NodeComponent};
6use driver_manager_shutdown::RemovalSet;
7use driver_manager_types::{ShutdownState, StartRequestReceiver};
8use fidl::endpoints::{ControlHandle, ServerEnd};
9use fuchsia_async::{self as fasync};
10use futures::channel::oneshot;
11use futures::{StreamExt, TryStreamExt};
12use log::{debug, warn};
13use std::rc::Rc;
14use {
15 fidl_fuchsia_component as fcomponent, fidl_fuchsia_component_runner as frunner,
16 fidl_fuchsia_driver_framework as fdf, fidl_fuchsia_driver_host as fdh,
17};
18
19#[derive(Debug)]
20pub struct NodeServerBinding {
21 pub node_ref: fdf::NodeControlHandle,
22 server_task: Option<fasync::Task<()>>,
23 close_listener_task: Option<fasync::Task<()>>,
24}
25
26impl NodeServerBinding {
27 pub fn new(
28 node_ref: fdf::NodeControlHandle,
29 server_task: Option<fasync::Task<()>>,
30 close_listener_task: Option<fasync::Task<()>>,
31 ) -> Self {
32 NodeServerBinding { node_ref, server_task, close_listener_task }
33 }
34
35 pub fn close(self) {
36 self.node_ref.shutdown_with_epitaph(zx::Status::OK);
37 }
38}
39
40impl Drop for NodeServerBinding {
41 fn drop(&mut self) {
42 if let Some(t) = self.close_listener_task.take() {
43 drop(t.abort());
44 }
45
46 if let Some(t) = self.server_task.take() {
47 drop(t.abort());
48 }
49 }
50}
51
52#[derive(Debug)]
53pub struct NodeControllerServerBinding {
54 pub node_controller_ref: fdf::NodeControllerControlHandle,
55 server_task: Option<fasync::Task<()>>,
56 close_listener_task: Option<fasync::Task<()>>,
57}
58
59impl NodeControllerServerBinding {
60 pub fn new(
61 node_controller_ref: fdf::NodeControllerControlHandle,
62 server_task: Option<fasync::Task<()>>,
63 close_listener_task: Option<fasync::Task<()>>,
64 ) -> Self {
65 NodeControllerServerBinding { node_controller_ref, server_task, close_listener_task }
66 }
67
68 pub fn close(self) {
69 self.node_controller_ref.shutdown_with_epitaph(zx::Status::OK);
70 }
71}
72
73impl Drop for NodeControllerServerBinding {
74 fn drop(&mut self) {
75 if let Some(t) = self.close_listener_task.take() {
76 drop(t.abort());
77 }
78
79 if let Some(t) = self.server_task.take() {
80 drop(t.abort());
81 }
82 }
83}
84
85#[derive(Debug)]
86pub struct ComponentRunnerComponentControllerServerBinding {
87 pub control_handle: frunner::ComponentControllerControlHandle,
88 server_task: Option<fasync::Task<()>>,
89 close_listener_task: Option<fasync::Task<()>>,
90}
91
92impl ComponentRunnerComponentControllerServerBinding {
93 pub fn new(
94 control_handle: frunner::ComponentControllerControlHandle,
95 server_task: Option<fasync::Task<()>>,
96 close_listener_task: Option<fasync::Task<()>>,
97 ) -> Self {
98 ComponentRunnerComponentControllerServerBinding {
99 control_handle,
100 server_task,
101 close_listener_task,
102 }
103 }
104}
105
106impl Drop for ComponentRunnerComponentControllerServerBinding {
107 fn drop(&mut self) {
108 if let Some(t) = self.close_listener_task.take() {
109 drop(t.abort());
110 }
111
112 if let Some(t) = self.server_task.take() {
113 drop(t.abort());
114 }
115 }
116}
117
118pub struct ComponentControllerClientBinding {
119 pub component_controller_proxy: fcomponent::ControllerProxy,
120 close_listener_task: Option<fasync::Task<()>>,
121}
122
123impl ComponentControllerClientBinding {
124 pub fn new(
125 component_controller_proxy: fcomponent::ControllerProxy,
126 close_listener_task: Option<fasync::Task<()>>,
127 ) -> Self {
128 ComponentControllerClientBinding { component_controller_proxy, close_listener_task }
129 }
130}
131
132impl Drop for ComponentControllerClientBinding {
133 fn drop(&mut self) {
134 if let Some(t) = self.close_listener_task.take() {
135 drop(t.abort());
136 }
137 }
138}
139
140#[derive(Debug)]
141pub struct DriverHostClientBinding {
142 pub driver_host_proxy: fdh::DriverProxy,
143 close_listener_task: Option<fasync::Task<()>>,
144}
145
146impl DriverHostClientBinding {
147 pub fn new(
148 driver_host_proxy: fdh::DriverProxy,
149 close_listener_task: Option<fasync::Task<()>>,
150 ) -> Self {
151 DriverHostClientBinding { driver_host_proxy, close_listener_task }
152 }
153}
154
155impl Drop for DriverHostClientBinding {
156 fn drop(&mut self) {
157 if let Some(t) = self.close_listener_task.take() {
158 drop(t.abort());
159 }
160 }
161}
162
163impl Node {
164 pub async fn set_created_info(
165 self: &Rc<Self>,
166 proxy: fcomponent::ControllerProxy,
167 handle_info: fidl_fuchsia_process::HandleInfo,
168 receiver: StartRequestReceiver,
169 ) {
170 let self_clone = self.clone();
171
172 let (sender, local_receiver) = oneshot::channel();
173 self.scope.spawn_local(async move {
174 let stream = proxy.take_event_stream();
175 let weak_node = self_clone.weak_from_this();
176 let close_listener_task = Some(fasync::Task::local(async move {
177 stream.for_each(|_| async {}).await;
179 if let Some(node) = weak_node.upgrade() {
180 node.take_component();
181 node.on_component_controller_closed();
182 }
183 }));
184 self_clone.set_component(NodeComponent {
185 controller: ComponentControllerClientBinding::new(proxy, close_listener_task),
186 start_handles: Some(vec![handle_info]),
187 start_request_receiver: Some(receiver),
188 });
189 sender.send(()).unwrap();
190 });
191 local_receiver.await.unwrap();
192 }
193
194 pub(crate) fn serve_node(
195 self: &Rc<Self>,
196 node: ServerEnd<fdf::NodeMarker>,
197 ) -> NodeServerBinding {
198 let (mut stream, control_handle) = node.into_stream_and_control_handle();
199 let control_handle_clone = control_handle.clone();
200 let weak_self = Rc::downgrade(self);
201
202 let close_listener_task = Some(fasync::Task::local(async move {
203 let result = control_handle_clone.on_closed().await;
204 if let Some(this) = weak_self.upgrade() {
205 this.on_node_closed(result);
206 }
207 }));
208
209 let weak_self = Rc::downgrade(self);
210 let server_task = Some(fasync::Task::local(async move {
211 while let Some(Ok(msg)) = stream.next().await {
212 let Some(this) = weak_self.upgrade() else {
213 break;
214 };
215 match msg {
216 fdf::NodeRequest::AddChild { args, controller, node, responder } => {
217 let _ = responder
218 .send(this.add_child(args, Some(controller), node).await.map(|_| ()));
219 }
220 _ => {
221 log::warn!("received unknown method.");
222 }
223 };
224 }
225 }));
226
227 NodeServerBinding::new(control_handle, server_task, close_listener_task)
228 }
229
230 pub(crate) fn serve_node_controller(
231 self: &Rc<Self>,
232 node_controller: ServerEnd<fdf::NodeControllerMarker>,
233 ) -> NodeControllerServerBinding {
234 let (mut stream, control_handle) = node_controller.into_stream_and_control_handle();
235
236 let weak_self = Rc::downgrade(self);
237 let control_handle_clone = control_handle.clone();
238 let close_listener_task = Some(fasync::Task::local(async move {
239 let _ = control_handle_clone.on_closed().await;
240 if let Some(this) = weak_self.upgrade() {
241 this.take_node_controller();
242 }
243 }));
244
245 let weak_self = Rc::downgrade(self);
246 let server_task = Some(fasync::Task::local(async move {
247 while let Some(Ok(msg)) = stream.next().await {
248 let Some(this) = weak_self.upgrade() else {
249 break;
250 };
251 match msg {
252 fdf::NodeControllerRequest::RequestBind { payload, responder } => {
253 let result = this
254 .bind_helper(
255 payload.force_rebind.unwrap_or(false),
256 payload.driver_url_suffix,
257 )
258 .await;
259 let _ = responder.send(result.map_err(zx::Status::into_raw));
260 }
261 fdf::NodeControllerRequest::Remove { .. } => {
262 this.set_should_destroy_driver_component(true);
263 this.remove(RemovalSet::All, None);
264 }
265 fdf::NodeControllerRequest::WaitForDriver { responder } => {
266 let (tx, rx) = oneshot::channel();
267 this.wait_for_driver(tx);
268 this.scope.spawn_local(async move {
269 match rx.await {
270 Ok(result) => {
271 let _ = responder.send(result.map_err(zx::Status::into_raw));
272 }
273 Err(_) => {
274 let _ = responder.send(Err(zx::Status::CANCELED.into_raw()));
275 }
276 }
277 });
278 }
279 _ => {
280 log::warn!("received unknown method.");
281 }
282 };
283 }
284 }));
285
286 NodeControllerServerBinding::new(control_handle, server_task, close_listener_task)
287 }
288
289 pub(crate) fn serve_runner_component_controller(
290 self: &Rc<Self>,
291 runner_component_controller: ServerEnd<frunner::ComponentControllerMarker>,
292 ) -> ComponentRunnerComponentControllerServerBinding {
293 let (controller_stream, control_handle) =
294 runner_component_controller.into_stream_and_control_handle();
295
296 let weak_self = Rc::downgrade(self);
297 let control_handle_clone = control_handle.clone();
298 let close_listener_task = Some(fasync::Task::local(async move {
299 let _ = control_handle_clone.on_closed().await;
300 if let Some(this) = weak_self.upgrade() {
301 this.take_node_controller();
302 this.on_runner_component_controller_closed();
303 }
304 }));
305
306 let weak_self = self.weak_from_this();
307 let server_task = Some(fasync::Task::local(async move {
308 let mut stream: frunner::ComponentControllerRequestStream = controller_stream;
309 while let Ok(Some(s)) = stream.try_next().await {
310 match s {
311 frunner::ComponentControllerRequest::Stop { .. } => {
312 if let Some(node) = weak_self.upgrade() {
313 debug!(
314 "Node: '{}' received stop from component framework",
315 node.make_component_moniker()
316 );
317 node.remove(RemovalSet::All, None);
318 }
319 }
320 frunner::ComponentControllerRequest::Kill { .. } => {
321 if let Some(node) = weak_self.upgrade() {
322 debug!(
323 "Node: '{}' received kill from component framework",
324 node.make_component_moniker()
325 );
326 node.remove(RemovalSet::All, None);
327 }
328 }
329 _ => {}
330 }
331 }
332 }));
333
334 ComponentRunnerComponentControllerServerBinding::new(
335 control_handle,
336 server_task,
337 close_listener_task,
338 )
339 }
340
341 pub(crate) fn serve_driver_host_client(
342 &self,
343 driver_host_proxy: fdh::DriverProxy,
344 ) -> DriverHostClientBinding {
345 let weak_self = self.weak_from_this();
346 let mut driver_event_stream = driver_host_proxy.take_event_stream();
347 let close_listener_task = Some(fasync::Task::local(async move {
348 if let Some(event) = driver_event_stream.next().await {
349 let Err(e) = event;
354 if let fidl::Error::ClientChannelClosed { status, .. } = e
355 && status == zx::Status::OK
356 {
357 } else {
358 warn!("Node: driver channel shutdown with: {e}");
359 }
360 }
361
362 let Some(this) = weak_self.upgrade() else {
363 return;
364 };
365 this.clear_driver_host();
366
367 let moniker = this.make_component_moniker();
368
369 let shutdown_state = this.shutdown_state();
370 if shutdown_state == ShutdownState::WaitingOnDriver {
371 debug!("Node: {moniker}: driver channel had expected shutdown.");
372 this.node_shutdown_coordinator.borrow_mut().check_node_state();
373 return;
374 }
375
376 if this.host_restart_on_crash() {
377 warn!("Restarting node {moniker} because of unexpected driver channel shutdown.");
378 this.restart_node();
379 return;
380 }
381
382 if this.is_pending_bind() {
384 debug!("Node: {moniker}: driver channel closed during binding.");
385 return;
386 }
387
388 warn!("Removing node {moniker} because of unexpected driver channel shutdown.");
389 this.remove(RemovalSet::All, None);
390 }));
391
392 DriverHostClientBinding::new(driver_host_proxy, close_listener_task)
393 }
394
395 fn on_node_closed(self: &Rc<Self>, result: Result<zx::Signals, fidl::Status>) {
396 if self.node_shutdown_coordinator.borrow().is_shutting_down() {
399 return;
400 }
401
402 if self.is_pending_bind() {
404 warn!("The driver for node {} failed to bind.", self.name());
405 return;
406 }
407
408 if self.shutdown_state() == ShutdownState::Running {
409 if self.host_restart_on_crash() {
412 warn!("Restarting node {} due to node closure while running.", self.name());
413 self.restart_node();
414 return;
415 }
416
417 warn!(
418 "fdf::Node binding for node {} closed while the node was running: {:?}",
419 self.name(),
420 result
421 );
422 }
423
424 self.remove(RemovalSet::All, None);
425 }
426
427 fn on_component_controller_closed(self: &Rc<Self>) {
428 if self.node_shutdown_coordinator.borrow().node_state() == &ShutdownState::WaitingOnDestroy
429 {
430 debug!(
431 "Node '{}': component controller channel had expected shutdown.",
432 self.make_component_moniker()
433 );
434 self.node_shutdown_coordinator.borrow_mut().check_node_state();
435 return;
436 }
437
438 warn!(
439 "Node '{}': unexpected component controller channel shutdown. in state {:?}",
440 self.make_component_moniker(),
441 self.node_shutdown_coordinator.borrow().node_state()
442 );
443 }
444
445 fn on_runner_component_controller_closed(self: &Rc<Self>) {
446 let node_state = self.shutdown_state();
447 if self.has_driver_component() {
448 if node_state == ShutdownState::WaitingOnDriverComponent {
449 debug!(
450 "Node '{}': runner component controller channel had expected close",
451 self.make_component_moniker()
452 );
453 self.set_driver_stopped();
454 self.node_shutdown_coordinator.borrow_mut().check_node_state();
455 } else {
456 warn!(
457 "Node '{}': runner component controller channel had unexpected close",
458 self.make_component_moniker()
459 );
460 self.set_driver_stopped();
461 self.remove(RemovalSet::All, None);
462 }
463 }
464 }
465}