Skip to main content

fake_clock/
lib.rs

1// Copyright 2026 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
5use 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}