Skip to main content

fdf_component/
lib.rs

1// Copyright 2024 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
5//! Wrappers around the mechanisms of driver registration for the driver
6//! framework for implementing startup and shutdown of the driver in rust.
7
8#![warn(missing_docs, unsafe_op_in_unsafe_fn)]
9
10use core::future::Future;
11
12mod context;
13mod error;
14mod incoming;
15pub mod macros;
16mod node;
17mod server;
18pub mod testing;
19
20pub use context::*;
21pub use error::DriverError;
22pub use incoming::*;
23pub use node::*;
24
25/// Entry points into a driver for starting and stopping.
26///
27/// Driver authors should implement this trait, taking information from the [`DriverContext`]
28/// passed to the [`Driver::start`] method to set up, and then tearing down any resources they use
29/// in the [`Driver::stop`] method.
30pub trait Driver: Sized + Send + 'static {
31    /// The name of the driver as it will appear in logs
32    const NAME: &str;
33
34    /// This will be called when the driver is started.
35    ///
36    /// The given [`DriverContext`] contains information and functionality necessary to get at the
37    /// driver's incoming and outgoing namespaces, add child nodes in the driver topology, and
38    /// manage dispatchers.
39    ///
40    /// In order for the driver to be properly considered started, it must return [`Status::OK`]
41    /// and bind the client end for the [`DriverStartArgs::node`] given in
42    /// [`DriverContext::start_args`].
43    fn start(context: DriverContext) -> impl Future<Output = Result<Self, DriverError>> + Send;
44
45    /// This will be called when the driver has been asked to stop, and should do any
46    /// asynchronous cleanup necessary before the driver is fully shut down.
47    ///
48    /// Note: The driver will not be considered fully stopped until the node client end bound in
49    /// [`Driver::start`] has been closed.
50    fn stop(&self) -> impl Future<Output = ()> + Send;
51
52    /// Called when the driver has been asked to suspend.
53    ///
54    /// This method is invoked after the driver runtime has suspended the driver's dispatchers
55    /// and waited for all executing power-managed (normal) tasks to complete.
56    ///
57    /// The driver should use this opportunity to put its hardware into a low-power state.
58    ///
59    /// Note: This will only be called after the driver has successfully finished [`Driver::start`].
60    /// If a stop is initiated while the driver is suspended, the driver will be fully resumed
61    /// (via [`Driver::system_resume`]) before [`Driver::stop`] is invoked.
62    ///
63    /// Only called when `power_managed_dispatchers_enabled` is set to `"true"` in the
64    /// driver's component manifest.
65    fn system_suspend(&self) -> impl Future<Output = Result<(), DriverError>> + Send {
66        async { Ok(()) }
67    }
68
69    /// Called when the driver has been asked to resume.
70    ///
71    /// This method is invoked when the system resumes or a registered wake vector triggers.
72    /// It executes *before* anything else. The driver should use this opportunity to bring
73    /// its hardware out of its low-power state. Any task queued for the driver to execute will
74    /// only run after this function completes, starting with the wake vector's task if there
75    /// was one.
76    ///
77    /// If the resume was triggered by a wake vector, `lease` will contain a lease token
78    /// representing the lease associated with the wakeup. The driver can retain this lease
79    /// token to keep the driver active and prevent it from suspending again.
80    ///
81    /// Note: This will only be called after the driver has successfully finished [`Driver::start`].
82    /// If the driver is suspended when a stop is initiated, this method is called to resume the
83    /// driver first, ensuring the driver is in a running state during the shutdown hook [`Driver::stop`].
84    ///
85    /// Only called when `power_managed_dispatchers_enabled` is set to `"true"` in the
86    /// driver's component manifest.
87    fn system_resume(
88        &self,
89        _lease: Option<zx::EventPair>,
90    ) -> impl Future<Output = Result<(), DriverError>> + Send {
91        async { Ok(()) }
92    }
93}