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 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}