Skip to main content

driver_manager_node/
node.rs

1// Copyright 2026 The Fuchsia Authors. All rights reserved.
2// Use of this source code is governed by a BSD-style license that can be
3// found in the LICENSE file.
4
5use 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 fidl_fuchsia_device_fs as fdevfs;
18use fidl_fuchsia_driver_development as fdd;
19use fidl_fuchsia_driver_framework as fdf;
20use fidl_fuchsia_driver_host as fdh;
21use flyweights::FlyStr;
22use fuchsia_async::{self as fasync};
23use futures::channel::oneshot;
24use log::{debug, warn};
25use std::cell::RefCell;
26use std::collections::HashMap;
27use std::rc::{Rc, Weak};
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 add_child_to_children_for_testing(&self, child: Rc<Node>) {
634        self.add_child_to_children(child);
635    }
636
637    pub fn set_state_for_testing(&self, state: NodeState) {
638        self.set_state(state);
639    }
640
641    pub fn driver_host(&self) -> Option<Rc<dyn DriverHost>> {
642        self.driver_host.borrow().host()
643    }
644
645    pub fn is_composite(&self) -> bool {
646        self.core.borrow().is_composite()
647    }
648
649    pub fn is_bound(&self) -> bool {
650        matches!(&*self.state.borrow(), NodeState::DriverComponent { .. })
651    }
652
653    pub fn is_driver_running(&self) -> bool {
654        if self.shutdown_state() != ShutdownState::Running {
655            return false;
656        }
657        matches!(
658            &*self.state.borrow(),
659            NodeState::DriverComponent(component) if component.state == DriverState::Running
660        )
661    }
662
663    pub fn evaluate_rematch_flags(
664        &self,
665        rematch_flags: fdd::RestartRematchFlags,
666        url: &str,
667    ) -> bool {
668        if self.core.borrow().is_composite()
669            && !rematch_flags.contains(fdd::RestartRematchFlags::COMPOSITE_SPEC)
670        {
671            return false;
672        }
673
674        let driver_url = self.driver_url();
675        if driver_url == url && !rematch_flags.contains(fdd::RestartRematchFlags::REQUESTED) {
676            return false;
677        }
678
679        if driver_url != url && rematch_flags.contains(fdd::RestartRematchFlags::NON_REQUESTED) {
680            return false;
681        }
682
683        true
684    }
685
686    pub fn set_subtree_dictionary(&self, dictionary: fidl_fuchsia_component_sandbox::CapabilityId) {
687        self.core.borrow_mut().set_subtree_dictionary(dictionary);
688    }
689
690    pub fn remove_subtree_dictionary(&self) {
691        self.core.borrow_mut().remove_subtree_dictionary();
692    }
693
694    pub fn has_subtree_dictionary(&self) -> bool {
695        self.core.borrow().has_subtree_dictionary()
696    }
697
698    pub fn skip_injected_offers(&self) -> bool {
699        self.has_subtree_dictionary()
700    }
701
702    pub async fn prepare_dictionary(
703        &self,
704    ) -> Option<fidl_fuchsia_component_sandbox::DictionaryRef> {
705        let dictionary_util = self.node_manager.get_dictionary_util().ok()?;
706
707        let to_export = self.core.borrow().dictionary_to_export();
708
709        if let Some(d) = to_export {
710            return dictionary_util.copy_export_dictionary(d).await.ok();
711        }
712
713        let sources = self.core.borrow_mut().take_dictionary_offer_sources();
714
715        let aggregate_dictionary =
716            dictionary_util.create_aggregate_dictionary(sources).await.ok()?;
717
718        self.core.borrow_mut().set_standard_dictionary(aggregate_dictionary);
719
720        dictionary_util.copy_export_dictionary(aggregate_dictionary).await.ok()
721    }
722
723    pub fn remove(
724        self: &Rc<Self>,
725        removal_set: RemovalSet,
726        removal_tracker: Option<Weak<RefCell<NodeRemovalTracker>>>,
727    ) {
728        NodeShutdownCoordinator::remove(self.clone(), removal_set, removal_tracker);
729    }
730
731    pub(crate) fn get_shutdown_coordinator(
732        &self,
733    ) -> std::cell::RefMut<'_, NodeShutdownCoordinator> {
734        self.node_shutdown_coordinator.borrow_mut()
735    }
736
737    pub fn weak_from_this(&self) -> Weak<Self> {
738        self.weak_self.clone()
739    }
740
741    pub fn collection(&self) -> Collection {
742        self.core.borrow().collection
743    }
744
745    pub fn set_collection(&self, collection: Collection) {
746        self.core.borrow_mut().set_collection(collection);
747    }
748
749    pub fn set_driver_package_type(&self, package_type: fdf::DriverPackageType) {
750        self.core.borrow_mut().set_driver_package_type(package_type);
751    }
752
753    pub fn set_driver_host_name_for_colocation(&self, name: &str) {
754        self.driver_host.borrow_mut().set_name_for_colocation(name);
755    }
756
757    pub fn node_type(&self) -> std::cell::Ref<'_, NodeTypeVariant> {
758        std::cell::Ref::map(self.core.borrow(), |core| &core.node_type)
759    }
760
761    pub(crate) fn set_symbols(&self, symbols: Vec<fdf::NodeSymbol>) {
762        self.core.borrow_mut().set_symbols(symbols);
763    }
764
765    pub fn symbols(&self) -> Vec<fdf::NodeSymbol> {
766        self.core.borrow().symbols().clone()
767    }
768
769    pub fn offers(&self) -> Vec<NodeOffer> {
770        self.core.borrow().offers().clone()
771    }
772
773    pub(crate) fn set_offers(&self, offers: Vec<NodeOffer>) {
774        self.core.borrow_mut().set_offers(offers);
775    }
776
777    pub(crate) fn reserve_offers(&self, additional: usize) {
778        self.core.borrow_mut().reserve_offers(additional);
779    }
780
781    pub(crate) fn push_offer(&self, offer: NodeOffer) {
782        self.core.borrow_mut().push_offer(offer);
783    }
784
785    pub(crate) fn set_bus_info(&self, bus_info: fdf::BusInfo) {
786        self.core.borrow_mut().set_bus_info(bus_info);
787    }
788
789    pub(crate) fn set_properties(&self, properties: Vec<NodePropertyEntry>) {
790        self.core.borrow_mut().set_properties(properties);
791    }
792
793    pub(crate) fn clear_properties(&self) {
794        self.core.borrow_mut().clear_properties();
795    }
796
797    pub(crate) fn push_property(&self, property: NodePropertyEntry) {
798        self.core.borrow_mut().push_property(property);
799    }
800
801    pub(crate) fn dictionary(&self) -> NodeDictionary {
802        self.core.borrow().dictionary().clone()
803    }
804
805    pub(crate) fn set_dictionary(&self, dictionary: NodeDictionary) {
806        self.core.borrow_mut().set_dictionary(dictionary);
807    }
808
809    pub(crate) fn set_node_controller(&self, controller: NodeControllerServerBinding) {
810        self.binding.borrow_mut().node_controller = Some(controller);
811    }
812
813    pub(crate) fn set_pending_bind_completer(
814        &self,
815        completer: oneshot::Sender<Result<(), zx::Status>>,
816    ) {
817        self.binding.borrow_mut().pending_bind_completer = Some(completer);
818    }
819
820    pub(crate) fn take_pending_bind_completer(
821        &self,
822    ) -> Option<oneshot::Sender<Result<(), zx::Status>>> {
823        self.binding.borrow_mut().pending_bind_completer.take()
824    }
825
826    pub(crate) fn set_wait_for_driver_completer(
827        &self,
828        completer: oneshot::Sender<Result<fdf::DriverResult, zx::Status>>,
829    ) {
830        self.binding.borrow_mut().wait_for_driver_completer = Some(completer);
831    }
832
833    pub(crate) fn take_wait_for_driver_completer(
834        &self,
835    ) -> Option<oneshot::Sender<Result<fdf::DriverResult, zx::Status>>> {
836        self.binding.borrow_mut().wait_for_driver_completer.take()
837    }
838
839    pub(crate) fn set_restart_driver_url_suffix(&self, suffix: String) {
840        self.binding.borrow_mut().restart_driver_url_suffix = Some(suffix);
841    }
842
843    pub fn set_host(&self, host: Rc<dyn DriverHost>) {
844        self.driver_host.borrow_mut().set_host(host);
845    }
846
847    pub(crate) fn host(&self) -> Option<Rc<dyn DriverHost>> {
848        self.driver_host.borrow().host()
849    }
850
851    pub(crate) fn set_restart_on_crash(&self, value: bool) {
852        self.driver_host.borrow_mut().set_restart_on_crash(value);
853    }
854
855    pub(crate) fn set_remove_complete_callback(&self, callback: oneshot::Sender<()>) {
856        self.shutdown.borrow_mut().set_remove_complete_callback(callback);
857    }
858
859    pub(crate) fn push_unbinding_children_completer(
860        &self,
861        completer: oneshot::Sender<Result<(), zx::Status>>,
862    ) {
863        self.shutdown.borrow_mut().push_unbinding_children_completer(completer);
864    }
865
866    pub(crate) fn unbinding_children_completers_len(&self) -> usize {
867        self.shutdown.borrow().unbinding_children_completers_len()
868    }
869
870    pub(crate) fn set_protocol_connector(&self, connector: fdevfs::ConnectorProxy) {
871        self.devfs.borrow_mut().set_protocol_connector(connector);
872    }
873
874    pub(crate) fn set_controller_allowlist_passthrough(
875        &self,
876        passthrough: Rc<ControllerAllowlistPassthrough>,
877    ) {
878        self.devfs.borrow_mut().set_controller_allowlist_passthrough(passthrough);
879    }
880
881    pub(crate) fn set_device(&self, device: DevfsDevice) {
882        self.devfs.borrow_mut().set_device(device);
883    }
884
885    pub(crate) fn device(&self) -> DevfsDevice {
886        self.devfs.borrow().device().clone()
887    }
888
889    pub(crate) fn set_start_request_receiver(&self, receiver: StartRequestReceiver) {
890        if let Some(ref mut component) = *self.component.borrow_mut() {
891            component.set_start_request_receiver(receiver);
892        }
893    }
894
895    pub(crate) fn take_start_request_receiver(&self) -> Option<StartRequestReceiver> {
896        if let Some(ref mut component) = *self.component.borrow_mut() {
897            component.take_start_request_receiver()
898        } else {
899            None
900        }
901    }
902
903    pub(crate) fn set_state(&self, state: NodeState) {
904        *self.state.borrow_mut() = state;
905    }
906
907    pub(crate) fn is_unbound(&self) -> bool {
908        matches!(&*self.state.borrow(), NodeState::Unbound)
909    }
910
911    pub(crate) fn is_running(&self) -> bool {
912        if let NodeState::DriverComponent(ref mut driver_component) = *self.state.borrow_mut() {
913            if driver_component.state == DriverState::Stopped {
914                warn!("completed bind but the driver is already stopped");
915                false
916            } else {
917                driver_component.state = DriverState::Running;
918                true
919            }
920        } else {
921            false
922        }
923    }
924
925    pub fn token_handle(&self) -> Option<zx::Event> {
926        if self.core.borrow().is_composite() {
927            self.core.borrow().children.iter().find_map(|child| {
928                if let NodeState::DriverComponent(driver_component) = &*child.state.borrow()
929                    && driver_component.state == DriverState::Running
930                {
931                    Some(driver_component.duplicate_instance_handle())
932                } else {
933                    None
934                }
935            })
936        } else if let NodeState::DriverComponent(driver_component) = &*self.state.borrow() {
937            if driver_component.state == DriverState::Running {
938                Some(driver_component.duplicate_instance_handle())
939            } else {
940                None
941            }
942        } else {
943            None
944        }
945    }
946
947    pub(crate) fn has_wait_for_driver_completer(&self) -> bool {
948        self.binding.borrow().has_wait_for_driver_completer()
949    }
950
951    pub(crate) fn bind_error(&self) -> Option<fdf::DriverResult> {
952        self.binding.borrow().bind_error()
953    }
954
955    pub(crate) fn has_pending_bind_completer(&self) -> bool {
956        self.binding.borrow().has_pending_bind_completer()
957    }
958
959    pub(crate) fn quarantine_start(&self) -> bool {
960        let mut state = self.state.borrow_mut();
961        match *state {
962            NodeState::DriverComponent(ref mut driver_component) => {
963                driver_component.close_node();
964                driver_component.driver_client_binding.take();
965            }
966            NodeState::Starting { .. } => {}
967            _ => {
968                return false;
969            }
970        }
971        let driver_url = match &*state {
972            NodeState::Starting { driver_url } => driver_url.clone(),
973            NodeState::DriverComponent(c) => c.driver_url.clone(),
974            _ => unreachable!(),
975        };
976        *state = NodeState::Quarantined { driver_url };
977        true
978    }
979
980    pub(crate) fn node_controller_ref(&self) -> Option<fdf::NodeControllerControlHandle> {
981        self.binding.borrow().node_controller_ref()
982    }
983
984    pub(crate) fn take_start_handles_for_start(&self) -> Vec<fidl_fuchsia_process::HandleInfo> {
985        let mut component = self.component.borrow_mut();
986        let component = component.as_mut().expect("component");
987        component
988            .start_handles
989            .take()
990            .expect("handles")
991            .iter()
992            .map(|h| fidl_fuchsia_process::HandleInfo {
993                handle: h
994                    .handle
995                    .duplicate_handle(zx::Rights::SAME_RIGHTS)
996                    .expect("duplicate handle"),
997                id: h.id,
998            })
999            .collect::<Vec<_>>()
1000    }
1001
1002    pub(crate) fn shutdown_state(&self) -> ShutdownState {
1003        *self.node_shutdown_coordinator.borrow().node_state()
1004    }
1005
1006    pub(crate) fn driver_host_name_for_colocation(&self) -> String {
1007        self.driver_host.borrow().name_for_colocation.clone()
1008    }
1009
1010    pub(crate) fn get_node_property_dict(&self) -> fdf::NodePropertyDictionary2 {
1011        let core = self.core.borrow();
1012        core.properties
1013            .iter()
1014            .map(|entry| fdf::NodePropertyEntry2 {
1015                name: entry.name.clone(),
1016                properties: entry.properties.clone().into_iter().map(|p| p.into()).collect(),
1017            })
1018            .collect()
1019    }
1020
1021    pub(crate) fn driver_package_type(&self) -> fdf::DriverPackageType {
1022        self.core.borrow().driver_package_type
1023    }
1024
1025    pub fn has_component_controller_proxy(&self) -> bool {
1026        self.component.borrow().is_some()
1027    }
1028
1029    pub(crate) fn protocol_connector(&self) -> Option<fdevfs::ConnectorProxy> {
1030        self.devfs.borrow().protocol_connector.clone()
1031    }
1032
1033    pub(crate) fn controller_allowlist_passthrough(
1034        &self,
1035    ) -> Option<Rc<ControllerAllowlistPassthrough>> {
1036        self.devfs.borrow().controller_allowlist_passthrough.clone()
1037    }
1038
1039    pub(crate) fn set_should_destroy_driver_component(&self, val: bool) {
1040        self.shutdown.borrow_mut().should_destroy_driver_component = val;
1041    }
1042
1043    pub(crate) fn take_component(&self) -> Option<crate::node::NodeComponent> {
1044        self.component.borrow_mut().take()
1045    }
1046
1047    pub(crate) fn set_component(&self, component: crate::node::NodeComponent) {
1048        *self.component.borrow_mut() = Some(component);
1049    }
1050
1051    pub(crate) fn take_node_controller(&self) -> Option<NodeControllerServerBinding> {
1052        self.binding.borrow_mut().node_controller.take()
1053    }
1054
1055    pub(crate) fn finish_shutdown_state(&self) {
1056        match *self.state.borrow_mut() {
1057            NodeState::DriverComponent(ref mut driver_component) => {
1058                driver_component.close_node();
1059                driver_component.driver_client_binding.take();
1060            }
1061            NodeState::OwnedByParent { ref mut node_server_binding } => {
1062                if let Some(binding) = node_server_binding.take() {
1063                    binding.close()
1064                }
1065            }
1066            _ => {}
1067        }
1068
1069        self.devfs.borrow_mut().device.topological.take();
1070        self.devfs.borrow_mut().device.protocol.take();
1071    }
1072
1073    pub(crate) fn reset_node_type(&self) {
1074        *self.state.borrow_mut() = NodeState::Unbound;
1075
1076        let mut core = self.core.borrow_mut();
1077        match core.node_type {
1078            NodeTypeVariant::Normal { .. } => {
1079                core.node_type = NodeTypeVariant::Normal { parent: Weak::new() };
1080            }
1081            NodeTypeVariant::Composite { .. } => {
1082                core.node_type = NodeTypeVariant::Composite {
1083                    parents: vec![],
1084                    parents_names: vec![],
1085                    primary_index: 0,
1086                };
1087            }
1088        }
1089    }
1090
1091    pub(crate) fn take_remove_complete_callback(&self) -> Option<oneshot::Sender<()>> {
1092        self.shutdown.borrow_mut().take_remove_complete_callback()
1093    }
1094
1095    pub(crate) fn take_composite_rebind_completer(
1096        &self,
1097    ) -> Option<oneshot::Sender<Result<(), zx::Status>>> {
1098        self.binding.borrow_mut().composite_rebind_completer.take()
1099    }
1100
1101    pub(crate) fn finish_restart_state(&self) {
1102        match *self.state.borrow_mut() {
1103            NodeState::DriverComponent(ref mut driver_component) => {
1104                driver_component.close_node();
1105                driver_component.driver_client_binding.take();
1106            }
1107            NodeState::OwnedByParent { ref mut node_server_binding } => {
1108                if let Some(binding) = node_server_binding.take() {
1109                    binding.close()
1110                }
1111            }
1112            _ => {}
1113        }
1114        *self.state.borrow_mut() = NodeState::Unbound;
1115    }
1116
1117    pub(crate) fn host_restart_on_crash(&self) -> bool {
1118        self.driver_host.borrow().restart_on_crash
1119    }
1120
1121    pub(crate) fn take_host(&self) -> Option<Rc<dyn DriverHost>> {
1122        self.driver_host.borrow_mut().host.take()
1123    }
1124
1125    pub(crate) fn take_restart_driver_url_suffix(&self) -> Option<String> {
1126        self.binding.borrow_mut().restart_driver_url_suffix.take()
1127    }
1128
1129    pub fn has_driver(&self) -> bool {
1130        match &*self.state.borrow() {
1131            NodeState::DriverComponent(component) => component.driver_client_binding.is_some(),
1132            _ => false,
1133        }
1134    }
1135
1136    pub fn has_driver_component(&self) -> bool {
1137        match &*self.state.borrow() {
1138            NodeState::DriverComponent(component) => component.state != DriverState::Stopped,
1139            _ => false,
1140        }
1141    }
1142
1143    pub(crate) fn stop_driver_component(&self) {
1144        if self.has_driver_component() {
1145            debug!(
1146                "Node '{}' sending stop through component runner",
1147                self.make_component_moniker()
1148            );
1149            self.send_on_stop();
1150        }
1151    }
1152
1153    pub(crate) fn remove_child_from_children(&self, child: &Rc<Node>) -> bool {
1154        self.core.borrow_mut().remove_child_from_children(child)
1155    }
1156
1157    pub(crate) fn driver_client_binding(&self) -> Option<fdh::DriverProxy> {
1158        match &*self.state.borrow() {
1159            NodeState::DriverComponent(component) => {
1160                component.driver_client_binding.as_ref().map(|b| b.driver_host_proxy.clone())
1161            }
1162            _ => None,
1163        }
1164    }
1165
1166    pub(crate) fn send_on_stop(&self) {
1167        if let NodeState::DriverComponent(ref driver_component) = *self.state.borrow() {
1168            driver_component.send_on_stop();
1169        }
1170    }
1171
1172    pub(crate) fn should_destroy_driver_component(&self) -> bool {
1173        self.shutdown.borrow().should_destroy_driver_component
1174    }
1175
1176    pub(crate) fn has_remove_complete_callback(&self) -> bool {
1177        self.shutdown.borrow().has_remove_complete_callback()
1178    }
1179
1180    pub(crate) fn component_controller_proxy(
1181        &self,
1182    ) -> Option<fidl_fuchsia_component::ControllerProxy> {
1183        self.component.borrow().as_ref().map(|c| c.controller.component_controller_proxy.clone())
1184    }
1185
1186    pub(crate) fn set_driver_stopped(&self) {
1187        let mut state = self.state.borrow_mut();
1188        if let NodeState::DriverComponent(ref mut driver_component) = *state {
1189            driver_component.state = DriverState::Stopped;
1190        }
1191    }
1192
1193    pub(crate) fn set_composite_rebind_completer(
1194        &self,
1195        completer: oneshot::Sender<Result<(), zx::Status>>,
1196    ) -> Result<(), oneshot::Sender<Result<(), zx::Status>>> {
1197        let mut binding = self.binding.borrow_mut();
1198        if binding.composite_rebind_completer.is_some() {
1199            return Err(completer);
1200        }
1201        binding.composite_rebind_completer = Some(completer);
1202        Ok(())
1203    }
1204}