driver_manager_core/
lib.rs1use driver_manager_node::Node;
6use driver_manager_types::Collection;
7use fidl::endpoints::ClientEnd;
8use futures::channel::{mpsc, oneshot};
9use log::warn;
10use std::collections::{HashSet, VecDeque};
11use std::rc::{Rc, Weak};
12use {fidl_fuchsia_driver_framework as fdf, fidl_fuchsia_ldsvc as fldsvc};
13
14mod bootup_tracker;
15mod driver_host_runner;
16mod driver_runner;
17mod memory_attribution;
18mod offer_injection;
19mod runner;
20#[cfg(test)]
21pub(crate) mod testing;
22mod trait_impls;
23
24pub use driver_runner::*;
25pub use offer_injection::*;
26
27pub(crate) struct DriverRunnerBridge(Weak<DriverRunner>);
30
31pub(crate) type LoaderServiceFactory =
32 mpsc::UnboundedSender<oneshot::Sender<Result<ClientEnd<fldsvc::LoaderMarker>, zx::Status>>>;
33
34pub(crate) async fn perform_bfs<F>(starting_node: Rc<Node>, mut visitor: F)
35where
36 F: AsyncFnMut(&Rc<Node>) -> bool,
37{
38 let mut visited: HashSet<*const Node> = HashSet::new();
39 let mut node_queue = VecDeque::new();
40
41 visited.insert(Rc::as_ptr(&starting_node));
42 node_queue.push_back(starting_node);
43
44 while let Some(current) = node_queue.pop_front() {
45 let visit_children = visitor(¤t).await;
46 if !visit_children {
47 continue;
48 }
49
50 for child in current.children() {
51 let Some(primary_parent) = child.get_primary_parent() else {
52 continue;
53 };
54 if !Rc::ptr_eq(&primary_parent, ¤t) {
55 continue;
56 }
57
58 if visited.insert(Rc::as_ptr(&child)) {
59 node_queue.push_back(child);
60 }
61 }
62 }
63}
64
65pub(crate) fn to_collection(node: &Node, package_type: fdf::DriverPackageType) -> Collection {
66 let collection = to_collection_internal(package_type);
67 get_highest_ranking_collection(node, collection)
68}
69
70fn to_collection_internal(package_type: fdf::DriverPackageType) -> Collection {
71 match package_type {
72 fdf::DriverPackageType::Boot => Collection::Boot,
73 fdf::DriverPackageType::Base => Collection::Package,
74 fdf::DriverPackageType::Cached | fdf::DriverPackageType::Universe => {
75 Collection::FullPackage
76 }
77 _ => Collection::None,
78 }
79}
80
81fn get_highest_ranking_collection(node: &Node, mut collection: Collection) -> Collection {
82 let mut ancestors = std::collections::VecDeque::new();
83 for parent in node.parents() {
84 ancestors.push_back(parent);
85 }
86
87 while let Some(ancestor_weak) = ancestors.pop_front() {
88 if let Some(ancestor) = ancestor_weak.upgrade() {
89 let ancestor_collection = ancestor.collection();
90 if ancestor_collection == Collection::None {
91 for parent in ancestor.parents() {
92 ancestors.push_back(parent);
93 }
94 } else if ancestor_collection > collection {
95 collection = ancestor_collection;
96 }
97 } else {
98 warn!("Ancestor node released");
99 }
100 }
101 collection
102}