driver_manager_core/
trait_impls.rs1use crate::{DriverRunner, DriverRunnerBridge};
6use async_trait::async_trait;
7use driver_manager_bind::{BindManagerBridge, BindSpecResult};
8use driver_manager_composite::CompositeManagerBridge;
9use driver_manager_driver_host::DriverHost;
10use driver_manager_node::{Node, NodeManager};
11use driver_manager_shutdown::{NodeRemover, RemovalSet};
12use driver_manager_types::BindResultTracker;
13use driver_manager_utils::DictionaryUtil;
14use fidl::endpoints::DiscoverableProtocolMarker;
15use futures::channel::oneshot;
16use log::info;
17use rand::rngs::StdRng;
18use std::cell::RefCell;
19use std::rc::{Rc, Weak};
20use {fidl_fuchsia_driver_framework as fdf, fidl_fuchsia_driver_index as fdi};
21
22#[async_trait(?Send)]
23impl NodeRemover for DriverRunner {
24 async fn shutdown_all_drivers(&self) {
25 info!("Driver Runner invokes shutdown all drivers");
26 let (tx, rx) = oneshot::channel();
27 self.removal_tracker.borrow_mut().set_all_callback(tx);
28 self.root_node.remove(RemovalSet::All, Some(Rc::downgrade(&self.removal_tracker)));
29 self.removal_tracker.borrow_mut().finish_enumeration(Rc::downgrade(&self.removal_tracker));
30 let _ = rx.await;
31 }
32
33 async fn shutdown_pkg_drivers(&self) {
34 let (tx, rx) = oneshot::channel();
35 self.removal_tracker.borrow_mut().set_pkg_callback(tx);
36 self.root_node.remove(RemovalSet::Package, Some(Rc::downgrade(&self.removal_tracker)));
37 self.removal_tracker.borrow_mut().finish_enumeration(Rc::downgrade(&self.removal_tracker));
38 let _ = rx.await;
39 }
40
41 fn set_on_removal_timeout_callback(&self, callback: Box<dyn Fn()>) {
42 self.removal_tracker.borrow_mut().set_on_removal_timeout_callback(callback);
43 }
44}
45
46#[async_trait(?Send)]
47impl NodeManager for DriverRunnerBridge {
48 fn clone_box(&self) -> Box<dyn NodeManager> {
49 Box::new(DriverRunnerBridge(self.0.clone()))
50 }
51
52 fn bind(&self, node: &Rc<Node>, tracker: Rc<RefCell<BindResultTracker>>) {
53 if let Some(runner) = self.0.upgrade() {
54 runner.bind_manager.bind(node, "", tracker);
55 }
56 }
57
58 fn bind_to_url(
59 &self,
60 node: &Rc<Node>,
61 driver_url_suffix: &str,
62 tracker: Rc<RefCell<BindResultTracker>>,
63 ) {
64 if let Some(runner) = self.0.upgrade() {
65 runner.bind_manager.bind(node, driver_url_suffix, tracker);
66 }
67 }
68
69 fn start_driver(
70 &self,
71 node: &Rc<Node>,
72 url: &str,
73 package_type: fdf::DriverPackageType,
74 ) -> Result<(), zx::Status> {
75 if let Some(runner) = self.0.upgrade() {
76 let node_clone = node.clone();
77 let url_clone = url.to_string();
78 let runner_clone = runner.clone();
79
80 runner.scope.spawn_local(async move {
83 let _ = runner_clone.start_driver(&node_clone, &url_clone, package_type).await;
84 });
85 Ok(())
86 } else {
87 Err(zx::Status::UNAVAILABLE)
88 }
89 }
90
91 fn get_driver_host(&self, driver_host_name_for_colocation: &str) -> Option<Rc<dyn DriverHost>> {
92 let runner = self.0.upgrade()?;
93 runner.get_driver_host(driver_host_name_for_colocation)
94 }
95
96 async fn create_driver_host(
97 &self,
98 use_next_vdso: bool,
99 driver_host_name_for_colocation: String,
100 ) -> Result<Rc<dyn DriverHost>, zx::Status> {
101 if let Some(runner) = self.0.upgrade() {
102 runner.create_driver_host(use_next_vdso, driver_host_name_for_colocation).await
103 } else {
104 Err(zx::Status::UNAVAILABLE)
105 }
106 }
107
108 async fn create_driver_host_dynamic_linker(
109 &self,
110 driver_host_name_for_colocation: String,
111 ) -> Result<Rc<dyn DriverHost>, zx::Status> {
112 if let Some(runner) = self.0.upgrade() {
113 runner.create_driver_host_dynamic_linker(driver_host_name_for_colocation).await
114 } else {
115 Err(zx::Status::UNAVAILABLE)
116 }
117 }
118
119 fn is_test_shutdown_delay_enabled(&self) -> bool {
120 if let Some(runner) = self.0.upgrade() { runner.enable_test_shutdown_delays } else { false }
121 }
122
123 fn get_shutdown_test_rng(&self) -> Weak<RefCell<StdRng>> {
124 if let Some(runner) = self.0.upgrade() {
125 Rc::downgrade(&runner.shutdown_test_rng)
126 } else {
127 Weak::new()
128 }
129 }
130
131 async fn wait_for_bootup(&self) {
132 if let Some(runner) = self.0.upgrade() {
133 runner.bootup_tracker.wait_for_bootup().await;
134 }
135 }
136
137 fn get_dictionary_util(&self) -> Result<Rc<DictionaryUtil>, zx::Status> {
138 if let Some(runner) = self.0.upgrade() {
139 Ok(runner.dictionary_util.clone())
140 } else {
141 Err(zx::Status::UNAVAILABLE)
142 }
143 }
144
145 fn memory_attributor(&self) -> Option<Rc<dyn driver_manager_node::MemoryAttributor>> {
146 let runner = self.0.upgrade()?;
147 Some(runner.memory_attributor.clone())
148 }
149}
150
151#[async_trait(?Send)]
152impl BindManagerBridge for DriverRunnerBridge {
153 fn box_clone(&self) -> Box<dyn BindManagerBridge> {
154 Box::new(Self(self.0.clone()))
155 }
156
157 fn on_binding_state_changed(&self) {
158 if let Some(runner) = self.0.upgrade() {
159 runner.bootup_tracker.notify_binding_changed();
160 }
161 }
162
163 async fn request_match_from_driver_index(
164 &self,
165 args: fidl_fuchsia_driver_index::MatchDriverArgs,
166 ) -> fidl::Result<fdi::MatchDriverResult> {
167 if let Some(runner) = self.0.upgrade() {
168 match runner.driver_index.match_driver(&args).await {
169 Ok(Ok(result)) => Ok(result),
170 Ok(Err(e)) => Err(fidl::Error::ClientChannelClosed {
171 status: zx::Status::from_raw(e),
172 protocol_name: fdi::DriverIndexMarker::PROTOCOL_NAME,
173 epitaph: None,
174 }),
175 Err(e) => Err(e),
176 }
177 } else {
178 Err(fidl::Error::ClientChannelClosed {
179 status: zx::Status::UNAVAILABLE,
180 protocol_name: fdi::DriverIndexMarker::PROTOCOL_NAME,
181 epitaph: None,
182 })
183 }
184 }
185
186 async fn start_driver(
187 &self,
188 node: &Rc<Node>,
189 driver_info: fidl_fuchsia_driver_framework::DriverInfo,
190 ) -> Result<String, zx::Status> {
191 if let Some(runner) = self.0.upgrade() {
192 let url = driver_info.url.clone().ok_or(zx::Status::INVALID_ARGS)?;
193 let package_type = driver_info.package_type.unwrap_or(fdf::DriverPackageType::Base);
194
195 let node_clone = node.clone();
196 let url_clone = url.clone();
197 let runner_clone = runner.clone();
198
199 runner.scope.spawn_local(async move {
203 let _ = runner_clone.start_driver(&node_clone, &url_clone, package_type).await;
204 });
205 Ok(url)
206 } else {
207 Err(zx::Status::UNAVAILABLE)
208 }
209 }
210
211 fn bind_to_parent_spec(
212 &self,
213 parents: &[fdf::CompositeParent],
214 node: Weak<Node>,
215 enable_multibind: bool,
216 ) -> Result<BindSpecResult, zx::Status> {
217 if let Some(runner) = self.0.upgrade() {
218 runner.composite_node_spec_manager.bind_parent_spec(parents, node, enable_multibind)
219 } else {
220 Err(zx::Status::UNAVAILABLE)
221 }
222 }
223}
224
225#[async_trait(?Send)]
226impl CompositeManagerBridge for DriverRunnerBridge {
227 fn box_clone(&self) -> Box<dyn CompositeManagerBridge> {
228 Box::new(Self(self.0.clone()))
229 }
230
231 async fn bind_nodes_for_composite_node_spec(&self) {
232 if let Some(runner) = self.0.upgrade() {
233 let _ = runner.bind_manager.try_bind_all_available().await;
234 }
235 }
236
237 async fn add_spec_to_driver_index(
238 &self,
239 spec: fidl_fuchsia_driver_framework::CompositeNodeSpec,
240 ) -> Result<(), zx::Status> {
241 if let Some(runner) = self.0.upgrade() {
242 runner
243 .driver_index
244 .add_composite_node_spec(&spec)
245 .await
246 .map_err(|_| zx::Status::INTERNAL)?
247 .map_err(zx::Status::from_raw)
248 } else {
249 Err(zx::Status::INTERNAL)
250 }
251 }
252
253 async fn request_rebind_from_driver_index(
254 &self,
255 spec: String,
256 driver_url_suffix: Option<String>,
257 ) -> Result<(), zx::Status> {
258 if let Some(runner) = self.0.upgrade() {
259 runner
260 .driver_index
261 .rebind_composite_node_spec(&spec, driver_url_suffix.as_deref())
262 .await
263 .map_err(|_| zx::Status::INTERNAL)?
264 .map_err(zx::Status::from_raw)
265 } else {
266 Err(zx::Status::INTERNAL)
267 }
268 }
269}