1use anyhow::Result;
6use fidl_fuchsia_power_system as fsystem;
7
8pub struct WakeLease {
9 _token: fsystem::LeaseToken,
10}
11
12impl WakeLease {
13 pub async fn acquire(
14 activity_governor: &fsystem::ActivityGovernorProxy,
15 name: String,
16 ) -> Result<Self> {
17 let token = activity_governor
18 .acquire_wake_lease(&name)
19 .await?
20 .map_err(|e| anyhow::anyhow!("Failed to acquire wake lease: {:?}", e))?;
21 Ok(Self { _token: token })
22 }
23}
24
25#[cfg(test)]
26mod tests {
27 use super::*;
28 use anyhow::Context;
29 use fidl::endpoints::create_proxy_and_stream;
30 use fuchsia_async as fasync;
31 use futures::channel::mpsc;
32 use futures::prelude::*;
33
34 struct FakeActivityGovernor {
35 wake_lease_active: mpsc::UnboundedSender<bool>,
37 }
38
39 impl FakeActivityGovernor {
40 async fn run(&self, stream: fsystem::ActivityGovernorRequestStream) -> Result<()> {
41 stream
42 .map(|request| request.context("failed request"))
43 .try_for_each(|request| async {
44 match request {
45 fsystem::ActivityGovernorRequest::AcquireWakeLease {
46 name: _name,
47 responder,
48 } => {
49 let (server_token, client_token) = fsystem::LeaseToken::create();
50 let wake_lease_active = self.wake_lease_active.clone();
51 assert!(wake_lease_active.unbounded_send(true).is_ok());
52
53 fasync::Task::local(async move {
55 let _ = fasync::OnSignals::new(
56 server_token,
57 zx::Signals::EVENTPAIR_PEER_CLOSED,
58 )
59 .await;
60 wake_lease_active
61 .unbounded_send(false)
62 .expect("server dropping wake lease status");
63 })
64 .detach();
65
66 responder.send(Ok(client_token)).context("send failed")
67 }
68 _ => unreachable!(),
69 }
70 })
71 .await
72 }
73 }
74
75 #[fasync::run_until_stalled(test)]
76 async fn test_acquire_then_release() -> Result<()> {
77 let (client, stream) = create_proxy_and_stream::<fsystem::ActivityGovernorMarker>();
78 let (wake_lease_active_tx, mut wake_lease_active_rx) = mpsc::unbounded::<bool>();
79
80 fasync::Task::local(async move {
82 let server = FakeActivityGovernor { wake_lease_active: wake_lease_active_tx };
83 server.run(stream).await.expect("FakeActivityGovernor server completion");
84 })
85 .detach();
86
87 let wake_lease = WakeLease::acquire(&client, "example_wake_lease".to_string()).await?;
89
90 assert!(wake_lease_active_rx.next().await.expect("server wake lease call"));
92
93 drop(wake_lease);
95 assert!(!wake_lease_active_rx.next().await.expect("server wake lease call"));
96
97 Ok(())
98 }
99}