1use fidl_fuchsia_driver_framework as fdf;
6use fidl_next::{Request, Responder};
7use fidl_next_fuchsia_hardware_clock::{self as fclock, ClockServerHandler};
8use fuchsia_async as fasync;
9use fuchsia_component::server::{ServiceFs, ServiceObjTrait};
10use fuchsia_sync::Mutex;
11use std::sync::Arc;
12
13struct FakeClockState {
14 enabled: bool,
15 rate: u64,
16}
17
18pub struct FakeClock {
19 state: Arc<Mutex<FakeClockState>>,
20}
21
22impl FakeClock {
23 pub fn new() -> Self {
24 Self { state: Arc::new(Mutex::new(FakeClockState { enabled: false, rate: 0 })) }
25 }
26
27 pub fn enabled(&self) -> bool {
28 self.state.lock().enabled
29 }
30
31 pub fn rate(&self) -> u64 {
32 self.state.lock().rate
33 }
34
35 pub fn set_rate(&self, hz: u64) {
36 self.state.lock().rate = hz;
37 }
38
39 pub fn serve<O: ServiceObjTrait>(
40 &self,
41 service_fs: &mut ServiceFs<O>,
42 scope: fasync::ScopeHandle,
43 instance_name: &str,
44 ) -> fdf::Offer {
45 fdf_component::ServiceOffer::<fclock::Service>::new_next()
46 .add_default_named_next(
47 service_fs,
48 instance_name,
49 FakeClockService { state: self.state.clone(), scope },
50 )
51 .build_zircon_offer_next()
52 }
53}
54
55struct FakeClockService {
56 state: Arc<Mutex<FakeClockState>>,
57 scope: fasync::ScopeHandle,
58}
59
60impl fclock::ServiceHandler for FakeClockService {
61 fn clock(&self, server_end: fidl_next::ServerEnd<fclock::Clock>) {
62 server_end.spawn_on(FakeClockServer { state: self.state.clone() }, &self.scope);
63 }
64}
65
66struct FakeClockServer {
67 state: Arc<Mutex<FakeClockState>>,
68}
69
70impl ClockServerHandler for FakeClockServer {
71 async fn enable(&mut self, responder: Responder<fclock::clock::Enable>) {
72 self.state.lock().enabled = true;
73 let _ = responder.respond(()).await;
74 }
75
76 async fn disable(&mut self, responder: Responder<fclock::clock::Disable>) {
77 self.state.lock().enabled = false;
78 let _ = responder.respond(()).await;
79 }
80
81 async fn is_enabled(&mut self, responder: Responder<fclock::clock::IsEnabled>) {
82 let enabled = self.state.lock().enabled;
83 let _ = responder.respond(enabled).await;
84 }
85
86 async fn set_rate(
87 &mut self,
88 request: Request<fclock::clock::SetRate>,
89 responder: Responder<fclock::clock::SetRate>,
90 ) {
91 self.state.lock().rate = request.payload().hz;
92 let _ = responder.respond(()).await;
93 }
94
95 async fn query_supported_rate(
96 &mut self,
97 _request: Request<fclock::clock::QuerySupportedRate>,
98 responder: Responder<fclock::clock::QuerySupportedRate>,
99 ) {
100 let _ = responder.respond_err(zx::Status::NOT_SUPPORTED.into_raw()).await;
101 }
102
103 async fn get_rate(&mut self, responder: Responder<fclock::clock::GetRate>) {
104 let rate = self.state.lock().rate;
105 let _ = responder.respond(rate).await;
106 }
107
108 async fn set_input(
109 &mut self,
110 _request: Request<fclock::clock::SetInput>,
111 responder: Responder<fclock::clock::SetInput>,
112 ) {
113 let _ = responder.respond_err(zx::Status::NOT_SUPPORTED.into_raw()).await;
114 }
115
116 async fn get_num_inputs(&mut self, responder: Responder<fclock::clock::GetNumInputs>) {
117 let _ = responder.respond_err(zx::Status::NOT_SUPPORTED.into_raw()).await;
118 }
119
120 async fn get_input(&mut self, responder: Responder<fclock::clock::GetInput>) {
121 let _ = responder.respond_err(zx::Status::NOT_SUPPORTED.into_raw()).await;
122 }
123
124 async fn get_properties(&mut self, responder: Responder<fclock::clock::GetProperties>) {
125 let _ = responder
126 .respond(fclock::natural::ClockGetPropertiesResponse {
127 id: 0,
128 name: "clock".to_string(),
129 })
130 .await;
131 }
132}