1use crate::devfs::ControllerAllowlistPassthrough;
6use crate::node_manager::NodeManager;
7use crate::serve::{ComponentControllerClientBinding, NodeControllerServerBinding};
8use crate::shutdown::NodeBridge;
9use crate::types::{DriverState, NodeDictionary, NodeState, NodeTypeVariant};
10use driver_manager_devfs::DevfsDevice;
11use driver_manager_driver_host::DriverHost;
12use driver_manager_shutdown::{NodeRemovalTracker, NodeShutdownCoordinator, RemovalSet};
13use driver_manager_types::{
14 Collection, NodeOffer, OfferTransport, ShutdownState, StartRequestReceiver,
15};
16use fidl_fuchsia_component_sandbox::AggregateSource;
17use flyweights::FlyStr;
18use fuchsia_async::{self as fasync};
19use futures::channel::oneshot;
20use log::{debug, warn};
21use std::cell::RefCell;
22use std::collections::HashMap;
23use std::rc::{Rc, Weak};
24use {
25 fidl_fuchsia_device_fs as fdevfs, fidl_fuchsia_driver_development as fdd,
26 fidl_fuchsia_driver_framework as fdf, fidl_fuchsia_driver_host as fdh,
27};
28
29#[derive(Clone)]
30pub enum NodePropertyValue {
31 IntValue(u32),
32 StringValue(FlyStr),
33 BoolValue(bool),
34 EnumValue(FlyStr),
35}
36
37impl std::convert::From<fdf::NodePropertyValue> for NodePropertyValue {
38 fn from(source: fdf::NodePropertyValue) -> Self {
39 match source {
40 fdf::NodePropertyValue::IntValue(i) => Self::IntValue(i),
41 fdf::NodePropertyValue::StringValue(s) => Self::StringValue(FlyStr::new(s)),
42 fdf::NodePropertyValue::BoolValue(b) => Self::BoolValue(b),
43 fdf::NodePropertyValue::EnumValue(e) => Self::EnumValue(FlyStr::new(e)),
44 _ => unimplemented!(),
45 }
46 }
47}
48
49impl std::convert::From<NodePropertyValue> for fdf::NodePropertyValue {
50 fn from(source: NodePropertyValue) -> fdf::NodePropertyValue {
51 match source {
52 NodePropertyValue::IntValue(i) => fdf::NodePropertyValue::IntValue(i),
53 NodePropertyValue::StringValue(s) => fdf::NodePropertyValue::StringValue(s.to_string()),
54 NodePropertyValue::BoolValue(b) => fdf::NodePropertyValue::BoolValue(b),
55 NodePropertyValue::EnumValue(e) => fdf::NodePropertyValue::EnumValue(e.to_string()),
56 }
57 }
58}
59
60#[derive(Clone)]
61pub struct NodeProperty {
62 pub key: FlyStr,
63 pub value: fdf::NodePropertyValue,
64}
65
66impl std::convert::From<fdf::NodeProperty2> for NodeProperty {
67 fn from(source: fdf::NodeProperty2) -> Self {
68 Self { key: FlyStr::new(source.key), value: source.value }
69 }
70}
71
72impl std::convert::From<NodeProperty> for fdf::NodeProperty2 {
73 fn from(source: NodeProperty) -> fdf::NodeProperty2 {
74 fdf::NodeProperty2 { key: source.key.to_string(), value: source.value }
75 }
76}
77
78#[derive(Clone)]
79pub struct NodePropertyEntry {
80 pub name: String,
81 pub properties: Vec<NodeProperty>,
82}
83
84impl std::convert::From<fdf::NodePropertyEntry2> for NodePropertyEntry {
85 fn from(source: fdf::NodePropertyEntry2) -> Self {
86 Self {
87 name: source.name,
88 properties: source.properties.into_iter().map(|p| p.into()).collect(),
89 }
90 }
91}
92
93impl std::convert::From<NodePropertyEntry> for fdf::NodePropertyEntry2 {
94 fn from(source: NodePropertyEntry) -> fdf::NodePropertyEntry2 {
95 fdf::NodePropertyEntry2 {
96 name: source.name,
97 properties: source.properties.into_iter().map(|p| p.into()).collect(),
98 }
99 }
100}
101
102pub(crate) struct NodeDevfs {
103 pub(crate) device: DevfsDevice,
104 pub(crate) protocol_connector: Option<fdevfs::ConnectorProxy>,
105 pub(crate) controller_allowlist_passthrough: Option<Rc<ControllerAllowlistPassthrough>>,
106}
107
108impl NodeDevfs {
109 pub(crate) fn set_protocol_connector(&mut self, connector: fdevfs::ConnectorProxy) {
110 self.protocol_connector = Some(connector);
111 }
112
113 pub(crate) fn set_controller_allowlist_passthrough(
114 &mut self,
115 passthrough: Rc<ControllerAllowlistPassthrough>,
116 ) {
117 self.controller_allowlist_passthrough = Some(passthrough);
118 }
119
120 pub(crate) fn set_device(&mut self, device: DevfsDevice) {
121 self.device = device;
122 }
123
124 pub(crate) fn device(&self) -> &DevfsDevice {
125 &self.device
126 }
127}
128
129pub(crate) struct NodeShutdown {
130 pub(crate) remove_complete_callback: Option<oneshot::Sender<()>>,
131 pub(crate) unbinding_children_completers: Vec<oneshot::Sender<Result<(), zx::Status>>>,
132 pub(crate) should_destroy_driver_component: bool,
133}
134
135impl NodeShutdown {
136 pub(crate) fn set_remove_complete_callback(&mut self, callback: oneshot::Sender<()>) {
137 self.remove_complete_callback = Some(callback);
138 }
139
140 pub(crate) fn push_unbinding_children_completer(
141 &mut self,
142 completer: oneshot::Sender<Result<(), zx::Status>>,
143 ) {
144 self.unbinding_children_completers.push(completer);
145 }
146
147 pub(crate) fn unbinding_children_completers_len(&self) -> usize {
148 self.unbinding_children_completers.len()
149 }
150
151 pub(crate) fn has_remove_complete_callback(&self) -> bool {
152 self.remove_complete_callback.is_some()
153 }
154
155 pub(crate) fn take_remove_complete_callback(&mut self) -> Option<oneshot::Sender<()>> {
156 self.remove_complete_callback.take()
157 }
158}
159
160pub(crate) struct NodeBinding {
161 pub(crate) node_controller: Option<NodeControllerServerBinding>,
162 pub(crate) pending_bind_completer: Option<oneshot::Sender<Result<(), zx::Status>>>,
163 pub(crate) bind_error: Option<fdf::DriverResult>,
164 pub(crate) wait_for_driver_completer:
165 Option<oneshot::Sender<Result<fdf::DriverResult, zx::Status>>>,
166 pub(crate) restart_driver_url_suffix: Option<String>,
167 pub(crate) composite_rebind_completer: Option<oneshot::Sender<Result<(), zx::Status>>>,
168}
169
170impl NodeBinding {
171 pub(crate) fn on_match_error(&mut self, error: zx::Status) {
172 self.bind_error = Some(fdf::DriverResult::MatchError(error.into_raw()));
173 }
174
175 pub(crate) fn on_start_error(&mut self, error: zx::Status) {
176 self.bind_error = Some(fdf::DriverResult::StartError(error.into_raw()));
177 }
178
179 pub(crate) fn bind_error(&self) -> Option<fdf::DriverResult> {
180 match &self.bind_error {
181 Some(fdf::DriverResult::MatchError(s)) => Some(fdf::DriverResult::MatchError(*s)),
182 Some(fdf::DriverResult::StartError(s)) => Some(fdf::DriverResult::StartError(*s)),
183 _ => None,
184 }
185 }
186
187 pub(crate) fn has_pending_bind_completer(&self) -> bool {
188 self.pending_bind_completer.is_some()
189 }
190
191 pub(crate) fn has_wait_for_driver_completer(&self) -> bool {
192 self.wait_for_driver_completer.is_some()
193 }
194
195 pub(crate) fn node_controller_ref(&self) -> Option<fdf::NodeControllerControlHandle> {
196 self.node_controller.as_ref().map(|c| c.node_controller_ref.clone())
197 }
198}
199
200pub(crate) struct NodeComponent {
201 pub(crate) controller: ComponentControllerClientBinding,
202 pub(crate) start_request_receiver: Option<StartRequestReceiver>,
203 pub(crate) start_handles: Option<Vec<fidl_fuchsia_process::HandleInfo>>,
204}
205
206impl NodeComponent {
207 pub(crate) fn set_start_request_receiver(&mut self, receiver: StartRequestReceiver) {
208 self.start_request_receiver = Some(receiver);
209 }
210
211 pub(crate) fn take_start_request_receiver(&mut self) -> Option<StartRequestReceiver> {
212 self.start_request_receiver.take()
213 }
214}
215
216pub(crate) struct NodeDriverHost {
217 pub(crate) host: Option<Rc<dyn DriverHost>>,
218 pub(crate) name_for_colocation: String,
219 pub(crate) restart_on_crash: bool,
220}
221
222impl NodeDriverHost {
223 pub(crate) fn set_name_for_colocation(&mut self, name: &str) {
224 self.name_for_colocation = name.to_string();
225 }
226
227 pub(crate) fn set_host(&mut self, host: Rc<dyn DriverHost>) {
228 self.host = Some(host);
229 }
230
231 pub(crate) fn host(&self) -> Option<Rc<dyn DriverHost>> {
232 self.host.clone()
233 }
234
235 pub(crate) fn set_restart_on_crash(&mut self, value: bool) {
236 self.restart_on_crash = value;
237 }
238}
239
240pub(crate) struct NodeCore {
241 pub(crate) collection: Collection,
242 pub(crate) driver_package_type: fdf::DriverPackageType,
243 pub(crate) node_type: NodeTypeVariant,
244 pub(crate) children: Vec<Rc<Node>>,
245 pub(crate) properties: Vec<NodePropertyEntry>,
246 pub(crate) symbols: Vec<fdf::NodeSymbol>,
247 pub(crate) offers: Vec<NodeOffer>,
248 pub(crate) bus_info: Option<fdf::BusInfo>,
249 pub(crate) dictionary: NodeDictionary,
250}
251
252impl NodeCore {
253 pub(crate) fn set_subtree_dictionary(
254 &mut self,
255 dictionary: fidl_fuchsia_component_sandbox::CapabilityId,
256 ) {
257 if matches!(self.dictionary, NodeDictionary::Standard(_)) {
258 panic!("Cannot set subtree dictionary on nodes with standard dictionaries");
259 }
260
261 self.dictionary = NodeDictionary::Subtree(dictionary);
262 }
263
264 pub(crate) fn remove_subtree_dictionary(&mut self) {
265 self.dictionary = NodeDictionary::None;
266 }
267
268 pub(crate) fn has_subtree_dictionary(&self) -> bool {
269 matches!(self.dictionary, NodeDictionary::Subtree(_))
270 }
271
272 pub(crate) fn set_collection(&mut self, collection: Collection) {
273 self.collection = collection;
274 }
275
276 pub(crate) fn set_driver_package_type(&mut self, package_type: fdf::DriverPackageType) {
277 self.driver_package_type = package_type;
278 }
279
280 pub(crate) fn is_composite(&self) -> bool {
281 matches!(self.node_type, NodeTypeVariant::Composite { .. })
282 }
283
284 pub(crate) fn dictionary_to_export(
285 &self,
286 ) -> Option<fidl_fuchsia_component_sandbox::CapabilityId> {
287 match self.dictionary {
288 NodeDictionary::None => None,
289 NodeDictionary::Standard(d) => Some(d),
290 NodeDictionary::Subtree(d) => Some(d),
291 }
292 }
293
294 pub(crate) fn take_dictionary_offer_sources(
295 &mut self,
296 ) -> HashMap<String, Vec<AggregateSource>> {
297 let mut sources = HashMap::<String, Vec<AggregateSource>>::new();
298 for dictionary_offer in self.offers.iter_mut() {
299 if !matches!(dictionary_offer.transport, OfferTransport::Dictionary) {
300 continue;
301 }
302
303 if let Some(connector) = dictionary_offer.dir_connector.take() {
304 sources.entry(dictionary_offer.service_name.clone()).or_default().push(
305 AggregateSource {
306 dir_connector: Some(connector),
307 source_instance_filter: Some(
308 dictionary_offer.source_instance_filter.clone(),
309 ),
310 renamed_instances: Some(dictionary_offer.renamed_instances.clone()),
311 ..Default::default()
312 },
313 );
314 }
315 }
316 sources
317 }
318
319 pub(crate) fn set_standard_dictionary(
320 &mut self,
321 dictionary: fidl_fuchsia_component_sandbox::CapabilityId,
322 ) {
323 self.dictionary = NodeDictionary::Standard(dictionary);
324 }
325
326 pub(crate) fn parents(&self) -> Vec<Weak<Node>> {
327 match &self.node_type {
328 NodeTypeVariant::Normal { parent } => vec![parent.clone()],
329 NodeTypeVariant::Composite { parents, .. } => parents.clone(),
330 }
331 }
332
333 pub(crate) fn get_primary_parent(&self) -> Option<Rc<Node>> {
334 match &self.node_type {
335 NodeTypeVariant::Normal { parent } => parent.upgrade(),
336 NodeTypeVariant::Composite { parents, primary_index, .. } => {
337 parents.get(*primary_index as usize).and_then(|p| p.upgrade())
338 }
339 }
340 }
341
342 pub(crate) fn add_child(&mut self, child: Rc<Node>) {
343 self.children.push(child);
344 }
345
346 pub(crate) fn get_node_properties(
347 &self,
348 parent_name: Option<&str>,
349 ) -> Option<Vec<fdf::NodeProperty2>> {
350 let parent_name = parent_name.unwrap_or("default");
351 for entry in self.properties.iter() {
352 if entry.name == parent_name {
353 return Some(entry.properties.clone().into_iter().map(|p| p.into()).collect());
354 }
355 }
356 None
357 }
358
359 pub(crate) fn set_symbols(&mut self, symbols: Vec<fdf::NodeSymbol>) {
360 self.symbols = symbols;
361 }
362
363 pub(crate) fn symbols(&self) -> &Vec<fdf::NodeSymbol> {
364 &self.symbols
365 }
366
367 pub(crate) fn offers(&self) -> &Vec<NodeOffer> {
368 &self.offers
369 }
370
371 pub(crate) fn set_offers(&mut self, offers: Vec<NodeOffer>) {
372 self.offers = offers;
373 }
374
375 pub(crate) fn reserve_offers(&mut self, additional: usize) {
376 self.offers.reserve(additional);
377 }
378
379 pub(crate) fn push_offer(&mut self, offer: NodeOffer) {
380 self.offers.push(offer);
381 }
382
383 pub(crate) fn set_bus_info(&mut self, bus_info: fdf::BusInfo) {
384 self.bus_info = Some(bus_info);
385 }
386
387 pub(crate) fn set_properties(&mut self, properties: Vec<NodePropertyEntry>) {
388 self.properties = properties;
389 }
390
391 pub(crate) fn clear_properties(&mut self) {
392 self.properties.clear();
393 }
394
395 pub(crate) fn push_property(&mut self, property: NodePropertyEntry) {
396 self.properties.push(property);
397 }
398
399 pub(crate) fn dictionary(&self) -> &NodeDictionary {
400 &self.dictionary
401 }
402
403 pub(crate) fn set_dictionary(&mut self, dictionary: NodeDictionary) {
404 self.dictionary = dictionary;
405 }
406
407 pub(crate) fn remove_child_from_children(&mut self, child: &Rc<Node>) -> bool {
408 self.children.retain(|c| !Rc::ptr_eq(c, child));
409 true
410 }
411}
412
413pub struct Node {
414 pub(crate) name: String,
415 pub(crate) node_manager: Box<dyn NodeManager>,
416 pub(crate) core: RefCell<NodeCore>,
417 pub(crate) state: RefCell<NodeState>,
418 pub(crate) devfs: RefCell<NodeDevfs>,
419 pub(crate) shutdown: RefCell<NodeShutdown>,
420 pub(crate) binding: RefCell<NodeBinding>,
421 pub(crate) component: RefCell<Option<NodeComponent>>,
422 pub(crate) driver_host: RefCell<NodeDriverHost>,
423 pub(crate) node_shutdown_coordinator: RefCell<NodeShutdownCoordinator>,
424 pub can_multibind_composites: bool,
425 pub(crate) weak_self: Weak<Self>,
426 pub(crate) scope: fasync::Scope,
427}
428
429impl Drop for Node {
430 fn drop(&mut self) {
431 debug!("Node: '{}' dropped", self.name());
432 }
433}
434
435impl Node {
436 pub fn new(name: &str, parent: Weak<Node>, node_manager: Box<dyn NodeManager>) -> Rc<Self> {
437 let driver_host = parent.upgrade().and_then(|p| p.host());
438 Rc::new_cyclic(|weak_self| {
439 let bridge = Box::new(NodeBridge::new(weak_self.clone()));
440 let enable_test_shutdown_delays = node_manager.is_test_shutdown_delay_enabled();
441 let shutdown_test_rng = node_manager.get_shutdown_test_rng();
442 Self {
443 name: name.to_string(),
444 node_manager,
445 core: RefCell::new(NodeCore {
446 collection: Collection::None,
447 driver_package_type: fdf::DriverPackageType::Base,
448 node_type: NodeTypeVariant::Normal { parent },
449 children: Vec::new(),
450 properties: Vec::new(),
451 symbols: Vec::new(),
452 offers: Vec::new(),
453 bus_info: None,
454 dictionary: NodeDictionary::None,
455 }),
456 state: RefCell::new(NodeState::Unbound),
457 devfs: RefCell::new(NodeDevfs {
458 device: DevfsDevice::new(),
459 protocol_connector: None,
460 controller_allowlist_passthrough: None,
461 }),
462 shutdown: RefCell::new(NodeShutdown {
463 remove_complete_callback: None,
464 unbinding_children_completers: Vec::new(),
465 should_destroy_driver_component: false,
466 }),
467 binding: RefCell::new(NodeBinding {
468 node_controller: None,
469 pending_bind_completer: None,
470 bind_error: None,
471 wait_for_driver_completer: None,
472 restart_driver_url_suffix: None,
473 composite_rebind_completer: None,
474 }),
475 component: RefCell::new(None),
476 driver_host: RefCell::new(NodeDriverHost {
477 host: driver_host,
478 name_for_colocation: String::new(),
479 restart_on_crash: false,
480 }),
481 node_shutdown_coordinator: RefCell::new(NodeShutdownCoordinator::new(
482 bridge,
483 enable_test_shutdown_delays,
484 shutdown_test_rng,
485 )),
486 can_multibind_composites: true,
487 weak_self: weak_self.clone(),
488 scope: fasync::Scope::new_with_name(format!("node:{name}")),
489 }
490 })
491 }
492
493 pub fn name(&self) -> &str {
494 &self.name
495 }
496
497 pub fn token_koid(&self) -> Option<zx::Koid> {
498 match &*self.state.borrow() {
499 NodeState::DriverComponent(driver_component) => Some(driver_component.instance_koid()),
500 _ => None,
501 }
502 }
503
504 pub fn make_topological_path(&self, deduplicate: bool) -> String {
505 let mut names = std::collections::VecDeque::new();
506 let mut current = Some(self.weak_self.upgrade().unwrap());
507 let mut prev_name = String::new();
508 while let Some(node) = current {
509 let name = node.name.clone();
510 if !deduplicate || name != prev_name {
511 names.push_front(name.clone());
512 prev_name = name;
513 }
514 current = node.get_primary_parent();
515 }
516 names.into_iter().collect::<Vec<_>>().join("/")
517 }
518
519 pub fn on_match_error(&self, error: zx::Status) {
520 self.binding.borrow_mut().on_match_error(error);
521 }
522
523 pub fn on_start_error(&self, error: zx::Status) {
524 self.binding.borrow_mut().on_start_error(error);
525 }
526
527 pub fn mark_as_composite_parent(&self) {
528 *self.state.borrow_mut() = NodeState::CompositeParent;
529 }
530
531 pub fn unmark_as_composite_parent(&self) {
532 *self.state.borrow_mut() = NodeState::Unbound;
533 }
534
535 pub(crate) fn is_pending_bind(&self) -> bool {
536 match &*self.state.borrow() {
537 NodeState::DriverComponent(component) => component.state == DriverState::Binding,
538 _ => false,
539 }
540 }
541
542 pub(crate) fn clear_driver_host(&self) {
543 if let NodeState::DriverComponent(ref mut component) = *self.state.borrow_mut() {
544 component.driver_client_binding.take();
545 }
546 }
547
548 pub fn make_component_moniker(&self) -> String {
549 let mut topo_path = self.make_topological_path(true);
550
551 let k_prefix = "dev/sys/platform/pt/";
552 let k_prefix2 = "dev/sys/platform/";
553
554 if topo_path == "dev" {
555 topo_path = "root".to_string();
556 } else if topo_path == "dev/sys/platform/pt" {
557 topo_path = "board".to_string();
558 } else if topo_path.starts_with(k_prefix) {
559 topo_path.replace_range(0..k_prefix.len(), "");
560 } else if topo_path.starts_with(k_prefix2) {
561 topo_path.replace_range(0..k_prefix2.len(), "");
562 }
563
564 topo_path.replace([':', '.'], "_").replace('/', ".")
565 }
566
567 pub fn children(&self) -> Vec<Rc<Node>> {
568 self.core.borrow().children.clone()
569 }
570
571 pub fn parents(&self) -> Vec<Weak<Node>> {
572 self.core.borrow().parents()
573 }
574
575 pub(crate) fn is_root_node(&self) -> bool {
576 self.make_topological_path(false) == "dev"
577 }
578
579 pub fn driver_url(&self) -> String {
580 match &*self.state.borrow() {
581 NodeState::Starting { driver_url } => driver_url.clone(),
582 NodeState::DriverComponent(c) => c.driver_url.clone(),
583 NodeState::Quarantined { driver_url } => driver_url.clone(),
584 NodeState::OwnedByParent { .. } => "owned by parent".to_string(),
585 NodeState::CompositeParent => "owned by composite(s)".to_string(),
586 NodeState::Unbound => "unbound".to_string(),
587 }
588 }
589
590 pub fn is_quarantined(&self) -> bool {
591 matches!(&*self.state.borrow(), NodeState::Quarantined { .. })
592 }
593
594 pub fn get_primary_parent(&self) -> Option<Rc<Node>> {
595 self.core.borrow().get_primary_parent()
596 }
597
598 pub fn get_bus_topology(&self) -> Vec<fdf::BusInfo> {
599 let mut segments = vec![];
600 let mut current = self.weak_self.upgrade();
601 while let Some(node) = current {
602 if let Some(bus_info) = node.core.borrow().bus_info.as_ref() {
603 segments.push(bus_info.clone());
604 }
605 current = node.get_primary_parent();
606 }
607 segments.reverse();
608 segments
609 }
610
611 pub fn get_node_properties(
612 &self,
613 parent_name: Option<&str>,
614 ) -> Option<Vec<fdf::NodeProperty2>> {
615 self.core.borrow().get_node_properties(parent_name)
616 }
617
618 pub(crate) fn add_to_parents(&self) {
619 let this_node = self.weak_self.upgrade().unwrap();
620 for parent in self.parents() {
621 if let Some(p) = parent.upgrade() {
622 p.add_child_to_children(this_node.clone());
623 } else {
624 warn!("Parent freed before child {} could be added to it", self.name());
625 }
626 }
627 }
628
629 pub(crate) fn add_child_to_children(&self, child: Rc<Node>) {
630 self.core.borrow_mut().add_child(child);
631 }
632
633 pub fn driver_host(&self) -> Option<Rc<dyn DriverHost>> {
634 self.driver_host.borrow().host()
635 }
636
637 pub fn is_composite(&self) -> bool {
638 self.core.borrow().is_composite()
639 }
640
641 pub fn is_bound(&self) -> bool {
642 matches!(&*self.state.borrow(), NodeState::DriverComponent { .. })
643 }
644
645 pub fn evaluate_rematch_flags(
646 &self,
647 rematch_flags: fdd::RestartRematchFlags,
648 url: &str,
649 ) -> bool {
650 if self.core.borrow().is_composite()
651 && !rematch_flags.contains(fdd::RestartRematchFlags::COMPOSITE_SPEC)
652 {
653 return false;
654 }
655
656 let driver_url = self.driver_url();
657 if driver_url == url && !rematch_flags.contains(fdd::RestartRematchFlags::REQUESTED) {
658 return false;
659 }
660
661 if driver_url != url && rematch_flags.contains(fdd::RestartRematchFlags::NON_REQUESTED) {
662 return false;
663 }
664
665 true
666 }
667
668 pub fn set_subtree_dictionary(&self, dictionary: fidl_fuchsia_component_sandbox::CapabilityId) {
669 self.core.borrow_mut().set_subtree_dictionary(dictionary);
670 }
671
672 pub fn remove_subtree_dictionary(&self) {
673 self.core.borrow_mut().remove_subtree_dictionary();
674 }
675
676 pub fn has_subtree_dictionary(&self) -> bool {
677 self.core.borrow().has_subtree_dictionary()
678 }
679
680 pub fn skip_injected_offers(&self) -> bool {
681 self.has_subtree_dictionary()
682 }
683
684 pub async fn prepare_dictionary(
685 &self,
686 ) -> Option<fidl_fuchsia_component_sandbox::DictionaryRef> {
687 let dictionary_util = self.node_manager.get_dictionary_util().ok()?;
688
689 let to_export = self.core.borrow().dictionary_to_export();
690
691 if let Some(d) = to_export {
692 return dictionary_util.copy_export_dictionary(d).await.ok();
693 }
694
695 let sources = self.core.borrow_mut().take_dictionary_offer_sources();
696
697 let aggregate_dictionary =
698 dictionary_util.create_aggregate_dictionary(sources).await.ok()?;
699
700 self.core.borrow_mut().set_standard_dictionary(aggregate_dictionary);
701
702 dictionary_util.copy_export_dictionary(aggregate_dictionary).await.ok()
703 }
704
705 pub fn remove(
706 self: &Rc<Self>,
707 removal_set: RemovalSet,
708 removal_tracker: Option<Weak<RefCell<NodeRemovalTracker>>>,
709 ) {
710 NodeShutdownCoordinator::remove(self.clone(), removal_set, removal_tracker);
711 }
712
713 pub(crate) fn get_shutdown_coordinator(
714 &self,
715 ) -> std::cell::RefMut<'_, NodeShutdownCoordinator> {
716 self.node_shutdown_coordinator.borrow_mut()
717 }
718
719 pub fn weak_from_this(&self) -> Weak<Self> {
720 self.weak_self.clone()
721 }
722
723 pub fn collection(&self) -> Collection {
724 self.core.borrow().collection
725 }
726
727 pub fn set_collection(&self, collection: Collection) {
728 self.core.borrow_mut().set_collection(collection);
729 }
730
731 pub fn set_driver_package_type(&self, package_type: fdf::DriverPackageType) {
732 self.core.borrow_mut().set_driver_package_type(package_type);
733 }
734
735 pub fn set_driver_host_name_for_colocation(&self, name: &str) {
736 self.driver_host.borrow_mut().set_name_for_colocation(name);
737 }
738
739 pub fn node_type(&self) -> std::cell::Ref<'_, NodeTypeVariant> {
740 std::cell::Ref::map(self.core.borrow(), |core| &core.node_type)
741 }
742
743 pub(crate) fn set_symbols(&self, symbols: Vec<fdf::NodeSymbol>) {
744 self.core.borrow_mut().set_symbols(symbols);
745 }
746
747 pub fn symbols(&self) -> Vec<fdf::NodeSymbol> {
748 self.core.borrow().symbols().clone()
749 }
750
751 pub fn offers(&self) -> Vec<NodeOffer> {
752 self.core.borrow().offers().clone()
753 }
754
755 pub(crate) fn set_offers(&self, offers: Vec<NodeOffer>) {
756 self.core.borrow_mut().set_offers(offers);
757 }
758
759 pub(crate) fn reserve_offers(&self, additional: usize) {
760 self.core.borrow_mut().reserve_offers(additional);
761 }
762
763 pub(crate) fn push_offer(&self, offer: NodeOffer) {
764 self.core.borrow_mut().push_offer(offer);
765 }
766
767 pub(crate) fn set_bus_info(&self, bus_info: fdf::BusInfo) {
768 self.core.borrow_mut().set_bus_info(bus_info);
769 }
770
771 pub(crate) fn set_properties(&self, properties: Vec<NodePropertyEntry>) {
772 self.core.borrow_mut().set_properties(properties);
773 }
774
775 pub(crate) fn clear_properties(&self) {
776 self.core.borrow_mut().clear_properties();
777 }
778
779 pub(crate) fn push_property(&self, property: NodePropertyEntry) {
780 self.core.borrow_mut().push_property(property);
781 }
782
783 pub(crate) fn dictionary(&self) -> NodeDictionary {
784 self.core.borrow().dictionary().clone()
785 }
786
787 pub(crate) fn set_dictionary(&self, dictionary: NodeDictionary) {
788 self.core.borrow_mut().set_dictionary(dictionary);
789 }
790
791 pub(crate) fn set_node_controller(&self, controller: NodeControllerServerBinding) {
792 self.binding.borrow_mut().node_controller = Some(controller);
793 }
794
795 pub(crate) fn set_pending_bind_completer(
796 &self,
797 completer: oneshot::Sender<Result<(), zx::Status>>,
798 ) {
799 self.binding.borrow_mut().pending_bind_completer = Some(completer);
800 }
801
802 pub(crate) fn take_pending_bind_completer(
803 &self,
804 ) -> Option<oneshot::Sender<Result<(), zx::Status>>> {
805 self.binding.borrow_mut().pending_bind_completer.take()
806 }
807
808 pub(crate) fn set_wait_for_driver_completer(
809 &self,
810 completer: oneshot::Sender<Result<fdf::DriverResult, zx::Status>>,
811 ) {
812 self.binding.borrow_mut().wait_for_driver_completer = Some(completer);
813 }
814
815 pub(crate) fn take_wait_for_driver_completer(
816 &self,
817 ) -> Option<oneshot::Sender<Result<fdf::DriverResult, zx::Status>>> {
818 self.binding.borrow_mut().wait_for_driver_completer.take()
819 }
820
821 pub(crate) fn set_restart_driver_url_suffix(&self, suffix: String) {
822 self.binding.borrow_mut().restart_driver_url_suffix = Some(suffix);
823 }
824
825 pub(crate) fn set_host(&self, host: Rc<dyn DriverHost>) {
826 self.driver_host.borrow_mut().set_host(host);
827 }
828
829 pub(crate) fn host(&self) -> Option<Rc<dyn DriverHost>> {
830 self.driver_host.borrow().host()
831 }
832
833 pub(crate) fn set_restart_on_crash(&self, value: bool) {
834 self.driver_host.borrow_mut().set_restart_on_crash(value);
835 }
836
837 pub(crate) fn set_remove_complete_callback(&self, callback: oneshot::Sender<()>) {
838 self.shutdown.borrow_mut().set_remove_complete_callback(callback);
839 }
840
841 pub(crate) fn push_unbinding_children_completer(
842 &self,
843 completer: oneshot::Sender<Result<(), zx::Status>>,
844 ) {
845 self.shutdown.borrow_mut().push_unbinding_children_completer(completer);
846 }
847
848 pub(crate) fn unbinding_children_completers_len(&self) -> usize {
849 self.shutdown.borrow().unbinding_children_completers_len()
850 }
851
852 pub(crate) fn set_protocol_connector(&self, connector: fdevfs::ConnectorProxy) {
853 self.devfs.borrow_mut().set_protocol_connector(connector);
854 }
855
856 pub(crate) fn set_controller_allowlist_passthrough(
857 &self,
858 passthrough: Rc<ControllerAllowlistPassthrough>,
859 ) {
860 self.devfs.borrow_mut().set_controller_allowlist_passthrough(passthrough);
861 }
862
863 pub(crate) fn set_device(&self, device: DevfsDevice) {
864 self.devfs.borrow_mut().set_device(device);
865 }
866
867 pub(crate) fn device(&self) -> DevfsDevice {
868 self.devfs.borrow().device().clone()
869 }
870
871 pub(crate) fn set_start_request_receiver(&self, receiver: StartRequestReceiver) {
872 if let Some(ref mut component) = *self.component.borrow_mut() {
873 component.set_start_request_receiver(receiver);
874 }
875 }
876
877 pub(crate) fn take_start_request_receiver(&self) -> Option<StartRequestReceiver> {
878 if let Some(ref mut component) = *self.component.borrow_mut() {
879 component.take_start_request_receiver()
880 } else {
881 None
882 }
883 }
884
885 pub(crate) fn set_state(&self, state: NodeState) {
886 *self.state.borrow_mut() = state;
887 }
888
889 pub(crate) fn is_unbound(&self) -> bool {
890 matches!(&*self.state.borrow(), NodeState::Unbound)
891 }
892
893 pub(crate) fn is_running(&self) -> bool {
894 if let NodeState::DriverComponent(ref mut driver_component) = *self.state.borrow_mut() {
895 if driver_component.state == DriverState::Stopped {
896 warn!("completed bind but the driver is already stopped");
897 false
898 } else {
899 driver_component.state = DriverState::Running;
900 true
901 }
902 } else {
903 false
904 }
905 }
906
907 pub fn token_handle(&self) -> Option<zx::Event> {
908 if self.core.borrow().is_composite() {
909 self.core.borrow().children.iter().find_map(|child| {
910 if let NodeState::DriverComponent(driver_component) = &*child.state.borrow()
911 && driver_component.state == DriverState::Running
912 {
913 Some(driver_component.duplicate_instance_handle())
914 } else {
915 None
916 }
917 })
918 } else if let NodeState::DriverComponent(driver_component) = &*self.state.borrow() {
919 if driver_component.state == DriverState::Running {
920 Some(driver_component.duplicate_instance_handle())
921 } else {
922 None
923 }
924 } else {
925 None
926 }
927 }
928
929 pub(crate) fn has_wait_for_driver_completer(&self) -> bool {
930 self.binding.borrow().has_wait_for_driver_completer()
931 }
932
933 pub(crate) fn bind_error(&self) -> Option<fdf::DriverResult> {
934 self.binding.borrow().bind_error()
935 }
936
937 pub(crate) fn has_pending_bind_completer(&self) -> bool {
938 self.binding.borrow().has_pending_bind_completer()
939 }
940
941 pub(crate) fn quarantine_start(&self) -> bool {
942 let mut state = self.state.borrow_mut();
943 match *state {
944 NodeState::DriverComponent(ref mut driver_component) => {
945 driver_component.close_node();
946 driver_component.driver_client_binding.take();
947 }
948 NodeState::Starting { .. } => {}
949 _ => {
950 return false;
951 }
952 }
953 let driver_url = match &*state {
954 NodeState::Starting { driver_url } => driver_url.clone(),
955 NodeState::DriverComponent(c) => c.driver_url.clone(),
956 _ => unreachable!(),
957 };
958 *state = NodeState::Quarantined { driver_url };
959 true
960 }
961
962 pub(crate) fn node_controller_ref(&self) -> Option<fdf::NodeControllerControlHandle> {
963 self.binding.borrow().node_controller_ref()
964 }
965
966 pub(crate) fn take_start_handles_for_start(&self) -> Vec<fidl_fuchsia_process::HandleInfo> {
967 let mut component = self.component.borrow_mut();
968 let component = component.as_mut().expect("component");
969 component
970 .start_handles
971 .take()
972 .expect("handles")
973 .iter()
974 .map(|h| fidl_fuchsia_process::HandleInfo {
975 handle: h.handle.duplicate(zx::Rights::SAME_RIGHTS).expect("duplicate handle"),
976 id: h.id,
977 })
978 .collect::<Vec<_>>()
979 }
980
981 pub(crate) fn shutdown_state(&self) -> ShutdownState {
982 *self.node_shutdown_coordinator.borrow().node_state()
983 }
984
985 pub(crate) fn driver_host_name_for_colocation(&self) -> String {
986 self.driver_host.borrow().name_for_colocation.clone()
987 }
988
989 pub(crate) fn get_node_property_dict(&self) -> fdf::NodePropertyDictionary2 {
990 let core = self.core.borrow();
991 core.properties
992 .iter()
993 .map(|entry| fdf::NodePropertyEntry2 {
994 name: entry.name.clone(),
995 properties: entry.properties.clone().into_iter().map(|p| p.into()).collect(),
996 })
997 .collect()
998 }
999
1000 pub(crate) fn driver_package_type(&self) -> fdf::DriverPackageType {
1001 self.core.borrow().driver_package_type
1002 }
1003
1004 pub fn has_component_controller_proxy(&self) -> bool {
1005 self.component.borrow().is_some()
1006 }
1007
1008 pub(crate) fn protocol_connector(&self) -> Option<fdevfs::ConnectorProxy> {
1009 self.devfs.borrow().protocol_connector.clone()
1010 }
1011
1012 pub(crate) fn controller_allowlist_passthrough(
1013 &self,
1014 ) -> Option<Rc<ControllerAllowlistPassthrough>> {
1015 self.devfs.borrow().controller_allowlist_passthrough.clone()
1016 }
1017
1018 pub(crate) fn set_should_destroy_driver_component(&self, val: bool) {
1019 self.shutdown.borrow_mut().should_destroy_driver_component = val;
1020 }
1021
1022 pub(crate) fn take_component(&self) -> Option<crate::node::NodeComponent> {
1023 self.component.borrow_mut().take()
1024 }
1025
1026 pub(crate) fn set_component(&self, component: crate::node::NodeComponent) {
1027 *self.component.borrow_mut() = Some(component);
1028 }
1029
1030 pub(crate) fn take_node_controller(&self) -> Option<NodeControllerServerBinding> {
1031 self.binding.borrow_mut().node_controller.take()
1032 }
1033
1034 pub(crate) fn finish_shutdown_state(&self) {
1035 match *self.state.borrow_mut() {
1036 NodeState::DriverComponent(ref mut driver_component) => {
1037 driver_component.close_node();
1038 driver_component.driver_client_binding.take();
1039 }
1040 NodeState::OwnedByParent { ref mut node_server_binding } => {
1041 if let Some(binding) = node_server_binding.take() {
1042 binding.close()
1043 }
1044 }
1045 _ => {}
1046 }
1047
1048 self.devfs.borrow_mut().device.topological.take();
1049 self.devfs.borrow_mut().device.protocol.take();
1050 }
1051
1052 pub(crate) fn reset_node_type(&self) {
1053 *self.state.borrow_mut() = NodeState::Unbound;
1054
1055 let mut core = self.core.borrow_mut();
1056 match core.node_type {
1057 NodeTypeVariant::Normal { .. } => {
1058 core.node_type = NodeTypeVariant::Normal { parent: Weak::new() };
1059 }
1060 NodeTypeVariant::Composite { .. } => {
1061 core.node_type = NodeTypeVariant::Composite {
1062 parents: vec![],
1063 parents_names: vec![],
1064 primary_index: 0,
1065 };
1066 }
1067 }
1068 }
1069
1070 pub(crate) fn take_remove_complete_callback(&self) -> Option<oneshot::Sender<()>> {
1071 self.shutdown.borrow_mut().take_remove_complete_callback()
1072 }
1073
1074 pub(crate) fn take_composite_rebind_completer(
1075 &self,
1076 ) -> Option<oneshot::Sender<Result<(), zx::Status>>> {
1077 self.binding.borrow_mut().composite_rebind_completer.take()
1078 }
1079
1080 pub(crate) fn finish_restart_state(&self) {
1081 match *self.state.borrow_mut() {
1082 NodeState::DriverComponent(ref mut driver_component) => {
1083 driver_component.close_node();
1084 driver_component.driver_client_binding.take();
1085 }
1086 NodeState::OwnedByParent { ref mut node_server_binding } => {
1087 if let Some(binding) = node_server_binding.take() {
1088 binding.close()
1089 }
1090 }
1091 _ => {}
1092 }
1093 *self.state.borrow_mut() = NodeState::Unbound;
1094 }
1095
1096 pub(crate) fn host_restart_on_crash(&self) -> bool {
1097 self.driver_host.borrow().restart_on_crash
1098 }
1099
1100 pub(crate) fn take_host(&self) -> Option<Rc<dyn DriverHost>> {
1101 self.driver_host.borrow_mut().host.take()
1102 }
1103
1104 pub(crate) fn take_restart_driver_url_suffix(&self) -> Option<String> {
1105 self.binding.borrow_mut().restart_driver_url_suffix.take()
1106 }
1107
1108 pub fn has_driver(&self) -> bool {
1109 match &*self.state.borrow() {
1110 NodeState::DriverComponent(component) => component.driver_client_binding.is_some(),
1111 _ => false,
1112 }
1113 }
1114
1115 pub fn has_driver_component(&self) -> bool {
1116 match &*self.state.borrow() {
1117 NodeState::DriverComponent(component) => component.state != DriverState::Stopped,
1118 _ => false,
1119 }
1120 }
1121
1122 pub(crate) fn stop_driver_component(&self) {
1123 if self.has_driver_component() {
1124 debug!(
1125 "Node '{}' sending stop through component runner",
1126 self.make_component_moniker()
1127 );
1128 self.send_on_stop();
1129 }
1130 }
1131
1132 pub(crate) fn remove_child_from_children(&self, child: &Rc<Node>) -> bool {
1133 self.core.borrow_mut().remove_child_from_children(child)
1134 }
1135
1136 pub(crate) fn driver_client_binding(&self) -> Option<fdh::DriverProxy> {
1137 match &*self.state.borrow() {
1138 NodeState::DriverComponent(component) => {
1139 component.driver_client_binding.as_ref().map(|b| b.driver_host_proxy.clone())
1140 }
1141 _ => None,
1142 }
1143 }
1144
1145 pub(crate) fn send_on_stop(&self) {
1146 if let NodeState::DriverComponent(ref driver_component) = *self.state.borrow() {
1147 driver_component.send_on_stop();
1148 }
1149 }
1150
1151 pub(crate) fn should_destroy_driver_component(&self) -> bool {
1152 self.shutdown.borrow().should_destroy_driver_component
1153 }
1154
1155 pub(crate) fn has_remove_complete_callback(&self) -> bool {
1156 self.shutdown.borrow().has_remove_complete_callback()
1157 }
1158
1159 pub(crate) fn component_controller_proxy(
1160 &self,
1161 ) -> Option<fidl_fuchsia_component::ControllerProxy> {
1162 self.component
1163 .borrow()
1164 .as_ref()
1165 .map(|c| c.controller.component_controller_proxy.clone())
1166 }
1167
1168 pub(crate) fn set_driver_stopped(&self) {
1169 let mut state = self.state.borrow_mut();
1170 if let NodeState::DriverComponent(ref mut driver_component) = *state {
1171 driver_component.state = DriverState::Stopped;
1172 }
1173 }
1174
1175 pub(crate) fn set_composite_rebind_completer(
1176 &self,
1177 completer: oneshot::Sender<Result<(), zx::Status>>,
1178 ) -> Result<(), oneshot::Sender<Result<(), zx::Status>>> {
1179 let mut binding = self.binding.borrow_mut();
1180 if binding.composite_rebind_completer.is_some() {
1181 return Err(completer);
1182 }
1183 binding.composite_rebind_completer = Some(completer);
1184 Ok(())
1185 }
1186}